Make atostr more thread safe
atostr now can hold 64 different results, and can be called from multiple threads. Thus, a returned string buffer is valid until atostr is called 64 more times.
This commit is contained in:
parent
05cb45ca14
commit
38eb06f105
3 changed files with 108 additions and 9 deletions
|
@ -12,6 +12,10 @@
|
||||||
#define UDPC_ID_NO_REC_CHK 0x20000000
|
#define UDPC_ID_NO_REC_CHK 0x20000000
|
||||||
#define UDPC_ID_RESENDING 0x10000000
|
#define UDPC_ID_RESENDING 0x10000000
|
||||||
|
|
||||||
|
#define UDPC_ATOSTR_BUFCOUNT 64
|
||||||
|
#define UDPC_ATOSTR_BUFSIZE 16
|
||||||
|
#define UDPC_ATOSTR_SIZE (UDPC_ATOSTR_BUFCOUNT * UDPC_ATOSTR_BUFSIZE)
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -229,7 +233,8 @@ public:
|
||||||
std::atomic_bool isAcceptNewConnections;
|
std::atomic_bool isAcceptNewConnections;
|
||||||
std::atomic_uint32_t protocolID;
|
std::atomic_uint32_t protocolID;
|
||||||
std::atomic_uint_fast8_t loggingType;
|
std::atomic_uint_fast8_t loggingType;
|
||||||
char atostrBuf[16];
|
std::atomic_uint32_t atostrBufIndex;
|
||||||
|
char atostrBuf[UDPC_ATOSTR_SIZE];
|
||||||
|
|
||||||
int socketHandle;
|
int socketHandle;
|
||||||
struct sockaddr_in socketInfo;
|
struct sockaddr_in socketInfo;
|
||||||
|
|
|
@ -77,6 +77,7 @@ loggingType(INFO),
|
||||||
#else
|
#else
|
||||||
loggingType(WARNING),
|
loggingType(WARNING),
|
||||||
#endif
|
#endif
|
||||||
|
atostrBufIndex(0),
|
||||||
rng_engine()
|
rng_engine()
|
||||||
{
|
{
|
||||||
if(isThreaded) {
|
if(isThreaded) {
|
||||||
|
@ -1006,7 +1007,9 @@ const char *UDPC_atostr(UDPC_HContext ctx, uint32_t addr) {
|
||||||
if(!c) {
|
if(!c) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
int index = 0;
|
const uint32_t headIndex =
|
||||||
|
c->atostrBufIndex.fetch_add(UDPC_ATOSTR_BUFSIZE) % UDPC_ATOSTR_SIZE;
|
||||||
|
uint32_t index = headIndex;
|
||||||
for(int x = 0; x < 4; ++x) {
|
for(int x = 0; x < 4; ++x) {
|
||||||
unsigned char temp = (addr >> (x * 8)) & 0xFF;
|
unsigned char temp = (addr >> (x * 8)) & 0xFF;
|
||||||
|
|
||||||
|
@ -1024,7 +1027,7 @@ const char *UDPC_atostr(UDPC_HContext ctx, uint32_t addr) {
|
||||||
}
|
}
|
||||||
c->atostrBuf[index] = 0;
|
c->atostrBuf[index] = 0;
|
||||||
|
|
||||||
return c->atostrBuf;
|
return c->atostrBuf + headIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t UDPC_strtoa(const char *addrStr) {
|
uint32_t UDPC_strtoa(const char *addrStr) {
|
||||||
|
|
|
@ -4,18 +4,109 @@
|
||||||
#include <UDPC_Defines.hpp>
|
#include <UDPC_Defines.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <future>
|
||||||
|
|
||||||
TEST(UDPC, atostr) {
|
TEST(UDPC, atostr) {
|
||||||
UDPC::Context context(false);
|
UDPC::Context context(false);
|
||||||
|
|
||||||
UDPC_atostr((UDPC_HContext)&context, 0x0100007F);
|
const char* resultBuf;
|
||||||
EXPECT_EQ(std::strcmp(context.atostrBuf, "127.0.0.1"), 0);
|
|
||||||
|
|
||||||
UDPC_atostr((UDPC_HContext)&context, 0xFF08000A);
|
resultBuf = UDPC_atostr((UDPC_HContext)&context, 0x0100007F);
|
||||||
EXPECT_EQ(std::strcmp(context.atostrBuf, "10.0.8.255"), 0);
|
EXPECT_EQ(std::strcmp(resultBuf, "127.0.0.1"), 0);
|
||||||
|
|
||||||
UDPC_atostr((UDPC_HContext)&context, 0x0201A8C0);
|
resultBuf = UDPC_atostr((UDPC_HContext)&context, 0xFF08000A);
|
||||||
EXPECT_EQ(std::strcmp(context.atostrBuf, "192.168.1.2"), 0);
|
EXPECT_EQ(std::strcmp(resultBuf, "10.0.8.255"), 0);
|
||||||
|
|
||||||
|
resultBuf = UDPC_atostr((UDPC_HContext)&context, 0x0201A8C0);
|
||||||
|
EXPECT_EQ(std::strcmp(resultBuf, "192.168.1.2"), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UDPC, atostr_concurrent) {
|
||||||
|
UDPC::Context context(false);
|
||||||
|
|
||||||
|
const char* results[64] = {
|
||||||
|
"0.0.0.0",
|
||||||
|
"1.1.1.1",
|
||||||
|
"2.2.2.2",
|
||||||
|
"3.3.3.3",
|
||||||
|
"4.4.4.4",
|
||||||
|
"5.5.5.5",
|
||||||
|
"6.6.6.6",
|
||||||
|
"7.7.7.7",
|
||||||
|
"8.8.8.8",
|
||||||
|
"9.9.9.9",
|
||||||
|
"10.10.10.10",
|
||||||
|
"11.11.11.11",
|
||||||
|
"12.12.12.12",
|
||||||
|
"13.13.13.13",
|
||||||
|
"14.14.14.14",
|
||||||
|
"15.15.15.15",
|
||||||
|
"16.16.16.16",
|
||||||
|
"17.17.17.17",
|
||||||
|
"18.18.18.18",
|
||||||
|
"19.19.19.19",
|
||||||
|
"20.20.20.20",
|
||||||
|
"21.21.21.21",
|
||||||
|
"22.22.22.22",
|
||||||
|
"23.23.23.23",
|
||||||
|
"24.24.24.24",
|
||||||
|
"25.25.25.25",
|
||||||
|
"26.26.26.26",
|
||||||
|
"27.27.27.27",
|
||||||
|
"28.28.28.28",
|
||||||
|
"29.29.29.29",
|
||||||
|
"30.30.30.30",
|
||||||
|
"31.31.31.31",
|
||||||
|
"32.32.32.32",
|
||||||
|
"33.33.33.33",
|
||||||
|
"34.34.34.34",
|
||||||
|
"35.35.35.35",
|
||||||
|
"36.36.36.36",
|
||||||
|
"37.37.37.37",
|
||||||
|
"38.38.38.38",
|
||||||
|
"39.39.39.39",
|
||||||
|
"40.40.40.40",
|
||||||
|
"41.41.41.41",
|
||||||
|
"42.42.42.42",
|
||||||
|
"43.43.43.43",
|
||||||
|
"44.44.44.44",
|
||||||
|
"45.45.45.45",
|
||||||
|
"46.46.46.46",
|
||||||
|
"47.47.47.47",
|
||||||
|
"48.48.48.48",
|
||||||
|
"49.49.49.49",
|
||||||
|
"50.50.50.50",
|
||||||
|
"51.51.51.51",
|
||||||
|
"52.52.52.52",
|
||||||
|
"53.53.53.53",
|
||||||
|
"54.54.54.54",
|
||||||
|
"55.55.55.55",
|
||||||
|
"56.56.56.56",
|
||||||
|
"57.57.57.57",
|
||||||
|
"58.58.58.58",
|
||||||
|
"59.59.59.59",
|
||||||
|
"60.60.60.60",
|
||||||
|
"61.61.61.61",
|
||||||
|
"62.62.62.62",
|
||||||
|
"63.63.63.63"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::future<void> futures[64];
|
||||||
|
const char* ptrs[64];
|
||||||
|
for(unsigned int i = 0; i < 2; ++i) {
|
||||||
|
for(unsigned int j = 0; j < 64; ++j) {
|
||||||
|
futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr, UDPC::Context* c) {
|
||||||
|
ptr[id] = UDPC_atostr((UDPC_HContext)c, id | (id << 8) | (id << 16) | (id << 24));
|
||||||
|
}, j, ptrs, &context);
|
||||||
|
}
|
||||||
|
for(unsigned int j = 0; j < 64; ++j) {
|
||||||
|
ASSERT_TRUE(futures[j].valid());
|
||||||
|
futures[j].wait();
|
||||||
|
}
|
||||||
|
for(unsigned int j = 0; j < 64; ++j) {
|
||||||
|
EXPECT_EQ(std::strcmp(ptrs[j], results[j]), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(UDPC, strtoa) {
|
TEST(UDPC, strtoa) {
|
||||||
|
|
Loading…
Reference in a new issue