From fd40c204e2773a34fe76c126c3f25df56b0872b4 Mon Sep 17 00:00:00 2001 From: krangelov Date: Tue, 26 Oct 2021 10:14:16 +0200 Subject: [PATCH] more aggressive cleanup for dead processes --- src/runtime/c/pgf/ipc.cxx | 129 +++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/src/runtime/c/pgf/ipc.cxx b/src/runtime/c/pgf/ipc.cxx index 5045a6dce..2aa14387a 100644 --- a/src/runtime/c/pgf/ipc.cxx +++ b/src/runtime/c/pgf/ipc.cxx @@ -56,6 +56,55 @@ static char gf_runtime_locks[] = "/gf-runtime-locks"; static file_locks *locks = NULL; +static +void ipc_cleanup_dead_processes() +{ + ptr_t(lock_entry) *last = &locks->lock_entries; + lock_entry *entry = ptr(*last, lock_entry); + while (entry != NULL) { + process_entry *pentry = &entry->p; + ptr_t(process_entry) *plast = NULL; + while (pentry != NULL) { + char proc_file[32]; + sprintf(proc_file, "/proc/%d", pentry->pid); + if (access(proc_file, F_OK) != 0) { + // if there are dead processes -> remove them + if (plast == NULL) { + if (entry->p.next == 0) { + *last = entry->next; + entry->next = locks->free_lock_entries; + entry->dev = 0; + entry->ino = 0; + entry->p.pid = 0; + locks->free_lock_entries = offs(entry); + goto next; + } else { + process_entry *tmp = + ptr(pentry->next, process_entry); + *pentry = *tmp; + tmp->pid = 0; + tmp->next = locks->free_process_entries; + locks->free_process_entries = offs(tmp); + } + } else { + *plast = pentry->next; + pentry->pid = 0; + pentry->next = locks->free_process_entries; + locks->free_process_entries = offs(pentry); + pentry = ptr(*plast,process_entry); + } + } else { + plast = &pentry->next; + pentry = ptr(*plast,process_entry); + } + } + + last = &entry->next; +next: + entry = ptr(*last, lock_entry); + } +} + PGF_INTERNAL pthread_rwlock_t *ipc_new_file_rwlock(const char* file_path) { @@ -130,6 +179,8 @@ pthread_rwlock_t *ipc_new_file_rwlock(const char* file_path) pthread_mutex_lock(&locks->mutex); + ipc_cleanup_dead_processes(); + lock_entry *entry = ptr(locks->lock_entries, lock_entry); while (entry != NULL) { if (entry->dev == s.st_dev && entry->ino == s.st_ino) { @@ -170,54 +221,22 @@ pthread_rwlock_t *ipc_new_file_rwlock(const char* file_path) entry->next = locks->lock_entries; locks->lock_entries = offs(entry); } else { - process_entry *pentry = &entry->p; - ptr_t(process_entry) *plast = NULL; - while (pentry != NULL) { - char proc_file[32]; - sprintf(proc_file, "/proc/%d", pentry->pid); - if (access(proc_file, F_OK) != 0) { - // if there are dead processes -> remove them - if (plast == NULL) { - if (entry->p.next == 0) { - entry->p.pid = 0; - break; - } else { - process_entry *tmp = - ptr(pentry->next, process_entry); - *pentry = *tmp; - tmp->pid = 0; - tmp->next = locks->free_process_entries; - locks->free_process_entries = offs(tmp); - } - } else { - *plast = pentry->next; - pentry->pid = 0; - pentry->next = locks->free_process_entries; - locks->free_process_entries = offs(pentry); - pentry = ptr(*plast,process_entry); - } - } else { - plast = &pentry->next; - pentry = ptr(*plast,process_entry); + process_entry *pentry; + if (locks->free_process_entries) { + pentry = ptr(locks->free_process_entries,process_entry); + locks->free_process_entries = pentry->next; + } else { + if (locks->top+sizeof(process_entry) > pagesize) { + pthread_mutex_unlock(&locks->mutex); + ipc_toomany(); } + pentry = ptr(locks->top,process_entry); + locks->top += sizeof(process_entry); } - if (plast != NULL) { - if (locks->free_process_entries) { - pentry = ptr(locks->free_process_entries,process_entry); - locks->free_process_entries = pentry->next; - } else { - if (locks->top+sizeof(process_entry) > pagesize) { - pthread_mutex_unlock(&locks->mutex); - ipc_toomany(); - } - pentry = ptr(locks->top,process_entry); - locks->top += sizeof(process_entry); - } - *plast = offs(pentry); - } pentry->pid = getpid(); - pentry->next = 0; + pentry->next = entry->p.next; + entry->p.next = offs(pentry); } pthread_mutex_unlock(&locks->mutex); @@ -240,6 +259,8 @@ void ipc_release_file_rwlock(const char* file_path, pthread_mutex_lock(&locks->mutex); + ipc_cleanup_dead_processes(); + lock_entry *entry = ptr(locks->lock_entries,lock_entry); ptr_t(lock_entry) *last = &locks->lock_entries; while (entry != NULL) { @@ -256,9 +277,6 @@ void ipc_release_file_rwlock(const char* file_path, ptr_t(process_entry) *plast = NULL; while (pentry != NULL) { if (pentry->pid == pid) { - pid = -1; // only the first entry should be removed - -free_it: if (plast == NULL) { if (entry->p.next == 0) { *last = entry->next; @@ -267,7 +285,6 @@ free_it: entry->ino = 0; entry->p.pid = 0; locks->free_lock_entries = offs(entry); - break; } else { process_entry *tmp = ptr(pentry->next, process_entry); @@ -281,19 +298,13 @@ free_it: pentry->pid = 0; pentry->next = locks->free_process_entries; locks->free_process_entries = offs(pentry); - pentry = ptr(*plast,process_entry); - } - } else { - char proc_file[32]; - sprintf(proc_file, "/proc/%d", pentry->pid); - if (access(proc_file, F_OK) != 0) { - // if there are dead processes -> remove them too - goto free_it; - } else { - plast = &pentry->next; - pentry = ptr(*plast,process_entry); } + + break; } + + plast = &pentry->next; + pentry = ptr(*plast,process_entry); } }