From slamb at slamb.org Thu Dec 18 16:32:46 2003 From: slamb at slamb.org (Scott Lamb) Date: Thu, 18 Dec 2003 09:32:46 -0600 Subject: [Help-gnutls] Thread cancellation Message-ID: <3FE1C89E.8030407@slamb.org> Hello, I stumbled onto gnutls through the dmoz/google directory link. I'm quite impressed so far, particularly with the quality of documentation. I've got a couple questions I didn't see answered, though: - Is gnutls cancellation-safe? - Similarly, is it exception-safe? In case you're not familiar with thread cancellation, here's a quick overview: Thread cancellation is conceptually similar to sending a SIGTERM to a process (a termination request) but much safer. Asynchronous cancellation happens at any time (difficult to do safely). The more normal method is deferred cancellation, where you define cancellation points within your code. The system library defines some, too. Most blocking operations are cancellation points. You can enable/disable cancellation in specific regions of code, or switch between deferred and async. There's also a stack of cleanup handlers, roughly corresponding to the normal program execution stack. You can push and pop it as you go along with pthread_cleanup_(push|pop). It's used for stuff like this, which safely locks and unlocks a mutex: pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); pthread_mutex_lock(&mut); /* do some work */ pthread_cleanup_pop(1); So I think cancellation safety essentially boils down to not leaking resources or being in an inconsistent state whenever in a cancellation point. There's a list of the system ones at ). But no holding locks or holding dynamically-allocated stuff on the stack unless you've explicitly defined a cleanup to deal with it. Plus to be friendly to cancellation, any long-running arithmetic operations should either do pthread_testcancel() periodically or (carefully!) enable asynchronous cancellation. Exception safety is pretty similar. I'd be thrilled if I could define a new transport layer and throw C++ exceptions all the way through the gnutls code to my code on the other side. If the transport operations are considered cancellation points (without using pthread_cleanup_xxx), it's exception-safe. (Provided that I compile with -fexceptions, but that's easy.) It'd save me the trouble of converting my exceptions to C-friendly errors and back again. (In fact, these are so similar that the pthread standards people suggested that cancellations be implemented with exceptions in C++, so try/catch blocks work with cancellation as an alternative to pthread_cleanup_xxx(). In a couple of newer systems (Tru64 and Linux with an extremely new glibc as in Fedora), they are. Most good C++ code is already exception-safe, so thread cancellation is extremely practical under C++.) Thanks, Scott Lamb From nmav at gnutls.org Fri Dec 19 09:10:05 2003 From: nmav at gnutls.org (Nikos Mavroyanopoulos) Date: Fri, 19 Dec 2003 10:10:05 +0200 Subject: [Help-gnutls] Thread cancellation In-Reply-To: <3FE1C89E.8030407@slamb.org> References: <3FE1C89E.8030407@slamb.org> Message-ID: <20031219081005.GA28366@gnutls.org> On Thu, Dec 18, 2003 at 09:32:46AM -0600, Scott Lamb wrote: > Hello, > > I stumbled onto gnutls through the dmoz/google directory link. I'm quite > impressed so far, particularly with the quality of documentation. > I've got a couple questions I didn't see answered, though: > - Is gnutls cancellation-safe? No gnutls is not cancellation safe. I guess that there could be some memory leaks when cancelation is used. That could be changed though since the system calls used in gnutls are few, but I don't know if it is a good idea to make gnutls use libpthread. According to Werner Libgcrypt is also not cancelation safe, but this may change within the 1.2.x releases of libgcrypt (libgcrypt already depends on pthread due to some locking required). > - Similarly, is it exception-safe? No. gnutls is written in plain C, with no exceptions in mind. > Exception safety is pretty similar. I'd be thrilled if I could define a > new transport layer and throw C++ exceptions all the way through the > gnutls code to my code on the other side. If the transport operations > are considered cancellation points (without using pthread_cleanup_xxx), > it's exception-safe. (Provided that I compile with -fexceptions, but > that's easy.) It'd save me the trouble of converting my exceptions to > C-friendly errors and back again. Currently that would be the case. The callbacks should report errors using the C interface defined. > Thanks, > Scott Lamb -- Nikos Mavroyanopoulos From slamb at slamb.org Fri Dec 19 17:01:07 2003 From: slamb at slamb.org (Scott Lamb) Date: Fri, 19 Dec 2003 10:01:07 -0600 Subject: [Help-gnutls] Thread cancellation In-Reply-To: <20031219081005.GA28366@gnutls.org> References: <3FE1C89E.8030407@slamb.org> <20031219081005.GA28366@gnutls.org> Message-ID: <3FE320C3.7010204@slamb.org> Nikos Mavroyanopoulos wrote: >>- Is gnutls cancellation-safe? > > No gnutls is not cancellation safe. I guess that there could be > some memory leaks when cancelation is used. That could be changed > though since the system calls used in gnutls are few, but I don't > know if it is a good idea to make gnutls use libpthread. > > According to Werner Libgcrypt is also not cancelation safe, but > this may change within the 1.2.x releases of libgcrypt (libgcrypt > already depends on pthread due to some locking required). libgcrypt depending on pthread is an argument for making gnutls use it, IMHO. If you're worried about extending its dependencies, gnutls -> libpthread is no worse than gnutls -> libgcrypt -> libpthread. But if you just don't want to complicate things, no worries. I think I can accomplish what I want anyway (below). >>- Similarly, is it exception-safe? > > No. gnutls is written in plain C, with no exceptions in mind. I'd really like to be able to use cancellation, but I think I can accomplish it anyway. I can keep around another buffer layer between the underlying stream and TLS. Then I can alternate IO that goes on the underlying stream <-> buffer (with cancellation and exceptions enabled) and IO that goes on the buffer <-> gnutls (with cancellation disabled and no throwing of exceptions). As a bonus, that means I don't need to convert exceptions to C errors and back. Which is good, because I think it's not possible to convert an arbitrary exception to C errors and back. (A consequence of C++ details I won't bore you with.) I'd have to have some extra code for every exception type that could pass through that layer, which kind of sucks. Not quite as straightforward or efficient to mess with another buffer layer, but hopefully not too bad. (I guess when doing encryption, I probably shouldn't worry about the performance impact of some extra allocations and byte transfers, anyway; it's likely not even the same order of magnitude.) Thanks, Scott Lamb From nmav at gnutls.org Sun Dec 21 10:52:39 2003 From: nmav at gnutls.org (Nikos Mavroyanopoulos) Date: Sun, 21 Dec 2003 11:52:39 +0200 Subject: [Help-gnutls] Thread cancellation In-Reply-To: <3FE320C3.7010204@slamb.org> References: <3FE1C89E.8030407@slamb.org> <20031219081005.GA28366@gnutls.org> <3FE320C3.7010204@slamb.org> Message-ID: <20031221095239.GB3654@gnutls.org> On Fri, Dec 19, 2003 at 10:01:07AM -0600, Scott Lamb wrote: > >According to Werner Libgcrypt is also not cancelation safe, but > >this may change within the 1.2.x releases of libgcrypt (libgcrypt > >already depends on pthread due to some locking required). > libgcrypt depending on pthread is an argument for making gnutls use it, > IMHO. If you're worried about extending its dependencies, gnutls -> > libpthread is no worse than gnutls -> libgcrypt -> libpthread. > But if you just don't want to complicate things, no worries. I think I > can accomplish what I want anyway (below). It's nice to hear that this could be avoided. At least for now I'll try to postpone adding this since I'm busy working on some other features. > Thanks, > Scott Lamb -- Nikos Mavroyanopoulos