diff --git a/dict.c b/dict.c index b5db396..4f87eae 100644 --- a/dict.c +++ b/dict.c @@ -7,7 +7,6 @@ #include "dict.h" #include "server.h" -static pthread_rwlock_t mu; static char* filepath; static uint8_t dict_md5[16]; @@ -21,8 +20,8 @@ static FILE* thread_fp[THREADCNT]; #define _dict_md5_4 ((uint32_t*)&dict_md5) #endif -int fill_md5() { - size_t size = get_dict_size(); +int fill_md5(pthread_rwlock_t* mu) { + size_t size = get_dict_size(mu); if(!size) { memset(dict_md5, 0, 16); puts("Dict is empty, use all zero md5"); @@ -30,15 +29,15 @@ int fill_md5() { } uint8_t* dict_buff = (uint8_t*)malloc(size); if(dict_buff) { - pthread_rwlock_rdlock(&mu); + pthread_rwlock_rdlock(mu); rewind(fp_read); if(fread(dict_buff, size, 1, fp_read) == 1) { - pthread_rwlock_unlock(&mu); + pthread_rwlock_unlock(mu); md5(dict_buff, size, dict_md5); free(dict_buff); return 1; } else { - pthread_rwlock_unlock(&mu); + pthread_rwlock_unlock(mu); free(dict_buff); puts("Read dict error"); return 0; @@ -49,26 +48,25 @@ int fill_md5() { } } -int init_dict(char* file_path) { +int init_dict(char* file_path, pthread_rwlock_t* mu) { fp = fopen(file_path, "rb+"); fp_read = fopen(file_path, "rb"); if(fp) { - int err = pthread_rwlock_init(&mu, NULL); + int err = pthread_rwlock_init(mu, NULL); if(err) { puts("Init lock error"); return 0; } filepath = file_path; - return fill_md5(); - } else { - puts("Open dict error"); - return 0; + return fill_md5(mu); } + puts("Open dict error"); + return 0; } -FILE* open_dict(uint8_t lock_type, uint32_t index) { +FILE* open_dict(uint8_t lock_type, uint32_t index, pthread_rwlock_t* mu) { if(lock_type & DICT_LOCK_EX) { - pthread_rwlock_wrlock(&mu); + pthread_rwlock_wrlock(mu); if(!fp) fp = fopen(filepath, "rb+"); else rewind(fp); return fp; @@ -77,7 +75,7 @@ FILE* open_dict(uint8_t lock_type, uint32_t index) { puts("Open dict: Index out of bounds"); return NULL; } - pthread_rwlock_rdlock(&mu); + pthread_rwlock_rdlock(mu); if(!thread_fp[index]) thread_fp[index] = fopen(filepath, "rb"); else rewind(thread_fp[index]); return thread_fp[index]; @@ -92,20 +90,20 @@ FILE* get_dict_fp_rd() { return fp_read; } -void close_dict(uint8_t lock_type, uint32_t index) { +void close_dict(uint8_t lock_type, uint32_t index, pthread_rwlock_t* mu) { if(lock_type & DICT_LOCK_EX) fflush(fp); - pthread_rwlock_unlock(&mu); + pthread_rwlock_unlock(mu); puts("Close dict"); } -off_t get_dict_size() { +off_t get_dict_size(pthread_rwlock_t* mu) { struct stat statbuf; - pthread_rwlock_rdlock(&mu); + pthread_rwlock_rdlock(mu); if(stat(filepath, &statbuf)==0) { - pthread_rwlock_unlock(&mu); + pthread_rwlock_unlock(mu); return statbuf.st_size; } - pthread_rwlock_unlock(&mu); + pthread_rwlock_unlock(mu); return -1; } diff --git a/dict.h b/dict.h index b02c482..3c21c9a 100644 --- a/dict.h +++ b/dict.h @@ -16,13 +16,13 @@ typedef struct DICT DICT; #define DICT_LOCK_SH 0x01 #define DICT_LOCK_EX 0x02 -int init_dict(char* file_path); -void close_dict(uint8_t lock_type, uint32_t index); -int fill_md5(); -FILE* get_dict_fp_wr(); -off_t get_dict_size(); +void close_dict(uint8_t lock_type, uint32_t index, pthread_rwlock_t* mu); +int fill_md5(pthread_rwlock_t* mu); +int init_dict(char* file_path, pthread_rwlock_t* mu); +int is_md5_equal(uint8_t* digest); FILE* get_dict_fp_rd(); -int is_md5_equal(uint8_t* digest); -FILE *open_dict(uint8_t lock_type, uint32_t index); +FILE* get_dict_fp_wr(); +off_t get_dict_size(pthread_rwlock_t* mu); +FILE* open_dict(uint8_t lock_type, uint32_t index, pthread_rwlock_t* mu); #endif \ No newline at end of file diff --git a/server.c b/server.c index bf0f5c0..8beff10 100644 --- a/server.c +++ b/server.c @@ -49,6 +49,7 @@ static DICT* setdict; static uint32_t* items_len; static CONFIG* cfg; static pthread_attr_t attr; +static pthread_rwlock_t mu; #define DICTPOOLSZ (((uint32_t)-1)>>((sizeof(uint32_t)*8-DICTPOOLBIT))) static DICT* dict_pool[DICTPOOLSZ+1]; @@ -139,10 +140,11 @@ static int send_data(int accept_fd, int index, char *data, size_t length) { static int send_all(THREADTIMER *timer) { int re = 1; - FILE *fp = open_dict(DICT_LOCK_SH, timer->index); + pthread_cleanup_push((void*)&pthread_rwlock_unlock, (void*)&mu); + FILE *fp = open_dict(DICT_LOCK_SH, timer->index, &mu); if(!fp) return 1; timer->lock_type = DICT_LOCK_SH; - off_t len = 0, file_size = get_dict_size(); + off_t len = 0, file_size = get_dict_size(&mu); char* buf = (char*)malloc(file_size); if(buf) { if(fread(buf, file_size, 1, fp) == 1) { @@ -163,7 +165,8 @@ static int send_all(THREADTIMER *timer) { } free(buf); } - close_dict(DICT_LOCK_SH, timer->index); + close_dict(DICT_LOCK_SH, timer->index, &mu); + pthread_cleanup_pop(0); return re; } @@ -208,15 +211,15 @@ static void init_dict_pool(FILE *fp) { static int s1_get(THREADTIMER *timer) { uint8_t digest[16]; - FILE *fp = open_dict(DICT_LOCK_SH, timer->index); + FILE *fp = open_dict(DICT_LOCK_SH, timer->index, &mu); //timer->status = 0; - if(fp) { + while(fp) { int ch; timer->lock_type = DICT_LOCK_SH; md5((uint8_t*)timer->dat, strlen(timer->dat)+1, digest); uint8_t* dp = digest; int p = ((*((uint32_t*)digest))>>(8*sizeof(uint32_t)-DICTPOOLBIT))&DICTPOOLSZ; - if(!dict_pool[p]) return close_and_send(timer, "null", 4); + if(!dict_pool[p]) break; int c = 16-4; int notok = 1; @@ -235,6 +238,8 @@ static int s1_get(THREADTIMER *timer) { return r; } else free(spb); } + + break; } return close_and_send(timer, "null", 4); } @@ -242,7 +247,7 @@ static int s1_get(THREADTIMER *timer) { static int s2_set(THREADTIMER *timer) { uint8_t digest[16]; timer->lock_type = DICT_LOCK_EX; - FILE *fp = open_dict(DICT_LOCK_EX, timer->index); + FILE *fp = open_dict(DICT_LOCK_EX, timer->index, &mu); if(fp) { md5((uint8_t*)timer->dat, strlen(timer->dat)+1, digest); uint8_t* dp = digest; @@ -351,7 +356,7 @@ static int s4_del(THREADTIMER *timer) { uint8_t digest[16]; char ret[4]; timer->lock_type = DICT_LOCK_EX; - FILE *fp = open_dict(DICT_LOCK_EX, timer->index); + FILE *fp = open_dict(DICT_LOCK_EX, timer->index, &mu); //timer->status = 0; if(fp) { md5((uint8_t*)timer->dat, strlen(timer->dat)+1, digest); @@ -373,7 +378,7 @@ static int s4_del(THREADTIMER *timer) { static int s5_md5(THREADTIMER *timer) { //timer->status = 0; - fill_md5(); + fill_md5(&mu); if(is_md5_equal((uint8_t*)timer->dat)) return send_data(timer->accept_fd, timer->index, "null", 4); else return send_data(timer->accept_fd, timer->index, "nequ", 4); } @@ -400,7 +405,6 @@ static void accept_timer(void *p) { pthread_t thread = accept_threads[index]; if(thread) { pthread_kill(thread, SIGQUIT); - accept_threads[index] = 0; puts("Kill thread"); } } @@ -418,9 +422,9 @@ static void kill_thread(THREADTIMER* timer) { timer->ptr = NULL; puts("Free data"); } - if(timer->lock_type) close_dict(timer->lock_type, timer->index); + if(timer->lock_type) close_dict(timer->lock_type, timer->index, &mu); free(timer); - puts("Finish killing\n"); + puts("Finish killing"); } static void handle_pipe(int signo) { @@ -433,9 +437,7 @@ static void handle_accept(void *p) { if(accept_fd > 0) { puts("\nConnected to the client"); pthread_t thread; - pthread_key_t key; - pthread_key_create(&key, (void *)&kill_thread); - pthread_setspecific(key, p); + pthread_cleanup_push((void*)&kill_thread, p); if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) puts("Error creating timer thread"); else puts("Creating timer thread succeeded"); //send_data(accept_fd, "Welcome to simple dict server.", 31); @@ -541,6 +543,7 @@ static void handle_accept(void *p) { } CONV_END: puts("Conversation end"); } else puts("Error allocating buffer"); + pthread_cleanup_pop(1); puts("Thread exited normally"); } else puts("Error accepting client"); } @@ -601,7 +604,7 @@ static void accept_client() { } static int close_and_send(THREADTIMER* timer, char *data, size_t numbytes) { - close_dict(timer->lock_type, timer->index); + close_dict(timer->lock_type, timer->index, &mu); return send_data(timer->accept_fd, timer->index, data, numbytes); } @@ -622,7 +625,7 @@ int main(int argc, char *argv[]) { if(!fp) fp = fopen(argv[as_daemon?4:3], "wb+"); if(fp) { fclose(fp); - if(init_dict(argv[as_daemon?4:3])) { + if(init_dict(argv[as_daemon?4:3], &mu)) { fp = NULL; if(argv[as_daemon?5:4][0] == '-') { // use env fp = (FILE*)1;