summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/core.c31
-rw-r--r--src/common/db.c106
-rw-r--r--src/common/db.h12
3 files changed, 132 insertions, 17 deletions
diff --git a/src/common/core.c b/src/common/core.c
index 016ade08d..a30445650 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -76,6 +76,11 @@ sigfunc *compat_signal(int signo, sigfunc *func)
static void sig_proc(int sn)
{
int i;
+ static int is_called = 0;
+
+ if(is_called++)
+ return;
+
switch(sn){
case SIGINT:
case SIGTERM:
@@ -196,11 +201,37 @@ static void display_title(void)
*/
int runflag = 1;
+char pid_file[256];
+
+void pid_delete(void) {
+ unlink(pid_file);
+}
+
+void pid_create(const char* file) {
+ FILE *fp;
+ int len = strlen(file);
+ strcpy(pid_file,file);
+ if(len > 4 && pid_file[len - 4] == '.') {
+ pid_file[len - 4] = 0;
+ }
+ strcat(pid_file,".pid");
+ fp = fopen(pid_file,"w");
+ if(fp) {
+#ifdef _WIN32
+ fprintf(fp,"%d",GetCurrentProcessId());
+#else
+ fprintf(fp,"%d",getpid());
+#endif
+ fclose(fp);
+ atexit(pid_delete);
+ }
+}
int main(int argc,char **argv)
{
int next;
+ pid_create(argv[0]);
Net_Init();
do_socket();
diff --git a/src/common/db.c b/src/common/db.c
index 9f2c75a68..5eb73c785 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -354,6 +354,29 @@ static void db_rebalance_erase(struct dbn *z,struct dbn **root)
}
}
+void db_free_lock(struct dbt *table) {
+ table->free_lock++;
+}
+
+void db_free_unlock(struct dbt *table) {
+ if(--table->free_lock == 0) {
+ int i;
+ for(i = 0; i < table->free_count ; i++) {
+ db_rebalance_erase(table->free_list[i].z,table->free_list[i].root);
+ if(table->cmp == strdb_cmp) {
+ free(table->free_list[i].z->key);
+ }
+#ifdef MALLOC_DBN
+ free_dbn(table->free_list[i].z);
+#else
+ free(table->free_list[i].z);
+#endif
+ table->item_count--;
+ }
+ table->free_count = 0;
+ }
+}
+
struct dbn* db_insert(struct dbt *table,void* key,void* data)
{
struct dbn *p,*priv;
@@ -363,10 +386,33 @@ struct dbn* db_insert(struct dbt *table,void* key,void* data)
for(c=0,priv=NULL ,p = table->ht[hash];p;){
c=table->cmp(table,key,p->key);
if(c==0){ // replace
- if (table->release)
- table->release(p, 3);
+ if (table->release)
+ table->release(p, 3);
+ if(p->deleted) {
+ // 削除されたデータなので、free_list 上の削除予定を消す
+ int i;
+ for(i = 0; i < table->free_count ; i++) {
+ if(table->free_list[i].z == p) {
+ memmove(
+ &table->free_list[i],
+ &table->free_list[i+1],
+ sizeof(struct db_free)*(table->free_count - i - 1)
+ );
+ break;
+ }
+ }
+ if(i == table->free_count || table->free_count <= 0) {
+ printf("db_insert: cannnot find deleted db node.\n");
+ } else {
+ table->free_count--;
+ if(table->cmp == strdb_cmp) {
+ free(p->key);
+ }
+ }
+ }
p->data=data;
p->key=key;
+ p->deleted = 0;
return p;
}
priv=p;
@@ -391,6 +437,7 @@ struct dbn* db_insert(struct dbt *table,void* key,void* data)
p->key = key;
p->data = data;
p->color = RED;
+ p->deleted = 0;
if(c==0){ // hash entry is empty
table->ht[hash] = p;
p->color = BLACK;
@@ -429,25 +476,47 @@ void* db_erase(struct dbt *table,void* key)
if(!p)
return NULL;
data=p->data;
- db_rebalance_erase(p,&table->ht[hash]);
-#ifdef MALLOC_DBN
- free_dbn(p);
-#else
- aFree(p);
-#endif
- table->item_count--;
+ if(table->free_lock) {
+ if(table->free_count == table->free_max) {
+ table->free_max += 32;
+ table->free_list = (struct db_free*)realloc(table->free_list,sizeof(struct db_free) * table->free_max);
+ }
+ table->free_list[table->free_count].z = p;
+ table->free_list[table->free_count].root = &table->ht[hash];
+ table->free_count++;
+ p->deleted = 1;
+ p->data = NULL;
+ if(table->cmp == strdb_cmp) {
+ if(table->maxlen) {
+ char *key = (char*)malloc(table->maxlen);
+ memcpy(key,p->key,table->maxlen);
+ p->key = key;
+ } else {
+ p->key = strdup((const char*)p->key);
+ }
+ }
+ } else {
+ db_rebalance_erase(p,&table->ht[hash]);
+ #ifdef MALLOC_DBN
+ free_dbn(p);
+ #else
+ aFree(p);
+ #endif
+ table->item_count--;
+ }
return data;
}
void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
{
int i,sp;
- int count = 0;
+ int count = table->item_count;
// red-black treeなので64個stackがあれば2^32個ノードまで大丈夫
struct dbn *p,*pn,*stack[64];
va_list ap;
va_start(ap,func);
+ db_free_lock(table);
for(i=0;i<HASH_SIZE;i++){
if((p=table->ht[i])==NULL)
continue;
@@ -457,8 +526,9 @@ void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
//if (!p->data) {
// printf("Warning: no data for key %d in db_foreach (db.c) !\n",(int)p->key);
//} else {
- func(p->key, p->data, ap);
- count++;
+ if(!p->deleted)
+ func(p->key, p->data, ap);
+ count--;
//}
if((pn=p->left)!=NULL){
if(p->right){
@@ -476,10 +546,11 @@ void db_foreach(struct dbt *table,int (*func)(void*,void*,va_list),...)
}
}
}
- if(count != table->item_count) {
+ db_free_unlock(table);
+ if(count) {
printf(
- "db_foreach : data lost %d of %d item(s) allocated from %s line %d\n",
- table->item_count - count,count,table->alloc_file,table->alloc_line
+ "db_foreach : data lost %d item(s) allocated from %s line %d\n",
+ count,table->alloc_file,table->alloc_line
);
}
va_end(ap);
@@ -492,12 +563,13 @@ void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
va_list ap;
va_start(ap,func);
+ db_free_lock(table);
for(i=0;i<HASH_SIZE;i++){
if((p=table->ht[i])==NULL)
continue;
sp=0;
while(1){
- if(func)
+ if(func && !p->deleted)
func(p->key,p->data,ap);
if((pn=p->left)!=NULL){
if(p->right){
@@ -520,6 +592,8 @@ void db_final(struct dbt *table,int (*func)(void*,void*,va_list),...)
p=pn;
}
}
+ db_free_unlock(table);
+ free(table->free_list);
aFree(table);
va_end(ap);
}
diff --git a/src/common/db.h b/src/common/db.h
index c31f5bfaa..11ed4f3e1 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -13,6 +13,7 @@ struct dbn {
int color;
void *key;
void *data;
+ int deleted; // 削除済みフラグ(db_foreach)
};
struct dbt {
@@ -24,7 +25,16 @@ struct dbt {
struct dbn *ht[HASH_SIZE];
int item_count; // vf?
const char* alloc_file; // DB?t@C
- int alloc_line; // DB?s
+ int alloc_line; // DB?s
+ // db_foreach 内部でdb_erase される対策として、
+ // db_foreach が終わるまでロックすることにする
+ struct db_free {
+ struct dbn *z;
+ struct dbn **root;
+ } *free_list;
+ int free_count;
+ int free_max;
+ int free_lock;
};
#define strdb_search(t,k) db_search((t),(void*)(k))