use mutex lock when access dynamic content array

pull/37/head
YuQing 2020-05-07 16:41:21 +08:00
parent 54cb8f8415
commit 7149a54128
4 changed files with 197 additions and 100 deletions

1
.gitignore vendored
View File

@ -50,6 +50,7 @@ src/tests/test_uniq_skiplist
src/tests/test_server_id_func src/tests/test_server_id_func
src/tests/test_pipe src/tests/test_pipe
src/tests/test_atomic src/tests/test_atomic
src/tests/test_file_write_hole
# other # other
*.swp *.swp

View File

@ -1,5 +1,5 @@
Version 1.44 2020-05-06 Version 1.44 2020-05-07
* add test file src/tests/test_pthread_lock.c * add test file src/tests/test_pthread_lock.c
* add uniq_skiplist.[hc] * add uniq_skiplist.[hc]
* add function split_string_ex * add function split_string_ex
@ -28,6 +28,7 @@ Version 1.44 2020-05-06
* uniq_skiplist add function find_ge and support bidirection * uniq_skiplist add function find_ge and support bidirection
* connection_pool support validate connection on error * connection_pool support validate connection on error
* fast_task_queue.[hc]: free_queue support init_callback * fast_task_queue.[hc]: free_queue support init_callback
* ini_file_reader.c: use mutex lock when access dynamic content array
Version 1.43 2019-12-25 Version 1.43 2019-12-25
* replace function call system to getExecResult, * replace function call system to getExecResult,

View File

