more aggressive cleanup for dead processes

This commit is contained in:
krangelov
2021-10-26 10:14:16 +02:00
parent 00ba552026
commit fd40c204e2

View File

@@ -56,6 +56,55 @@ static char gf_runtime_locks[] = "/gf-runtime-locks";
static file_locks *locks = NULL; 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 PGF_INTERNAL
pthread_rwlock_t *ipc_new_file_rwlock(const char* file_path) 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); pthread_mutex_lock(&locks->mutex);
ipc_cleanup_dead_processes();
lock_entry *entry = ptr(locks->lock_entries, lock_entry); lock_entry *entry = ptr(locks->lock_entries, lock_entry);
while (entry != NULL) { while (entry != NULL) {
if (entry->dev == s.st_dev && entry->ino == s.st_ino) { 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; entry->next = locks->lock_entries;
locks->lock_entries = offs(entry); locks->lock_entries = offs(entry);
} else { } else {
process_entry *pentry = &entry->p; process_entry *pentry;
ptr_t(process_entry) *plast = NULL; if (locks->free_process_entries) {
while (pentry != NULL) { pentry = ptr(locks->free_process_entries,process_entry);
char proc_file[32]; locks->free_process_entries = pentry->next;
sprintf(proc_file, "/proc/%d", pentry->pid); } else {
if (access(proc_file, F_OK) != 0) { if (locks->top+sizeof(process_entry) > pagesize) {
// if there are dead processes -> remove them pthread_mutex_unlock(&locks->mutex);
if (plast == NULL) { ipc_toomany();
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);
} }
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->pid = getpid();
pentry->next = 0; pentry->next = entry->p.next;
entry->p.next = offs(pentry);
} }
pthread_mutex_unlock(&locks->mutex); pthread_mutex_unlock(&locks->mutex);
@@ -240,6 +259,8 @@ void ipc_release_file_rwlock(const char* file_path,
pthread_mutex_lock(&locks->mutex); pthread_mutex_lock(&locks->mutex);
ipc_cleanup_dead_processes();
lock_entry *entry = ptr(locks->lock_entries,lock_entry); lock_entry *entry = ptr(locks->lock_entries,lock_entry);
ptr_t(lock_entry) *last = &locks->lock_entries; ptr_t(lock_entry) *last = &locks->lock_entries;
while (entry != NULL) { while (entry != NULL) {
@@ -256,9 +277,6 @@ void ipc_release_file_rwlock(const char* file_path,
ptr_t(process_entry) *plast = NULL; ptr_t(process_entry) *plast = NULL;
while (pentry != NULL) { while (pentry != NULL) {
if (pentry->pid == pid) { if (pentry->pid == pid) {
pid = -1; // only the first entry should be removed
free_it:
if (plast == NULL) { if (plast == NULL) {
if (entry->p.next == 0) { if (entry->p.next == 0) {
*last = entry->next; *last = entry->next;
@@ -267,7 +285,6 @@ free_it:
entry->ino = 0; entry->ino = 0;
entry->p.pid = 0; entry->p.pid = 0;
locks->free_lock_entries = offs(entry); locks->free_lock_entries = offs(entry);
break;
} else { } else {
process_entry *tmp = process_entry *tmp =
ptr(pentry->next, process_entry); ptr(pentry->next, process_entry);
@@ -281,19 +298,13 @@ free_it:
pentry->pid = 0; pentry->pid = 0;
pentry->next = locks->free_process_entries; pentry->next = locks->free_process_entries;
locks->free_process_entries = offs(pentry); 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);
} }
} }