mirror of
https://github.com/fumiama/simple-dict.git
synced 2026-06-28 16:00:25 +08:00
fix: close exdict race
This commit is contained in:
17
dict.h
17
dict.h
@@ -25,6 +25,7 @@ static uint8_t dict_md5[16];
|
|||||||
|
|
||||||
static volatile int is_ex_dict_open;
|
static volatile int is_ex_dict_open;
|
||||||
static volatile int is_ex_dict_opening;
|
static volatile int is_ex_dict_opening;
|
||||||
|
static volatile uint32_t ex_dict_owner_index = (uint32_t)-1;
|
||||||
|
|
||||||
static FILE* dict_fp = NULL; // fp for EX
|
static FILE* dict_fp = NULL; // fp for EX
|
||||||
static FILE* dict_thread_fp[THREADCNT];
|
static FILE* dict_thread_fp[THREADCNT];
|
||||||
@@ -89,17 +90,23 @@ static int init_dict(char* file_path) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FILE* open_ex_dict() {
|
static inline FILE* open_ex_dict(uint32_t index) {
|
||||||
is_ex_dict_opening = 1;
|
is_ex_dict_opening = 1;
|
||||||
if(pthread_rwlock_wrlock(&mu)) {
|
if(pthread_rwlock_wrlock(&mu)) {
|
||||||
perror("Open dict: Writelock busy");
|
perror("Open ex dict: Writelock busy");
|
||||||
is_ex_dict_opening = 0;
|
is_ex_dict_opening = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
is_ex_dict_opening = 0;
|
is_ex_dict_opening = 0;
|
||||||
if(!dict_fp) dict_fp = fopen(dict_filepath, "rb+");
|
if(!dict_fp) dict_fp = fopen(dict_filepath, "rb+");
|
||||||
else rewind(dict_fp);
|
else rewind(dict_fp);
|
||||||
if(dict_fp) is_ex_dict_open = 1;
|
if(!dict_fp) {
|
||||||
|
perror("Open ex dict: fopen");
|
||||||
|
pthread_rwlock_unlock(&mu);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
is_ex_dict_open = 1;
|
||||||
|
ex_dict_owner_index = index;
|
||||||
puts("Open ex dict");
|
puts("Open ex dict");
|
||||||
return dict_fp;
|
return dict_fp;
|
||||||
}
|
}
|
||||||
@@ -132,7 +139,8 @@ static inline int require_shared_lock(uint32_t index) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void close_ex_dict() {
|
static inline void close_ex_dict(uint32_t index) {
|
||||||
|
if(index != ex_dict_owner_index) return;
|
||||||
if(is_ex_dict_open) {
|
if(is_ex_dict_open) {
|
||||||
fflush(dict_fp);
|
fflush(dict_fp);
|
||||||
for(int i = 0; i < THREADCNT; i++) {
|
for(int i = 0; i < THREADCNT; i++) {
|
||||||
@@ -142,6 +150,7 @@ static inline void close_ex_dict() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is_ex_dict_open = 0;
|
is_ex_dict_open = 0;
|
||||||
|
ex_dict_owner_index = (uint32_t)-1;
|
||||||
pthread_rwlock_unlock(&mu);
|
pthread_rwlock_unlock(&mu);
|
||||||
puts("Close ex dict");
|
puts("Close ex dict");
|
||||||
} else puts("Ex dict already closed");
|
} else puts("Ex dict already closed");
|
||||||
|
|||||||
12
server.c
12
server.c
@@ -338,7 +338,7 @@ ERR_INSERT_ITEM:
|
|||||||
|
|
||||||
static int s3_set_data(thread_timer_t *timer) {
|
static int s3_set_data(thread_timer_t *timer) {
|
||||||
if(!setdicts[timer->index].data[0]) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
if(!setdicts[timer->index].data[0]) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
||||||
FILE *fp = open_ex_dict();
|
FILE *fp = open_ex_dict(timer->index);
|
||||||
if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
||||||
|
|
||||||
int datasize = (timer->numbytes > (DICTDATSZ-1))?(DICTDATSZ-1):timer->numbytes;
|
int datasize = (timer->numbytes > (DICTDATSZ-1))?(DICTDATSZ-1):timer->numbytes;
|
||||||
@@ -349,7 +349,7 @@ static int s3_set_data(thread_timer_t *timer) {
|
|||||||
return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
pthread_cleanup_push((void*)&close_ex_dict, NULL);
|
pthread_cleanup_push((void*)&close_ex_dict, (void*)(uintptr_t)timer->index);
|
||||||
|
|
||||||
uint8_t* dp = (uint8_t*)setdicts[timer->index].data;
|
uint8_t* dp = (uint8_t*)setdicts[timer->index].data;
|
||||||
touch_timer(timer);
|
touch_timer(timer);
|
||||||
@@ -463,10 +463,10 @@ static int s4_del(thread_timer_t *timer) {
|
|||||||
uint8_t digest[16];
|
uint8_t digest[16];
|
||||||
char ret[4];
|
char ret[4];
|
||||||
int r;
|
int r;
|
||||||
FILE *fp = open_ex_dict();
|
FILE *fp = open_ex_dict(timer->index);
|
||||||
if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
if(fp == NULL) return send_data(timer->accept_fd, timer->index, ACKERRO, "erro", 4);
|
||||||
|
|
||||||
pthread_cleanup_push((void*)&close_ex_dict, NULL);
|
pthread_cleanup_push((void*)&close_ex_dict, (void*)(uintptr_t)timer->index);
|
||||||
while(1) {
|
while(1) {
|
||||||
md5((uint8_t*)timer->dat, strlen(timer->dat)+1, digest);
|
md5((uint8_t*)timer->dat, strlen(timer->dat)+1, digest);
|
||||||
uint8_t* dp = digest;
|
uint8_t* dp = digest;
|
||||||
@@ -551,7 +551,7 @@ static void cleanup_thread(thread_timer_t* timer) {
|
|||||||
timer->accept_fd = 0;
|
timer->accept_fd = 0;
|
||||||
puts("Close accept");
|
puts("Close accept");
|
||||||
}
|
}
|
||||||
close_ex_dict();
|
close_ex_dict(timer->index);
|
||||||
puts("Finish cleaning");
|
puts("Finish cleaning");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,7 +566,7 @@ static void handle_pipe(int signo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_accept(void *p) {
|
static void handle_accept(void *p) {
|
||||||
puts("Connected to the client, handling accept...");
|
puts("Handling accept...");
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) {
|
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) {
|
||||||
perror("Error creating timer thread");
|
perror("Error creating timer thread");
|
||||||
|
|||||||
Reference in New Issue
Block a user