aborting (or finishing) pending operations in GPGME
Stephane Corthesy
stephane@sente.ch
Tue Jan 15 17:08:01 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