forked from PsychoticNinja/irssi
Rewrite pidwait using g_child_watch_add.
git-svn-id: file:///var/www/svn.irssi.org/SVN/irssi/trunk@4975 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
baba2b7505
commit
8cc7a02b4d
@ -22,24 +22,39 @@
|
|||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
#include <sys/wait.h>
|
static GHashTable *child_pids;
|
||||||
|
|
||||||
static GSList *pids;
|
static GSList *pids;
|
||||||
|
|
||||||
static unsigned int childcheck_tag;
|
|
||||||
static int signal_pidwait;
|
static int signal_pidwait;
|
||||||
|
|
||||||
|
static void sig_child(GPid pid, gint status, gpointer data)
|
||||||
|
{
|
||||||
|
signal_emit_id(signal_pidwait, 2, GINT_TO_POINTER(pid),
|
||||||
|
GINT_TO_POINTER(status));
|
||||||
|
g_hash_table_remove(child_pids, GINT_TO_POINTER(pid));
|
||||||
|
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
|
||||||
|
}
|
||||||
|
|
||||||
/* add a pid to wait list */
|
/* add a pid to wait list */
|
||||||
void pidwait_add(int pid)
|
void pidwait_add(int pid)
|
||||||
{
|
{
|
||||||
|
if (g_hash_table_lookup(child_pids, GINT_TO_POINTER(pid)) == NULL) {
|
||||||
|
int id = g_child_watch_add_full(10, pid, sig_child, NULL, NULL);
|
||||||
|
g_hash_table_insert(child_pids, GINT_TO_POINTER(pid), GINT_TO_POINTER(id));
|
||||||
pids = g_slist_append(pids, GINT_TO_POINTER(pid));
|
pids = g_slist_append(pids, GINT_TO_POINTER(pid));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* remove pid from wait list */
|
/* remove pid from wait list */
|
||||||
void pidwait_remove(int pid)
|
void pidwait_remove(int pid)
|
||||||
{
|
{
|
||||||
|
gpointer id = g_hash_table_lookup(child_pids, GINT_TO_POINTER(pid));
|
||||||
|
if (id != NULL) {
|
||||||
|
g_source_remove(GPOINTER_TO_INT(id));
|
||||||
|
g_hash_table_remove(child_pids, GINT_TO_POINTER(pid));
|
||||||
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
|
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* return list of pids that are being waited.
|
/* return list of pids that are being waited.
|
||||||
don't free the return value. */
|
don't free the return value. */
|
||||||
@ -48,37 +63,16 @@ GSList *pidwait_get_pids(void)
|
|||||||
return pids;
|
return pids;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int child_check(void)
|
|
||||||
{
|
|
||||||
GSList *tmp, *next;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
/* wait for each pid.. */
|
|
||||||
for (tmp = pids; tmp != NULL; tmp = next) {
|
|
||||||
int pid = GPOINTER_TO_INT(tmp->data);
|
|
||||||
|
|
||||||
next = tmp->next;
|
|
||||||
if (waitpid(pid, &status, WNOHANG) > 0) {
|
|
||||||
/* process terminated, remove from list */
|
|
||||||
signal_emit_id(signal_pidwait, 2, tmp->data,
|
|
||||||
GINT_TO_POINTER(status));
|
|
||||||
pids = g_slist_remove(pids, tmp->data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pidwait_init(void)
|
void pidwait_init(void)
|
||||||
{
|
{
|
||||||
|
child_pids = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||||
pids = NULL;
|
pids = NULL;
|
||||||
childcheck_tag = g_timeout_add(1000, (GSourceFunc) child_check, NULL);
|
|
||||||
|
|
||||||
signal_pidwait = signal_get_uniq_id("pidwait");
|
signal_pidwait = signal_get_uniq_id("pidwait");
|
||||||
}
|
}
|
||||||
|
|
||||||
void pidwait_deinit(void)
|
void pidwait_deinit(void)
|
||||||
{
|
{
|
||||||
|
g_hash_table_destroy(child_pids);
|
||||||
g_slist_free(pids);
|
g_slist_free(pids);
|
||||||
|
|
||||||
g_source_remove(childcheck_tag);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user