From 6f7d1bc7704fb043439ecaf4fe14261eb56c10ab Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 22 Jan 2002 15:11:53 +0000 Subject: [PATCH] 2002-01-22 Marcus Brinkmann * wait.c (_gpgme_wait_on_condition): If the process finished, reset the pending flag. Also if the operation was cancelled. (struct proc_s): Rename READY to DONE. (wait_item_s): Likewise. (set_process_ready): Rename to ... (set_process_done): ... this. (_gpgme_remove_proc_from_wait_queue): Call set_process_done instead set_process_ready. (_gpgme_wait_on_condition): Likewise. (do_select): Rename READY to DONE. * verify.c (gpgme_op_verify): Do not set pending to zero here. * sign.c (gpgme_op_sign): Likewise. * import.c (gpgme_op_import): Likewise. * genkey.c (gpgme_op_genkey): Likewise. * export.c (gpgme_op_export): Likewise. * encrypt.c (gpgme_op_encrypt): Likewise. * delete.c (gpgme_op_delete): Likewise. * decrypt-verify.c (gpgme_op_decrypt_verify): Likewise. * decrypt.c (gpgme_op_decrypt): Likewise. --- gpgme/ChangeLog | 24 +++ gpgme/decrypt-verify.c | 1 - gpgme/decrypt.c | 1 - gpgme/delete.c | 18 +- gpgme/encrypt.c | 1 - gpgme/export.c | 5 +- gpgme/genkey.c | 14 +- gpgme/import.c | 12 +- gpgme/keylist.c | 4 +- gpgme/sign.c | 1 - gpgme/verify.c | 1 - gpgme/wait.c | 419 ++++++++++++++++++++++------------------- 12 files changed, 269 insertions(+), 232 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 1d4d7b0..348b54c 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,27 @@ +2002-01-22 Marcus Brinkmann + + * wait.c (_gpgme_wait_on_condition): If the process finished, + reset the pending flag. Also if the operation was cancelled. + + (struct proc_s): Rename READY to DONE. + (wait_item_s): Likewise. + (set_process_ready): Rename to ... + (set_process_done): ... this. + (_gpgme_remove_proc_from_wait_queue): Call set_process_done + instead set_process_ready. + (_gpgme_wait_on_condition): Likewise. + (do_select): Rename READY to DONE. + + * verify.c (gpgme_op_verify): Do not set pending to zero here. + * sign.c (gpgme_op_sign): Likewise. + * import.c (gpgme_op_import): Likewise. + * genkey.c (gpgme_op_genkey): Likewise. + * export.c (gpgme_op_export): Likewise. + * encrypt.c (gpgme_op_encrypt): Likewise. + * delete.c (gpgme_op_delete): Likewise. + * decrypt-verify.c (gpgme_op_decrypt_verify): Likewise. + * decrypt.c (gpgme_op_decrypt): Likewise. + 2002-01-22 Marcus Brinkmann * export.c: Cleanup. diff --git a/gpgme/decrypt-verify.c b/gpgme/decrypt-verify.c index e7ec128..087fffa 100644 --- a/gpgme/decrypt-verify.c +++ b/gpgme/decrypt-verify.c @@ -74,7 +74,6 @@ gpgme_op_decrypt_verify (GpgmeCtx ctx, if (! err) *r_stat = _gpgme_intersect_stati (ctx->result.verify); } - ctx->pending = 0; } return err; } diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c index cc0c3be..7346eab 100644 --- a/gpgme/decrypt.c +++ b/gpgme/decrypt.c @@ -195,7 +195,6 @@ gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out) { gpgme_wait (ctx, 1); err = _gpgme_decrypt_result (ctx); - ctx->pending = 0; } return err; } diff --git a/gpgme/delete.c b/gpgme/delete.c index 1e26778..a5f122f 100644 --- a/gpgme/delete.c +++ b/gpgme/delete.c @@ -102,17 +102,13 @@ gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret) * Return value: 0 on success or an error code. **/ GpgmeError -gpgme_op_delete ( GpgmeCtx c, const GpgmeKey key, int allow_secret ) +gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret) { - int rc = gpgme_op_delete_start ( c, key, allow_secret ); - if ( !rc ) { - gpgme_wait (c, 1); - c->pending = 0; - /* FIXME: check for success */ + GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret); + if (!err) + { + gpgme_wait (ctx, 1); + /* FIXME: check for success */ } - return rc; + return err; } - - - - diff --git a/gpgme/encrypt.c b/gpgme/encrypt.c index d246333..3c457f0 100644 --- a/gpgme/encrypt.c +++ b/gpgme/encrypt.c @@ -227,7 +227,6 @@ gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp, if (c->result.encrypt->no_recipients) err = mk_error (No_Recipients); } - c->pending = 0; /* Old gpg versions don't return status info for invalid * recipients, so we simply check whether we got any output at * all and if not assume that we don't have valid recipients diff --git a/gpgme/export.c b/gpgme/export.c index 3896404..e113ad3 100644 --- a/gpgme/export.c +++ b/gpgme/export.c @@ -94,9 +94,6 @@ gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata) { GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata); if (!err) - { - gpgme_wait (ctx, 1); - ctx->pending = 0; - } + gpgme_wait (ctx, 1); return err; } diff --git a/gpgme/genkey.c b/gpgme/genkey.c index 295cd7a..be52056 100644 --- a/gpgme/genkey.c +++ b/gpgme/genkey.c @@ -204,15 +204,13 @@ gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms, * Return value: 0 for success or an error code **/ GpgmeError -gpgme_op_genkey( GpgmeCtx c, const char *parms, - GpgmeData pubkey, GpgmeData seckey ) +gpgme_op_genkey (GpgmeCtx ctx, const char *parms, + GpgmeData pubkey, GpgmeData seckey) { - int rc = gpgme_op_genkey_start ( c, parms, pubkey, seckey ); - if ( !rc ) { - gpgme_wait (c, 1); - c->pending = 0; - } - return rc; + GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey); + if (!err) + gpgme_wait (ctx, 1); + return err; } diff --git a/gpgme/import.c b/gpgme/import.c index de0b894..2f830c7 100644 --- a/gpgme/import.c +++ b/gpgme/import.c @@ -89,14 +89,12 @@ gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata) * Return value: o on success or an error code. **/ GpgmeError -gpgme_op_import ( GpgmeCtx c, GpgmeData keydata ) +gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata) { - int rc = gpgme_op_import_start ( c, keydata ); - if ( !rc ) { - gpgme_wait (c, 1); - c->pending = 0; - } - return rc; + GpgmeError err = gpgme_op_import_start (ctx, keydata); + if (!err) + gpgme_wait (ctx, 1); + return err; } diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 65bded3..b9907a4 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -466,7 +466,7 @@ gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key) *r_key = NULL; if (!ctx) return mk_error (Invalid_Value); - if (!ctx->pending ) + if (!ctx->pending) return mk_error (No_Request); if (ctx->out_of_core) return mk_error (Out_Of_Core); @@ -506,7 +506,7 @@ gpgme_op_keylist_end (GpgmeCtx ctx) { if (!ctx) return mk_error (Invalid_Value); - if (!ctx->pending ) + if (!ctx->pending) return mk_error (No_Request); if (ctx->out_of_core) return mk_error (Out_Of_Core); diff --git a/gpgme/sign.c b/gpgme/sign.c index e31c5ad..7c0a64c 100644 --- a/gpgme/sign.c +++ b/gpgme/sign.c @@ -277,7 +277,6 @@ gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode) err = mk_error (No_Data); /* Hmmm: choose a better error? */ } } - ctx->pending = 0; } return err; } diff --git a/gpgme/verify.c b/gpgme/verify.c index c0e8776..f1f6cd7 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -355,7 +355,6 @@ gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text, } *r_stat = _gpgme_intersect_stati (c->result.verify); } - c->pending = 0; } return rc; } diff --git a/gpgme/wait.c b/gpgme/wait.c index a830c2d..b86ca5f 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -54,7 +54,7 @@ struct proc_s { int pid; GpgmeCtx ctx; struct wait_item_s *handler_list; - int ready; + int done; }; struct wait_item_s { @@ -63,7 +63,7 @@ struct wait_item_s { void *handler_value; int inbound; /* this is an inbound data handler fd */ struct proc_s *proc; /* backlink */ - int ready; + int done; int frozen; /* copy of the frozen flag from the fd_table */ }; @@ -75,61 +75,67 @@ static void run_idle (void); /* only to be called with a locked proc_queue */ static int -count_running_fds ( struct proc_s *proc ) +count_running_fds (struct proc_s *proc) { - struct wait_item_s *q; - int count = 0; + struct wait_item_s *q; + int count = 0; - for (q=proc->handler_list; q; q=q->next) { - if ( !q->frozen && !q->ready ) - count++; + for (q = proc->handler_list; q; q=q->next) + { + if (!q->frozen && !q->done) + count++; } - return count; + return count; } /* only to be called with a locked proc_queue */ static void -set_process_ready ( struct proc_s *proc ) +set_process_done (struct proc_s *proc) { - struct wait_item_s *q, *q2; - int i; - - assert (proc); - DEBUG2 ("set_process_ready(%p) pid=%d", proc, proc->pid ); - LOCK (fd_table_lock); - for (q = proc->handler_list; q; q=q2) { - q2 = q->next; - for (i=0; i < fd_table_size; i++ ) { - if (fd_table[i].fd != -1 && q == fd_table[i].opaque ) { - fd_table[i].opaque = NULL; - fd_table[i].fd = -1; + struct wait_item_s *q, *q2; + int i; + + assert (proc); + DEBUG2 ("set_process_done(%p) pid=%d", proc, proc->pid); + LOCK (fd_table_lock); + for (q = proc->handler_list; q; q=q2) + { + q2 = q->next; + for (i = 0; i < fd_table_size; i++) + { + if (fd_table[i].fd != -1 && q == fd_table[i].opaque) + { + fd_table[i].opaque = NULL; + fd_table[i].fd = -1; } } - xfree (q); + xfree (q); } - UNLOCK (fd_table_lock); - proc->handler_list = NULL; - proc->ready = 1; + UNLOCK (fd_table_lock); + proc->handler_list = NULL; + proc->done = 1; } void -_gpgme_remove_proc_from_wait_queue ( int pid ) +_gpgme_remove_proc_from_wait_queue (int pid) { struct proc_s *proc, *last; - DEBUG1 ("removing process %d", pid ); + DEBUG1 ("removing process %d", pid); LOCK (proc_queue_lock); - for (last=NULL, proc=proc_queue; proc; last = proc, proc = proc->next ) { - if (proc->pid == pid ) { - set_process_ready (proc); + for (last = NULL, proc = proc_queue; proc; last = proc, proc = proc->next) + { + if (proc->pid == pid) + { + set_process_done (proc); if (!last) - proc_queue = proc->next; + proc_queue = proc->next; else - last->next = proc->next; + last->next = proc->next; xfree (proc); break; - } - } + } + } UNLOCK (proc_queue_lock); } @@ -148,49 +154,58 @@ _gpgme_remove_proc_from_wait_queue ( int pid ) * and no (or the given) request has finished. **/ GpgmeCtx -gpgme_wait ( GpgmeCtx c, int hang ) +gpgme_wait (GpgmeCtx ctx, int hang) { - return _gpgme_wait_on_condition ( c, hang, NULL ); + return _gpgme_wait_on_condition (ctx, hang, NULL); } GpgmeCtx -_gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond ) +_gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond) { - DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", c, hang, cond ); - do { - int any = 0; - struct proc_s *proc; - - do_select(); - - if ( cond && *cond ) - hang = 0; - else { - LOCK (proc_queue_lock); - for (proc=proc_queue; proc; proc = proc->next ) { - if ( !proc->ready && !count_running_fds (proc) ) { - set_process_ready (proc); - } - if (c && proc->ready && proc->ctx == c) - hang = 0; - if ( !proc->ready ) - any = 1; + DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", ctx, hang, cond); + do + { + int any = 0; + struct proc_s *proc; + + do_select (); + + if (cond && *cond) + hang = 0; + else + { + LOCK (proc_queue_lock); + for (proc = proc_queue; proc; proc = proc->next) + { + if (!proc->done && !count_running_fds (proc)) + set_process_done (proc); + if (ctx && proc->done && proc->ctx == ctx) + { + hang = 0; + ctx->pending = 0; + } + if (!proc->done) + any = 1; } - UNLOCK (proc_queue_lock); - if (!any) - hang = 0; + UNLOCK (proc_queue_lock); + if (!any) + hang = 0; } - /* fixme: we should check here for hanging processes */ + /* fixme: We should check here for hanging processes. */ - if (hang) - run_idle (); - } while (hang && !c->cancel ); - c->cancel = 0; /* fixme: fix all functions, to return a cancel error */ - return c; + if (hang) + run_idle (); + } + while (hang && !ctx->cancel); + if (ctx->cancel) + { + ctx->cancel = 0; /* fixme: Fix all functions to return a cancel error. */ + ctx->pending = 0; + } + return ctx; } - /* * We use this function to do the select stuff for all running * gpgs. A future version might provide a facility to delegate @@ -201,168 +216,182 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond ) */ static int -do_select ( void ) +do_select (void) { - int i, n; - int any=0; + int i, n; + int any = 0; - n = _gpgme_io_select ( fd_table, fd_table_size ); - if ( n <= 0 ) - return 0; /* error or timeout */ - - for (i=0; i < fd_table_size && n; i++ ) { - if ( fd_table[i].fd != -1 && fd_table[i].signaled - && !fd_table[i].frozen ) { - struct wait_item_s *q; - - assert (n); - n--; + n = _gpgme_io_select (fd_table, fd_table_size); + if (n <= 0) + return 0; /* error or timeout */ + + for (i = 0; i < fd_table_size && n; i++) + { + if (fd_table[i].fd != -1 && fd_table[i].signaled + && !fd_table[i].frozen) + { + struct wait_item_s *q; + + assert (n); + n--; - q = fd_table[i].opaque; - assert ( q ); - assert ( q->proc ); - assert ( !q->ready ); - any = 1; - if ( q->handler (q->handler_value, - q->proc->pid, fd_table[i].fd ) ) { - DEBUG2 ("setting fd %d (q=%p) ready", fd_table[i].fd, q ); - q->ready = 1; - /* free the table entry*/ - LOCK (fd_table_lock); - fd_table[i].for_read = 0; - fd_table[i].for_write = 0; - fd_table[i].fd = -1; - fd_table[i].opaque = NULL; - UNLOCK (fd_table_lock); + q = fd_table[i].opaque; + assert (q); + assert (q->proc); + assert (!q->done); + any = 1; + if (q->handler (q->handler_value, + q->proc->pid, fd_table[i].fd)) + { + DEBUG2 ("setting fd %d (q=%p) done", fd_table[i].fd, q); + q->done = 1; + /* Free the table entry. */ + LOCK (fd_table_lock); + fd_table[i].for_read = 0; + fd_table[i].for_write = 0; + fd_table[i].fd = -1; + fd_table[i].opaque = NULL; + UNLOCK (fd_table_lock); } } } - return any; + return any; } - /* * called by rungpg.c to register something for select() */ GpgmeError -_gpgme_register_pipe_handler ( void *opaque, +_gpgme_register_pipe_handler (void *opaque, int (*handler)(void*,int,int), void *handler_value, - int pid, int fd, int inbound ) + int pid, int fd, int inbound) { - GpgmeCtx ctx = opaque; - struct wait_item_s *q; - struct proc_s *proc; - int i; - - assert (opaque); - assert (handler); - - /* Allocate a structure to hold info about the handler */ - q = xtrycalloc ( 1, sizeof *q ); - if ( !q ) - return mk_error (Out_Of_Core); - q->inbound = inbound; - q->handler = handler; - q->handler_value = handler_value; - - /* Put this into the process queue */ - LOCK (proc_queue_lock); - for (proc=proc_queue; proc && proc->pid != pid; proc = proc->next) - ; - if (!proc) { /* a new process */ - proc = xtrycalloc ( 1, sizeof *proc ); - if (!proc) { - UNLOCK (proc_queue_lock); - return mk_error (Out_Of_Core); + GpgmeCtx ctx = opaque; + struct wait_item_s *q; + struct proc_s *proc; + int i; + + assert (opaque); + assert (handler); + + /* Allocate a structure to hold info about the handler. */ + q = xtrycalloc (1, sizeof *q); + if (!q) + return mk_error (Out_Of_Core); + q->inbound = inbound; + q->handler = handler; + q->handler_value = handler_value; + + /* Put this into the process queue. */ + LOCK (proc_queue_lock); + for (proc = proc_queue; proc && proc->pid != pid; proc = proc->next) + ; + if (!proc) + { + /* A new process. */ + proc = xtrycalloc (1, sizeof *proc); + if (!proc) + { + UNLOCK (proc_queue_lock); + return mk_error (Out_Of_Core); } - proc->pid = pid; - proc->ctx = ctx; - proc->next = proc_queue; - proc_queue = proc; + proc->pid = pid; + proc->ctx = ctx; + proc->next = proc_queue; + proc_queue = proc; } - assert (proc->ctx == ctx); - q->proc = proc; - q->next = proc->handler_list; - proc->handler_list = q; - UNLOCK (proc_queue_lock); + assert (proc->ctx == ctx); + q->proc = proc; + q->next = proc->handler_list; + proc->handler_list = q; + UNLOCK (proc_queue_lock); - LOCK (fd_table_lock); + LOCK (fd_table_lock); again: - for (i=0; i < fd_table_size; i++ ) { - if ( fd_table[i].fd == -1 ) { - fd_table[i].fd = fd; - fd_table[i].for_read = inbound; - fd_table[i].for_write = !inbound; - fd_table[i].signaled = 0; - fd_table[i].frozen = 0; - fd_table[i].opaque = q; - UNLOCK (fd_table_lock); - return 0; + for (i=0; i < fd_table_size; i++) + { + if (fd_table[i].fd == -1) + { + fd_table[i].fd = fd; + fd_table[i].for_read = inbound; + fd_table[i].for_write = !inbound; + fd_table[i].signaled = 0; + fd_table[i].frozen = 0; + fd_table[i].opaque = q; + UNLOCK (fd_table_lock); + return 0; } } - if ( fd_table_size < 50 ) { - /* FIXME: We have to wait until there are no other readers of the - * table, i.e that the io_select is not active in another thread */ - struct io_select_fd_s *tmp; - - tmp = xtryrealloc ( fd_table, (fd_table_size + 10) * sizeof *tmp ); - if ( tmp ) { - for (i=0; i < 10; i++ ) - tmp[fd_table_size+i].fd = -1; - fd_table_size += i; - fd_table = tmp; - goto again; - } - } - - UNLOCK (fd_table_lock); - xfree (q); - /* FIXME: remove the proc table entry */ - return mk_error (Too_Many_Procs); + if ( fd_table_size < 50 ) { + /* FIXME: We have to wait until there are no other readers of the + * table, i.e that the io_select is not active in another thread */ + struct io_select_fd_s *tmp; + + tmp = xtryrealloc (fd_table, (fd_table_size + 10) * sizeof *tmp); + if (tmp) + { + for (i = 0; i < 10; i++) + tmp[fd_table_size+i].fd = -1; + fd_table_size += i; + fd_table = tmp; + goto again; + } + } + + UNLOCK (fd_table_lock); + xfree (q); + /* FIXME: Remove the proc table entry. */ + return mk_error (Too_Many_Procs); } void -_gpgme_freeze_fd ( int fd ) +_gpgme_freeze_fd (int fd) { - int i; - - LOCK (fd_table_lock); - for (i=0; i < fd_table_size; i++ ) { - if ( fd_table[i].fd == fd ) { - struct wait_item_s *q; - - fd_table[i].frozen = 1; - if ( (q=fd_table[i].opaque) ) - q->frozen = 1; - DEBUG2 ("fd %d frozen (q=%p)", fd, q ); - break; + int i; + + LOCK (fd_table_lock); + for (i = 0; i < fd_table_size; i++) + { + if (fd_table[i].fd == fd) + { + struct wait_item_s *q; + + fd_table[i].frozen = 1; + q = fd_table[i].opaque; + if (q) + q->frozen = 1; + DEBUG2 ("fd %d frozen (q=%p)", fd, q); + break; } } - UNLOCK (fd_table_lock); + UNLOCK (fd_table_lock); } void -_gpgme_thaw_fd ( int fd ) +_gpgme_thaw_fd (int fd) { - int i; - - LOCK (fd_table_lock); - for (i=0; i < fd_table_size; i++ ) { - if ( fd_table[i].fd == fd ) { - struct wait_item_s *q; - - fd_table[i].frozen = 0; - if ( (q=fd_table[i].opaque) ) - q->frozen = 0; - DEBUG2 ("fd %d thawed (q=%p)", fd, q ); - break; + int i; + + LOCK (fd_table_lock); + for (i = 0; i < fd_table_size; i++) + { + if (fd_table[i].fd == fd) + { + struct wait_item_s *q; + + fd_table[i].frozen = 0; + q = fd_table[i].opaque; + if (q) + q->frozen = 0; + DEBUG2 ("fd %d thawed (q=%p)", fd, q); + break; } } - UNLOCK (fd_table_lock); + UNLOCK (fd_table_lock); } @@ -374,9 +403,9 @@ _gpgme_thaw_fd ( int fd ) * that is is idle. NULL may be used to remove this function. **/ void -gpgme_register_idle ( void (*fnc)(void) ) +gpgme_register_idle (void (*fnc)(void)) { - idle_function = fnc; + idle_function = fnc; } -- 2.26.2