diff --git a/demo/test_handle_logger.c b/demo/test_handle_logger.c index f9cee4a..d14b8f8 100644 --- a/demo/test_handle_logger.c +++ b/demo/test_handle_logger.c @@ -164,8 +164,8 @@ int main(int argc, char ** args) { pthread_create(&t[i], NULL, thread_logger, (void *)(unsigned long)(i)); } - signal(SIGINT, sig_int_handler); - signal(SIGHUP, sig_hup_handler); + //signal(SIGINT, sig_int_handler); + //signal(SIGHUP, sig_hup_handler); while(1) ; //MESA_destroy_runtime_log_handle(sample_handle); diff --git a/inc/MESA_shm_ring_queue.h b/inc/MESA_shm_ring_queue.h index ed9d712..ca1e065 100644 --- a/inc/MESA_shm_ring_queue.h +++ b/inc/MESA_shm_ring_queue.h @@ -37,16 +37,17 @@ struct MESA_shm_queue_head{ }; -int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_status); +int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, int **consumer_status); struct MESA_shm_queue_head *MESA_shm_get_ring_queue(); void MESA_shm_init_mutex(); -void MESA_shm_init_overview(); +void MESA_shm_init(); void MESA_shm_recycle_ring_queue(struct MESA_shm_queue_head *ring_queue_head); int MESA_shm_copy_buf_to_ring_queue(char *buf, int buflen, struct MESA_shm_queue_head *head, char *log_file, int log_file_len); int MESA_shm_ring_queue_is_empty(struct MESA_shm_queue_head *head); int MESA_shm_ring_queue_is_full(struct MESA_shm_queue_head *head); void MESA_shm_ring_queue_set_empty(struct MESA_shm_queue_head *head); int MESA_shm_get_consumer_status(); +void MESA_shm_unlink(struct MESA_shm_overview *ovw, int ovw_shmid); #endif diff --git a/shm_consumer/MESA_shm_consumer.c b/shm_consumer/MESA_shm_consumer.c index d4105dd..4b1b537 100644 --- a/shm_consumer/MESA_shm_consumer.c +++ b/shm_consumer/MESA_shm_consumer.c @@ -24,7 +24,6 @@ #define CONSUMER_CARE_PID_SPEC 1 #define CONSUMER_CARE_PID_MAX_LEN 128 -int g_cur_tty_fd = -1; struct log_file_list{ char log_file_pre[MESA_SHM_LOG_PATH_LEN]; @@ -44,6 +43,10 @@ struct care_pid_list g_care_pid_list; int g_output_mode = CONSUMER_OUTPUT_MODE_FILE; int g_care_pid = CONSUMER_CARE_PID_ALL; int *g_status = NULL; +int g_cur_tty_fd = -1; +struct MESA_shm_overview *g_shm_overview = NULL; +int g_shm_overview_id = -1; + void init_ring_queue_head_arrray(struct MESA_shm_overview *ovw, struct MESA_shm_queue_head **ring_queue_head) { @@ -514,12 +517,33 @@ error: } void signal_handler_exit(int signum) { - if(g_status == NULL){ - exit(0); + struct shmid_ds buf; + if(g_status != NULL){ + *g_status = MESA_CONSUMER_NOT_RUNNING; } - *g_status = MESA_CONSUMER_NOT_RUNNING; + if(g_shm_overview == NULL || g_shm_overview_id == -1){ + goto out; + } + if(shmctl(g_shm_overview_id, IPC_STAT, &buf) == -1){ + goto out; + } + if(buf.shm_nattch <= 1){ + /* + This is the last process to use this shared memory, + we need to unlink the shared memory before the process exit + */ + MESA_shm_unlink(g_shm_overview, g_shm_overview_id); + } +out: exit(0); } +/* +if we use shmctl function and IPC_RMID parameter, +the shared memory will actually be destroyed only after the last process detaches it, +but no more attaches for the shared memory identified by the shmid parameter are allowed, +producer process and consumer process start at an indeterminate time, +so we have to use IPC_RMID parameter to unlink the shared memory when all processes exit +*/ void register_sginal_handler() { signal(SIGKILL, signal_handler_exit); @@ -564,20 +588,20 @@ int main(int argc, char **argv) } int i = 0; int ret = 0; - struct MESA_shm_overview *shm_overview = NULL; + struct MESA_shm_overview *tmp_ovw = NULL; struct MESA_shm_queue_head *ring_queue_head[MESA_SHM_RING_QUEUE_NUM] = {NULL}; INIT_LIST_HEAD(&g_log_file_list.list); - ret = MESA_shm_alloc_overview(&shm_overview, &g_status); + ret = MESA_shm_alloc_overview(&g_shm_overview, &g_shm_overview_id, &g_status); if(ret < 0){ return 0; } *g_status = MESA_CONSUMER_RUNNING; register_sginal_handler(); - init_ring_queue_head_arrray(shm_overview, ring_queue_head); + init_ring_queue_head_arrray(g_shm_overview, ring_queue_head); while(1){ for(i = 0; i< MESA_SHM_RING_QUEUE_NUM; i++){ - tmp_ovw = shm_overview + i; + tmp_ovw = g_shm_overview + i; if(tmp_ovw->shmid == -1){ break; } diff --git a/src/MESA_handle_logger.c b/src/MESA_handle_logger.c index 4c378cd..54d5bd4 100644 --- a/src/MESA_handle_logger.c +++ b/src/MESA_handle_logger.c @@ -264,7 +264,7 @@ void MESA_free_pthread_private(void *arg) void MESA_alloc_pthread_key() { pthread_key_create(&MESA_pthread_key, MESA_free_pthread_private); - MESA_shm_init_overview(); + MESA_shm_init(); return ; } diff --git a/src/MESA_shm_ring_queue.c b/src/MESA_shm_ring_queue.c index 44c9ee6..ac921a9 100644 --- a/src/MESA_shm_ring_queue.c +++ b/src/MESA_shm_ring_queue.c @@ -7,14 +7,15 @@ #include #include #include +#include #include "MESA_handle_logger.h" #include "MESA_shm_ring_queue.h" #include "list.h" - struct MESA_shm_overview *MESA_shm_ovw = NULL; int *MESA_consumer_status = NULL; struct MESA_shm_queue_head *MESA_ring_queue_head[MESA_SHM_RING_QUEUE_NUM] = {NULL}; +int MESA_shm_ovw_id = -1; void MESA_shm_init_ring_queue_mutex(struct MESA_shm_overview *ovw) @@ -34,8 +35,61 @@ int MESA_shm_get_consumer_status() } return *MESA_consumer_status; } - -int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_status) +void MESA_shm_unlink(struct MESA_shm_overview *ovw, int ovw_shmid) +{ + int i; + struct MESA_shm_overview *tmp_ovw; + if(ovw == NULL || ovw_shmid == -1){ + return ; + } + for(i = 0; i < MESA_SHM_RING_QUEUE_NUM; i++){ + tmp_ovw = ovw + i; + if(tmp_ovw->shmid != -1){ + shmctl(tmp_ovw->shmid, IPC_RMID, NULL); + } + } + shmctl(ovw_shmid, IPC_RMID, NULL); + return ; +} +void MESA_shm_check_unlink(int signum) +{ + struct shmid_ds buf; + if(MESA_shm_ovw == NULL || MESA_shm_ovw_id == -1){ + return ; + } + if(shmctl(MESA_shm_ovw_id, IPC_STAT, &buf) == -1){ + return ; + } + if(buf.shm_nattch <= 1){ + /* + This is the last process to use this shared memory, + we need to unlink the shared memory before the process exit + */ + MESA_shm_unlink(MESA_shm_ovw, MESA_shm_ovw_id); + } + exit(0); +} +/* +if we use shmctl function and IPC_RMID parameter, +the shared memory will actually be destroyed only after the last process detaches it, +but no more attaches for the shared memory identified by the shmid parameter are allowed, +producer process and consumer process start at an indeterminate time, +so we have to use IPC_RMID parameter to unlink the shared memory when all processes exit +*/ +void MESA_shm_register_sginal_handler() +{ + signal(SIGKILL, MESA_shm_check_unlink); + signal(SIGTRAP, MESA_shm_check_unlink); + signal(SIGABRT, MESA_shm_check_unlink); + signal(SIGBUS, MESA_shm_check_unlink); + signal(SIGFPE, MESA_shm_check_unlink); + signal(SIGSEGV, MESA_shm_check_unlink); + signal(SIGTERM, MESA_shm_check_unlink); + signal(SIGINT, MESA_shm_check_unlink); + signal(SIGQUIT, MESA_shm_check_unlink); + return ; +} +int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, int **consumer_status) { int shmsize = (sizeof(struct MESA_shm_overview) * MESA_SHM_RING_QUEUE_NUM) + sizeof(int); struct MESA_shm_overview *shm_overview = NULL; @@ -61,6 +115,7 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_statu } *ovw = shm_overview; *consumer_status = (int *)(shm_overview + MESA_SHM_RING_QUEUE_NUM); + *ovw_id = shmid; } }else{ shm_overview = (struct MESA_shm_overview *)shmat(shmid, NULL, 0); @@ -69,14 +124,16 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int **consumer_statu } *ovw = shm_overview; *consumer_status = (int *)(shm_overview + MESA_SHM_RING_QUEUE_NUM); + *ovw_id = shmid; } return 0; } -void MESA_shm_init_overview() +void MESA_shm_init() { - if(MESA_shm_ovw == NULL || MESA_consumer_status == NULL){ - MESA_shm_alloc_overview(&MESA_shm_ovw, &MESA_consumer_status); + if(MESA_shm_ovw == NULL || MESA_consumer_status == NULL || MESA_shm_ovw_id == -1){ + MESA_shm_alloc_overview(&MESA_shm_ovw, &MESA_shm_ovw_id, &MESA_consumer_status); } + MESA_shm_register_sginal_handler(); return ; } @@ -89,7 +146,6 @@ void MESA_shm_init_new_ring_queue(struct MESA_shm_queue_head *head, struct MESA_ head->ovw_idx = ovw->idx; return ; } - void MESA_shm_recycle_ring_queue(struct MESA_shm_queue_head *ring_queue_head) { if(MESA_shm_ovw == NULL){ diff --git a/src/version.map b/src/version.map index c815f8a..c46b80a 100644 --- a/src/version.map +++ b/src/version.map @@ -1,4 +1,4 @@ { - global: MESA*runtime_log*;GIT_VERSION_*;MESA_shm_alloc*;MESA_handle_fmt_rule_register;MESA_shm_ring_queue*; + global: MESA*runtime_log*;GIT_VERSION_*;MESA_shm_alloc*;MESA_handle_fmt_rule_register;MESA_shm_ring_queue*;MESA_shm_unlink; local: *; };