aborting (or finishing) pending operations in GPGME
Marcus Brinkmann
Marcus.Brinkmann@ruhr-uni-bochum.de
Tue Jan 15 16:27: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).
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).
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.
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.
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.
Comments on these suggestions, but also on alternatives etc, are welcome.
Thanks,
Marcus
--
`Rhubarb is no Egyptian god.' Debian http://www.debian.org brinkmd@debian.org
Marcus Brinkmann GNU http://www.gnu.org marcus@gnu.org
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de