diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 62d1aaa4..defb9edc 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,19 @@ +2001-12-18 Marcus Brinkmann + + * rungpg.c (struct reap_s, reap_list, reap_list_lock): Moved to ... + * engine.c (struct reap_s, reap_list, reap_list_lock): ... here. + Include `time.h', `sys/types.h', `assert.h', and `sema.h'. + + * rungpg.c (_gpgme_engine_add_child_to_reap_list): New function. + (do_reaping, _gpgme_gpg_housecleaning): Moved to ... + * engine.c (do_reaping, _gpgme_engine_housecleaning): ... here. + * rungpg.c (_gpgme_gpg_release): Replace code that is now in its + own function by call to _gpgme_engine_add_child_to_reap_list(). + + * wait.c: Include `engine.h'. + (run_idle): Call _gpgme_engine_housecleaning(), not + _gpgme_gpg_housecleaning(). + 2001-12-18 Marcus Brinkmann * key.c (_gpgme_key_append_name): Append, not prepend, the uid. diff --git a/gpgme/engine.c b/gpgme/engine.c index 025832bb..3c250c9e 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -22,9 +22,13 @@ #ifdef HAVE_CONFIG_H #include #endif +#include +#include +#include #include "gpgme.h" #include "util.h" +#include "sema.h" #include "engine.h" #include "rungpg.h" @@ -44,6 +48,17 @@ struct engine_object_s } engine; }; +struct reap_s +{ + struct reap_s *next; + int pid; + time_t entered; + int term_send; +}; + +static struct reap_s *reap_list; +DEFINE_STATIC_LOCK (reap_list_lock); + /* Get the path of the engine for PROTOCOL. */ const char * _gpgme_engine_get_path (GpgmeProtocol proto) @@ -433,7 +448,8 @@ _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text) return 0; } -GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque) +GpgmeError +_gpgme_engine_start (EngineObject engine, void *opaque) { if (!engine) return mk_error (Invalid_Value); @@ -449,3 +465,84 @@ GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque) } return 0; } + +void +_gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid) +{ + /* Reuse the memory, so that we don't need to allocate another + memory block and to handle errors. */ + struct reap_s *child = buf; + + assert (buflen >= sizeof *child); + memset (child, 0, sizeof *child); + child->pid = pid; + child->entered = time (NULL); + LOCK(reap_list_lock); + child->next = reap_list; + reap_list = child; + UNLOCK(reap_list_lock); +} + +static void +do_reaping (void) +{ + struct reap_s *r, *rlast; + static time_t last_check; + time_t cur_time = time (NULL); + + /* A race does not matter here. */ + if (!last_check) + last_check = time (NULL); + + if (last_check >= cur_time) + return; /* We check only every second. */ + + /* Fixme: it would be nice if to have a TRYLOCK here. */ + LOCK (reap_list_lock); + for (r = reap_list, rlast = NULL; r; rlast = r, r = r ? r->next : NULL) + { + int dummy1, dummy2; + + if (_gpgme_io_waitpid (r->pid, 0, &dummy1, &dummy2)) + { + /* The process has terminated - remove it from the queue. */ + void *p = r; + if (!rlast) + { + reap_list = r->next; + r = reap_list; + } + else + { + rlast->next = r->next; + r = rlast; + } + xfree (p); + } + else if (!r->term_send) + { + if (r->entered + 1 >= cur_time) + { + _gpgme_io_kill (r->pid, 0); + r->term_send = 1; + r->entered = cur_time; + } + } + else + { + /* Give it 5 second before we are going to send the killer. */ + if (r->entered + 5 >= cur_time) + { + _gpgme_io_kill (r->pid, 1); + r->entered = cur_time; /* Just in case we have to repeat it. */ + } + } + } + UNLOCK (reap_list_lock); +} + +void +_gpgme_engine_housecleaning (void) +{ + do_reaping (); +} diff --git a/gpgme/engine.h b/gpgme/engine.h index a2f2f6c2..23be9dc9 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -63,4 +63,7 @@ GpgmeError _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData text); GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque); +void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid); +void _gpgme_engine_housecleaning (void); + #endif /* ENGINE_H */ diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 6151f7de..dc3e2388 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -118,17 +118,6 @@ struct gpg_object_s { } cmd; }; -struct reap_s { - struct reap_s *next; - int pid; - time_t entered; - int term_send; -}; - -static struct reap_s *reap_list; -DEFINE_STATIC_LOCK (reap_list_lock); - - static void free_argv ( char **argv ); static void free_fd_data_map ( struct fd_data_map_s *fd_data_map ); @@ -290,83 +279,11 @@ _gpgme_gpg_release (GpgObject gpg) _gpgme_io_close (gpg->colon.fd[1]); free_fd_data_map (gpg->fd_data_map); if (gpg->running) - { - int pid = gpg->pid; - struct reap_s *r; - - /* Reuse the memory, so that we don't need to allocate another - memory block and to handle errors. */ - assert (sizeof *r < sizeof *gpg); - r = (void*)gpg; - memset (r, 0, sizeof *r); - r->pid = pid; - r->entered = time (NULL); - LOCK(reap_list_lock); - r->next = reap_list; - reap_list = r; - UNLOCK(reap_list_lock); - } + _gpgme_engine_add_child_to_reap_list (gpg, sizeof *gpg, gpg->pid); else xfree (gpg); } - -static void -do_reaping (void) -{ - struct reap_s *r, *rlast; - static time_t last_check; - time_t cur_time = time (NULL); - - /* a race does not matter here */ - if (!last_check) - last_check = time(NULL); - - if (last_check >= cur_time) - return; /* we check only every second */ - - /* fixme: it would be nice if to have a TRYLOCK here */ - LOCK (reap_list_lock); - for (r=reap_list,rlast=NULL; r ; rlast=r, r=r?r->next:NULL) { - int dummy1, dummy2; - - if ( _gpgme_io_waitpid (r->pid, 0, &dummy1, &dummy2) ) { - /* process has terminated - remove it from the queue */ - void *p = r; - if (!rlast) { - reap_list = r->next; - r = reap_list; - } - else { - rlast->next = r->next; - r = rlast; - } - xfree (p); - } - else if ( !r->term_send ) { - if( r->entered+1 >= cur_time ) { - _gpgme_io_kill ( r->pid, 0); - r->term_send = 1; - r->entered = cur_time; - } - } - else { - /* give it 5 second before we are going to send the killer */ - if ( r->entered+5 >= cur_time ) { - _gpgme_io_kill (r->pid, 1); - r->entered = cur_time; /* just in case we have to repat it */ - } - } - } - UNLOCK (reap_list_lock); -} - -void -_gpgme_gpg_housecleaning () -{ - do_reaping (); -} - void _gpgme_gpg_enable_pipemode ( GpgObject gpg ) { diff --git a/gpgme/wait.c b/gpgme/wait.c index a474126e..a830c2d1 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -34,6 +34,7 @@ #include "wait.h" #include "sema.h" #include "io.h" +#include "engine.h" struct wait_item_s; struct proc_s; @@ -382,8 +383,7 @@ gpgme_register_idle ( void (*fnc)(void) ) static void run_idle () { - _gpgme_gpg_housecleaning (); - if (idle_function) - idle_function (); + _gpgme_engine_housecleaning (); + if (idle_function) + idle_function (); } -