@ -19,6 +19,7 @@
#include "logger.h" #include "logger.h"
#include "http_func.h" #include "http_func.h"
#include "local_ip_func.h" #include "local_ip_func.h"
#include "pthread_func.h"
#include "ini_file_reader.h" #include "ini_file_reader.h"
#define _LINE_BUFFER_SIZE 512 #define _LINE_BUFFER_SIZE 512
@ -53,15 +54,15 @@
#define _PREPROCESS_TAG_STR_FOR_STEP "step" #define _PREPROCESS_TAG_STR_FOR_STEP "step"
#define _PREPROCESS_TAG_LEN_FOR_STEP (sizeof(_PREPROCESS_TAG_STR_FOR_STEP) - 1) #define _PREPROCESS_TAG_LEN_FOR_STEP (sizeof(_PREPROCESS_TAG_STR_FOR_STEP) - 1)
#define _MAX_DYNAMIC_CONTENTS 8 #define _INIT_DYNAMIC_CONTENTS 8
#define _BUILTIN_ANNOTATION_COUNT 3 #define _BUILTIN_ANNOTATION_COUNT 3
static AnnotationEntry *g_annotations = NULL; static AnnotationEntry *g_annotations = NULL;
static int g_annotation_count = 0; static int g_annotation_count = 0;
typedef struct { typedef struct {
int count; int count;
int alloc_count; int alloc;
char **contents; char **contents;
} DynamicContents; } DynamicContents;
@ -72,7 +73,7 @@ typedef struct {
typedef struct { typedef struct {
int count; int count;
int alloc_count; int alloc;
AnnotationEntry *annotations; AnnotationEntry *annotations;
} DynamicAnnotations; } DynamicAnnotations;
@ -84,11 +85,17 @@ typedef struct {
DynamicAnnotations dynamicAnnotations; DynamicAnnotations dynamicAnnotations;
} CDCPair; } CDCPair;
typedef struct {
volatile int init_counter;
int alloc;
int count;
int index;
CDCPair *contents;
pthread_mutex_t lock;
} DynamicContentArray;
//dynamic alloced contents which will be freed when destroy //dynamic alloced contents which will be freed when destroy
static int g_dynamic_content_count = 0; static DynamicContentArray g_dynamic_content_array = {0, 0, 0, 0, NULL};
static int g_dynamic_content_index = 0;
static CDCPair g_dynamic_contents[_MAX_DYNAMIC_CONTENTS] = {{false, NULL,
{0, 0, NULL}, {0, NULL}, {0, 0, NULL}}};
static int remallocSection(IniSection *pSection, IniItem **pItem); static int remallocSection(IniSection *pSection, IniItem **pItem);
static int iniDoLoadFromFile(const char *szFilename, \ static int iniDoLoadFromFile(const char *szFilename, \
@ -1194,7 +1201,7 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
nValueLen = FAST_INI_ITEM_VALUE_LEN; nValueLen = FAST_INI_ITEM_VALUE_LEN;
} }
if (pSection->count >= pSection->alloc_count) if (pSection->count >= pSection->alloc)
{ {
result = remallocSection(pSection, &pItem); result = remallocSection(pSection, &pItem);
if (result != 0) if (result != 0)
@ -1300,7 +1307,7 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
pItem->value[nValueLen] = '\0'; pItem->value[nValueLen] = '\0';
pSection->count++; pSection->count++;
pItem++; pItem++;
if (pSection->count >= pSection->alloc_count) if (pSection->count >= pSection->alloc)
{ {
result = remallocSection(pSection, &pItem); result = remallocSection(pSection, &pItem);
if (result != 0) if (result != 0)
@ -1331,27 +1338,96 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
return result; return result;
} }
static inline int checkInitDynamicContentArray()
{
if (__sync_fetch_and_add(&g_dynamic_content_array.init_counter, 1) != 0)
{
return 0;
}
logInfo("file: "__FILE__", line: %d, func: %s, "
"init_pthread_lock", __LINE__, __FUNCTION__);
return init_pthread_lock(&g_dynamic_content_array.lock);
}
static int checkAllocDynamicContentArray()
{
CDCPair *contents;
int alloc;
int bytes;
if (g_dynamic_content_array.alloc > g_dynamic_content_array.count)
{
return 0;
}
alloc = (g_dynamic_content_array.alloc == 0) ? _INIT_DYNAMIC_CONTENTS :
g_dynamic_content_array.alloc * 2;
bytes = sizeof(CDCPair) * alloc;
contents = (CDCPair *)malloc(bytes);
if (contents == NULL)
{
logError("file: "__FILE__", line: %d, "
"malloc %d bytes fail", __LINE__, bytes);
return ENOMEM;
}
memset(contents, 0, bytes);
if (g_dynamic_content_array.alloc > 0)
{
memcpy(contents, g_dynamic_content_array.contents,
sizeof(CDCPair) * g_dynamic_content_array.alloc);
free(g_dynamic_content_array.contents);
}
logInfo("file: "__FILE__", line: %d, func: %s, "
"alloc count: %d", __LINE__, __FUNCTION__, alloc);
g_dynamic_content_array.contents = contents;
g_dynamic_content_array.alloc = alloc;
return 0;
}
static CDCPair *iniGetCDCPair(IniContext *pContext) static CDCPair *iniGetCDCPair(IniContext *pContext)
{ {
int i; int i;
if (g_dynamic_contents[g_dynamic_content_index].context == pContext) CDCPair *pair;
if (checkInitDynamicContentArray() != 0)
{ {
return g_dynamic_contents + g_dynamic_content_index; return NULL;
} }
if (g_dynamic_content_count > 0) pthread_mutex_lock(&g_dynamic_content_array.lock);
if (g_dynamic_content_array.contents == NULL)
{ {
for (i=0; i<_MAX_DYNAMIC_CONTENTS; i++) pair = NULL;
}
else if (g_dynamic_content_array.contents[g_dynamic_content_array.index].
context == pContext)
{
pair = g_dynamic_content_array.contents + g_dynamic_content_array.index;
}
else
{
pair = NULL;
if (g_dynamic_content_array.count > 0)
{ {
if (g_dynamic_contents[i].context == pContext) for (i=0; i<g_dynamic_content_array.alloc; i++)
{ {
g_dynamic_content_index = i; if (g_dynamic_content_array.contents[i].context == pContext)
return g_dynamic_contents + g_dynamic_content_index; {
g_dynamic_content_array.index = i;
pair = g_dynamic_content_array.contents +
g_dynamic_content_array.index;
break;
}
} }
} }
} }
pthread_mutex_unlock(&g_dynamic_content_array.lock);
return NULL; return pair;
} }
static CDCPair *iniAllocCDCPair(IniContext *pContext) static CDCPair *iniAllocCDCPair(IniContext *pContext)
@ -1363,29 +1439,35 @@ static CDCPair *iniAllocCDCPair(IniContext *pContext)
return pair; return pair;
} }
if (g_dynamic_content_count == _MAX_DYNAMIC_CONTENTS) pthread_mutex_lock(&g_dynamic_content_array.lock);
{ do {
return NULL; if (checkAllocDynamicContentArray() != 0)
}
for (i=0; i<_MAX_DYNAMIC_CONTENTS; i++)
{
if (!g_dynamic_contents[i].used)
{ {
g_dynamic_contents[i].used = true; break;
g_dynamic_contents[i].context = pContext;
g_dynamic_content_index = i;
g_dynamic_content_count++;
return g_dynamic_contents + g_dynamic_content_index;
} }
}
return NULL; for (i=0; i<g_dynamic_content_array.alloc; i++)
{
if (!g_dynamic_content_array.contents[i].used)
{
g_dynamic_content_array.contents[i].used = true;
g_dynamic_content_array.contents[i].context = pContext;
g_dynamic_content_array.index = i;
g_dynamic_content_array.count++;
pair = g_dynamic_content_array.contents +
g_dynamic_content_array.index;
break;
}
}
} while (0);
pthread_mutex_unlock(&g_dynamic_content_array.lock);
return pair;
} }
static DynamicContents *iniAllocDynamicContent(IniContext *pContext) static DynamicContents *iniAllocDynamicContent(IniContext *pContext)
{ {
static CDCPair *pair; CDCPair *pair;
pair = iniAllocCDCPair(pContext); pair = iniAllocCDCPair(pContext);
if (pair == NULL) if (pair == NULL)
@ -1397,7 +1479,7 @@ static DynamicContents *iniAllocDynamicContent(IniContext *pContext)
static SetDirectiveVars *iniGetVars(IniContext *pContext) static SetDirectiveVars *iniGetVars(IniContext *pContext)
{ {
static CDCPair *pair; CDCPair *pair;
pair = iniGetCDCPair(pContext); pair = iniGetCDCPair(pContext);
if (pair == NULL) if (pair == NULL)
@ -1409,7 +1491,7 @@ static SetDirectiveVars *iniGetVars(IniContext *pContext)
static DynamicAnnotations *iniAllocDynamicAnnotation(IniContext *pContext) static DynamicAnnotations *iniAllocDynamicAnnotation(IniContext *pContext)
{ {
static CDCPair *pair; CDCPair *pair;
pair = iniAllocCDCPair(pContext); pair = iniAllocCDCPair(pContext);
if (pair == NULL) if (pair == NULL)
@ -1421,7 +1503,7 @@ static DynamicAnnotations *iniAllocDynamicAnnotation(IniContext *pContext)
static AnnotationEntry *iniGetAnnotations(IniContext *pContext) static AnnotationEntry *iniGetAnnotations(IniContext *pContext)
{ {
static CDCPair *pair; CDCPair *pair;
pair = iniGetCDCPair(pContext); pair = iniGetCDCPair(pContext);
if (pair == NULL) if (pair == NULL)
@ -1433,7 +1515,7 @@ static AnnotationEntry *iniGetAnnotations(IniContext *pContext)
static SetDirectiveVars *iniAllocVars(IniContext *pContext, const bool initVars) static SetDirectiveVars *iniAllocVars(IniContext *pContext, const bool initVars)
{ {
static CDCPair *pair; CDCPair *pair;
SetDirectiveVars *set; SetDirectiveVars *set;
set = iniGetVars(pContext); set = iniGetVars(pContext);
@ -1475,60 +1557,73 @@ static void iniFreeDynamicContent(IniContext *pContext)
DynamicAnnotations *pDynamicAnnotations; DynamicAnnotations *pDynamicAnnotations;
int i; int i;
if (g_dynamic_content_count == 0) if (checkInitDynamicContentArray() != 0)
{ {
return; return;
} }
if (g_dynamic_contents[g_dynamic_content_index].context == pContext) pthread_mutex_lock(&g_dynamic_content_array.lock);
do
{ {
pCDCPair = g_dynamic_contents + g_dynamic_content_index; if (g_dynamic_content_array.count == 0)
}
else
{
pCDCPair = NULL;
for (i=0; i<_MAX_DYNAMIC_CONTENTS; i++)
{ {
if (g_dynamic_contents[i].context == pContext) break;
}
if (g_dynamic_content_array.contents[g_dynamic_content_array.index].
context == pContext)
{
pCDCPair = g_dynamic_content_array.contents +
g_dynamic_content_array.index;
}
else
{
pCDCPair = NULL;
for (i=0; i<g_dynamic_content_array.alloc; i++)
{
if (g_dynamic_content_array.contents[i].context == pContext)
{
pCDCPair = g_dynamic_content_array.contents + i;
break;
}
}
if (pCDCPair == NULL)
{ {
pCDCPair = g_dynamic_contents + i;
break; break;
} }
} }
if (pCDCPair == NULL)
{
return;
}
}
pDynamicContents = &pCDCPair->dynamicContents; pDynamicContents = &pCDCPair->dynamicContents;
if (pDynamicContents->contents != NULL) if (pDynamicContents->contents != NULL)
{
for (i=0; i<pDynamicContents->count; i++)
{ {
if (pDynamicContents->contents[i] != NULL) for (i=0; i<pDynamicContents->count; i++)
{ {
free(pDynamicContents->contents[i]); if (pDynamicContents->contents[i] != NULL)
{
free(pDynamicContents->contents[i]);
}
} }
free(pDynamicContents->contents);
pDynamicContents->contents = NULL;
pDynamicContents->alloc = 0;
pDynamicContents->count = 0;
} }
free(pDynamicContents->contents);
pDynamicContents->contents = NULL;
pDynamicContents->alloc_count = 0;
pDynamicContents->count = 0;
}
pDynamicAnnotations = &pCDCPair->dynamicAnnotations; pDynamicAnnotations = &pCDCPair->dynamicAnnotations;
if (pDynamicAnnotations->annotations != NULL) if (pDynamicAnnotations->annotations != NULL)
{ {
free(pDynamicAnnotations->annotations); free(pDynamicAnnotations->annotations);
pDynamicAnnotations->annotations = NULL; pDynamicAnnotations->annotations = NULL;
pDynamicAnnotations->alloc_count = 0; pDynamicAnnotations->alloc = 0;
pDynamicAnnotations->count = 0; pDynamicAnnotations->count = 0;
} }
pCDCPair->used = false; pCDCPair->used = false;
pCDCPair->context = NULL; pCDCPair->context = NULL;
g_dynamic_content_count--; g_dynamic_content_array.count--;
} while (0);
pthread_mutex_unlock(&g_dynamic_content_array.lock);
} }
static char *iniAllocContent(IniContext *pContext, const int content_len) static char *iniAllocContent(IniContext *pContext, const int content_len)
@ -1542,20 +1637,20 @@ static char *iniAllocContent(IniContext *pContext, const int content_len)
"malloc dynamic contents fail", __LINE__); "malloc dynamic contents fail", __LINE__);
return NULL; return NULL;
} }
if (pDynamicContents->count >= pDynamicContents->alloc_count) if (pDynamicContents->count >= pDynamicContents->alloc)
{ {
int alloc_count; int alloc;
int bytes; int bytes;
char **contents; char **contents;
if (pDynamicContents->alloc_count == 0) if (pDynamicContents->alloc == 0)
{ {
alloc_count = 8; alloc = 8;
} }
else else
{ {
alloc_count = pDynamicContents->alloc_count * 2; alloc = pDynamicContents->alloc * 2;
} }
bytes = sizeof(char *) * alloc_count; bytes = sizeof(char *) * alloc;
contents = (char **)malloc(bytes); contents = (char **)malloc(bytes);
if (contents == NULL) if (contents == NULL)
{ {
@ -1571,7 +1666,7 @@ static char *iniAllocContent(IniContext *pContext, const int content_len)
free(pDynamicContents->contents); free(pDynamicContents->contents);
} }
pDynamicContents->contents = contents; pDynamicContents->contents = contents;
pDynamicContents->alloc_count = alloc_count; pDynamicContents->alloc = alloc;
} }
buff = malloc(content_len); buff = malloc(content_len);
@ -1588,29 +1683,29 @@ static char *iniAllocContent(IniContext *pContext, const int content_len)
static int iniCheckAllocAnnotations(DynamicAnnotations *pDynamicAnnotations, static int iniCheckAllocAnnotations(DynamicAnnotations *pDynamicAnnotations,
const int annotation_count) const int annotation_count)
{ {
int alloc_count; int alloc;
int bytes; int bytes;
AnnotationEntry *annotations; AnnotationEntry *annotations;
if (pDynamicAnnotations->count + annotation_count < if (pDynamicAnnotations->count + annotation_count <
pDynamicAnnotations->alloc_count) pDynamicAnnotations->alloc)
{ {
return 0; return 0;
} }
if (pDynamicAnnotations->alloc_count == 0) if (pDynamicAnnotations->alloc == 0)
{ {
alloc_count = 8; alloc = 8;
} }
else else
{ {
alloc_count = pDynamicAnnotations->alloc_count * 2; alloc = pDynamicAnnotations->alloc * 2;
} }
while (alloc_count <= pDynamicAnnotations->count + annotation_count) while (alloc <= pDynamicAnnotations->count + annotation_count)
{ {
alloc_count *= 2; alloc *= 2;
} }
bytes = sizeof(AnnotationEntry) * alloc_count; bytes = sizeof(AnnotationEntry) * alloc;
annotations = (AnnotationEntry *)malloc(bytes); annotations = (AnnotationEntry *)malloc(bytes);
if (annotations == NULL) if (annotations == NULL)
{ {
@ -1626,7 +1721,7 @@ static int iniCheckAllocAnnotations(DynamicAnnotations *pDynamicAnnotations,
free(pDynamicAnnotations->annotations); free(pDynamicAnnotations->annotations);
} }
pDynamicAnnotations->annotations = annotations; pDynamicAnnotations->annotations = annotations;
pDynamicAnnotations->alloc_count = alloc_count; pDynamicAnnotations->alloc = alloc;
return 0; return 0;
} }
@ -2630,18 +2725,18 @@ static int remallocSection(IniSection *pSection, IniItem **pItem)
{ {
int bytes; int bytes;
int result; int result;
int alloc_count; int alloc;
IniItem *pNew; IniItem *pNew;
if (pSection->alloc_count == 0) if (pSection->alloc == 0)
{ {
alloc_count = _INIT_ALLOC_ITEM_COUNT; alloc = _INIT_ALLOC_ITEM_COUNT;
} }
else else
{ {
alloc_count = pSection->alloc_count * 2; alloc = pSection->alloc * 2;
} }
bytes = sizeof(IniItem) * alloc_count; bytes = sizeof(IniItem) * alloc;
pNew = (IniItem *)malloc(bytes); pNew = (IniItem *)malloc(bytes);
if (pNew == NULL) if (pNew == NULL)
{ {
@ -2658,11 +2753,11 @@ static int remallocSection(IniSection *pSection, IniItem **pItem)
free(pSection->items); free(pSection->items);
} }
pSection->alloc_count = alloc_count; pSection->alloc = alloc;
pSection->items = pNew; pSection->items = pNew;
*pItem = pSection->items + pSection->count; *pItem = pSection->items + pSection->count;
memset(*pItem, 0, sizeof(IniItem) * memset(*pItem, 0, sizeof(IniItem) *
(pSection->alloc_count - pSection->count)); (pSection->alloc - pSection->count));
return 0; return 0;
} }

View File

@ -43,7 +43,7 @@ typedef struct ini_section
{ {
IniItem *items; IniItem *items;
int count; //item count int count; //item count
int alloc_count; int alloc;
} IniSection; } IniSection;
typedef struct ini_section_info typedef struct ini_section_info