diff --git a/dict.h b/dict.h index afbac6e..69b0064 100644 --- a/dict.h +++ b/dict.h @@ -26,8 +26,7 @@ static uint8_t dict_md5[16]; static volatile int is_ex_dict_open; static volatile int is_ex_dict_opening; -static FILE* dict_fp = NULL; //fp for EX -static FILE* dict_fp_read = NULL; //fp for md5 +static FILE* dict_fp = NULL; // fp for EX static FILE* dict_thread_fp[THREADCNT]; static pthread_rwlock_t mu; @@ -45,7 +44,7 @@ static inline off_t get_dict_size() { return -1; } -static int fill_md5(pthread_rwlock_t* mu) { +static int fill_md5(FILE* fp) { size_t size = get_dict_size(); if(!size) { memset(dict_md5, 0, 16); @@ -54,18 +53,17 @@ static int fill_md5(pthread_rwlock_t* mu) { } uint8_t* dict_buff = (uint8_t*)malloc(size); if(dict_buff) { - if(pthread_rwlock_tryrdlock(mu)) { + if(pthread_rwlock_tryrdlock(&mu)) { perror("Readlock busy"); return 1; } - rewind(dict_fp_read); - if(fread(dict_buff, size, 1, dict_fp_read) == 1) { - pthread_rwlock_unlock(mu); + if(fread(dict_buff, size, 1, fp) == 1) { + pthread_rwlock_unlock(&mu); md5(dict_buff, size, dict_md5); free(dict_buff); return 0; } else { - pthread_rwlock_unlock(mu); + pthread_rwlock_unlock(&mu); free(dict_buff); perror("Read dict error"); return 2; @@ -76,23 +74,22 @@ static int fill_md5(pthread_rwlock_t* mu) { } } -static int init_dict(char* file_path, pthread_rwlock_t* mu) { +static int init_dict(char* file_path) { dict_fp = fopen(file_path, "rb+"); - dict_fp_read = fopen(file_path, "rb"); if(dict_fp) { - int err = pthread_rwlock_init(mu, NULL); + int err = pthread_rwlock_init(&mu, NULL); if(err) { perror("Init lock error"); return 1; } dict_filepath = file_path; - return fill_md5(mu); + return fill_md5(dict_fp); } perror("Open dict error"); return 2; } -static FILE* open_ex_dict() { +static inline FILE* open_ex_dict() { is_ex_dict_opening = 1; if(pthread_rwlock_wrlock(&mu)) { perror("Open dict: Writelock busy"); @@ -106,12 +103,12 @@ static FILE* open_ex_dict() { return dict_fp; } -static FILE* open_shared_dict(uint32_t index) { +static inline FILE* open_shared_dict(uint32_t index, int requirelock) { if(index >= THREADCNT) { puts("Open dict: Index out of bounds"); return NULL; } - if(pthread_rwlock_tryrdlock(&mu)) { + if(requirelock && pthread_rwlock_tryrdlock(&mu)) { perror("Open dict: Readlock busy"); return NULL; } @@ -120,12 +117,19 @@ static FILE* open_shared_dict(uint32_t index) { return dict_thread_fp[index]; } -static inline FILE* get_dict_fp_rd() { - rewind(dict_fp_read); - return dict_fp_read; +static inline int require_shared_lock(uint32_t index) { + if(index >= THREADCNT) { + puts("Open dict: Index out of bounds"); + return 1; + } + if(pthread_rwlock_tryrdlock(&mu)) { + perror("Open dict: Readlock busy"); + return 1; + } + return 0; } -static void close_ex_dict() { +static inline void close_ex_dict() { if(is_ex_dict_open) { fflush(dict_fp); for(int i = 0; i < THREADCNT; i++) { @@ -140,7 +144,7 @@ static void close_ex_dict() { } else puts("Ex dict already closed"); } -static void close_shared_dict() { +static inline void close_shared_dict() { pthread_rwlock_unlock(&mu); puts("Close shared dict"); } diff --git a/server.c b/server.c index 37cb14e..98078f3 100644 --- a/server.c +++ b/server.c @@ -61,6 +61,7 @@ static void handle_accept(void *accept_fd_p); static void handle_int(int signo); static void handle_pipe(int signo); static void handle_quit(int signo); +static void handle_segv(int signo); static void init_dict_pool(FILE *fp); static int insert_item(FILE *fp, const dict_t* dict, int keysize, int datasize); static void kill_timer(pthread_t thread); @@ -141,7 +142,7 @@ static int send_data(int accept_fd, int index, server_ack_t cmd, const char *dat static int send_all(thread_timer_t *timer) { int re = 1; - FILE *fp = open_shared_dict(timer->index); + FILE *fp = open_shared_dict(timer->index, 1); if(fp == NULL) return 1; pthread_cleanup_push((void*)&close_shared_dict, NULL); off_t len = 0, file_size = get_dict_size(); @@ -215,8 +216,8 @@ static void init_dict_pool(FILE *fp) { static int s1_get(thread_timer_t *timer) { uint8_t digest[16]; uint8_t buf[8+DICTSZ]; - FILE *fp = open_shared_dict(timer->index); - if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4); + if(require_shared_lock(timer->index)) // busy + return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4); int ret = -1; pthread_cleanup_push((void*)&close_shared_dict, NULL); while(1) { @@ -234,6 +235,12 @@ static int s1_get(thread_timer_t *timer) { break; } + FILE *fp = open_shared_dict(timer->index, 0); // really open + if(fp == NULL) { + ret = send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4); + break; + } + while(has_next(fp, ch)) { if(!ch) continue; // skip null bytes SIMPLE_PB* spb = read_pb_into(fp, (SIMPLE_PB*)buf); @@ -481,8 +488,14 @@ static int s4_del(thread_timer_t *timer) { } static int s5_md5(thread_timer_t *timer) { - fill_md5(&mu); - if(is_dict_md5_equal((uint8_t*)timer->dat)) return send_data(timer->accept_fd, timer->index, ACKNULL, "null", 4); + FILE* fp = open_shared_dict(timer->index, 1); + if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4); + int r; + pthread_cleanup_push((void*)&close_shared_dict, NULL); + fill_md5(fp); + r = is_dict_md5_equal((uint8_t*)timer->dat); + pthread_cleanup_pop(1); + if(r) return send_data(timer->accept_fd, timer->index, ACKNULL, "null", 4); else return send_data(timer->accept_fd, timer->index, ACKNEQU, "nequ", 4); } @@ -491,6 +504,12 @@ static void handle_quit(int signo) { pthread_exit(NULL); } +static void handle_segv(int signo) { + puts("Handle kill/segv/term"); + fflush(stdout); + pthread_exit(NULL); +} + static void accept_timer(void *p) { thread_timer_t *timer = timer_pointer_of(p); uint32_t index = timer->index; @@ -665,12 +684,14 @@ static void accept_client(int fd) { }*/ signal(SIGINT, handle_int); signal(SIGQUIT, handle_quit); - signal(SIGKILL, exit); + signal(SIGKILL, handle_segv); + signal(SIGSEGV, handle_segv); signal(SIGPIPE, handle_pipe); + signal(SIGTERM, handle_segv); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); init_crypto(); - init_dict_pool(get_dict_fp_rd()); + init_dict_pool(open_shared_dict(0, 0)); while(1) { puts("Ready for accept, waitting..."); int p = 0; @@ -742,7 +763,7 @@ int main(int argc, char *argv[]) { return 3; } fclose(fp); - if(init_dict(argv[as_daemon?3:2], &mu)) + if(init_dict(argv[as_daemon?3:2])) return 4; fp = NULL; if(argv[as_daemon?4:3][0] == '-') { // use env