aborting (or finishing) pending operations in GPGME

Stephane Corthesy stephane at sente.ch
Tue Jan 15 17:08:01 CET 2002


> On Mon, Jan 14, 2002 at 11:42:13AM +0100, Stephane Corthesy wrote: 
> > I find the op_start calls useful, combined with gpgme_wait(): user   
> > can start operations in a secondary thread, blocks the secondary   
> > thread with gpgme_wait() until end of operation, and notify back in   
> > the main (caller) thread; or he can cancel the operation. gpgme  
only
> > needs to be thread-safe, and provide a way for user to get  
status on
> > the operations. Of course, we could do the same with the sync
> > calls...
>
> Ok, with gpgme_cancel you can get back the control while in a  
gpgme_wait
> loop, and I can see how this would be useful.
>
> You raised another point:  thread-safeness.  gpgme is not thread  
safe at
> all.  There are many points in the code were locking is not  
implemented at
> all, and where it is implemented, it only works in a Windows  
environment.
> The stubs in posix-sema.c are empty.  This certainly needs to be  
fixed at
> some time, but it will take some effort to go through gpgme and to add 
> proper locking.  That doesn't mean that you can't use it in a threaded 
> environment, you just have to be very careful.  What you describe  
above is
> probably safe, but I didn't check (cancel just sets an int from  
zero to some
> non-zero value).

I didn't know that; this is a good reason for me to stop using the  
op_start functions until gpgme is thread-safe; as I work on a  
library, I can't be sure that people would always use it in a  
thread-safe way (except if I add mutexes myself). This  
non-thread-safeness should be emphasized somewhere in the docs (which  
docs ;-? even if we know that gpgme is in alpha stage.

> This leaves the problem of getting at the return value of the  
operation (how
> do you check the result in your example above?) and resetting the  
pending
> flag in the context (in your code, you probably trash the context  
after each
> operation).

It depends on the user. He could decide to reuse the same context,  
or trash it. But most calls should raise if the context is in use.

> My initial idea was to pull those interfaces so we can prevent a soname 
> change when we add a proper interface.  But if you find them  
useful (or they
> are probably already used by some code), we better fix the few  
issues they
> have and keep them.  The things I would like to fix is getting at  
the result
> and resetting the pending flag.

I don't use yet op_start calls; I just _tried_ to wrap them in ObjC  
methods, with threads, and found it didn't work correctly (I was  
missing things like operation result...).
Please feel free to remove the op_start calls from the interface.

> Maybe gpgme_wait can reset the pending flag when the background process 
> exits.  This is the same condition as when it would return if  
invoked with
> the hang option.  I think that is feasible, because there can't be  
any data
> left to be read or parsed.  [When we use one server process for many 
> operations, we will dequeue/queue the server process or something  
like that,
> so when I say "when the background process exits", I am a bit  
sloppy.  For
> now, process lifetime is what we rely on].  In addition, a way to
> explicitely terminate a pending operation is certainly desirable,  
but we can
> punt it off if gpgme_wait only does the right thing.

gpgme_cancel() should do it.

> What about the result?  It seems that the only way to go about it is a 
> function that returns the result of the last (finished) operation.  
 This can
> be either a full set of functions like "gpgme_op_decrypt_result()"  
etc, or a
> generic function "gpgme_op_result()", which requires gpgme to keep  
track of
> the last operation.  As it should also keep track of it for  
robustness (the
> pending flag is currently indiscriminate, so a keylist_next on a
> decrypt_start'ed context will hang it), this doesn't sound too bad. 

Couldn't gpgme_get_op_info() do the trick?


Talking about gpgme performances: did anyone make some profiling on  
gpgme calls and can tell me why it takes so long to enumerate the  
whole pubring? Listing keys with gpg is very fast, whereas with  
gpgme_op_keylist_XXX() it's soooooo slow.

Thanks for your reply,

Stephane








More information about the Gnupg-devel mailing list