guys, hi,
am on the mailing list (subscribed) but am not receiving posts: please cc me if this would be an issue.
for win32, i am using pthreads-win32: will reactos be able to support the trick that luke howard is referring to?
l.
----- Forwarded message from Luke Howard lukeh@padl.com -----
Envelope-to: lkcl@localhost Delivery-date: Mon, 24 Apr 2006 12:51:50 +0100 X-Original-To: lkcl@lkcl.net Resent-Date: 24 Apr 2006 10:22:43 -0000 From: Luke Howard lukeh@padl.com Organization: PADL Software Pty Ltd To: freedce-devel@lists.sourceforge.net Subject: NPTL and FreeDCE Cc: opendce@opengroup.org Reply-To: lukeh@padl.com Versions: dmail (bsd44) 2.6d/makemail 2.10 X-Spam-Status: NO, hits=-5.60 required=5.00 X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on au.padl.com X-Spam-Flag: NO X-Spam-Level: Resent-Message-ID: UQB5HC.A.7PG.ubKTEB@mailman Resent-To: opendce@opengroup.org Resent-From: opendce@opengroup.org X-Mailing-List: opendce:archive/latest/626 Resent-Sender: opendce-request@opengroup.org X-hands-com-MailScanner: Found to be clean X-MailScanner-From: opendce-request@opengroup.org Resent-Date: Mon, 24 Apr 2006 12:51:50 +0100
It may be possible to integrate DCE exception handling and NPTL so that longjmp() is never explicitly called from a cancellation cleanup handler. In fact, cleanup handlers need not be used at all.
This approach requires the NPTL r ather than the LinuxThreads, API and is orthogonal to the previous issue about removing thread cancellation (that was a runtime issue present with NPTL regardless of which header one compiles against).
Instead of calling _pthread_cleanup_push_defer(), we can store a __pthread_unwind_buf_t in the exception context and call __sigsetjmp() and __pthread_register_cancel_defer(). If __sigsetjmp() returns from a longjmp(), then we call dce_pthread_test_exit_np() to test whether the thread was cancelled, and set the current exception to pthread_cancel_e if necessary. No cleanup handler is necessary.
The trick is that the code that raises an exception needs to call the internal API __pthread_unwind(), rather than longjmp(). Of course this ends up calling longjmp() anyway but hopefully does the right thing with respect to any other cleanup handlers that are registered.
Another idea is to use the _Unwind_XXX API, but this strikes me as a little ambitious for now and I don't have any desire to interleave C++ and DCE exceptions.
/* * For the NPTL API we share a setjmp/longjmp buffer between the * pthreads cancellation and DCE exception handling APIs. * * Note that we never actually call the cancellation function, we * just change the current exception context directly; this is the * same as calling dce_ptdexc_raise(&pthread_cancel_e) except that * __pthread_unwind() is not called. */
#define dce_exc_cleanup_push(cu, routine, arg) do \ { \ __exc_occured = __sigsetjmp((struct __jmp_buf_tag *)(cu)->__cancel_buf.__cancel_jmp_buf, 0); \ if (__exc_occured) \ { \ void *__status; \ \ if (dce_pthread_test_exit_np(&__status) == PTHREAD_STATUS_EXIT_NP \ && __status == PTHREAD_CANCELED) \ __exc_ctxt.exc = &pthread_cancel_e; \ } \ else \ { \ __pthread_register_cancel_defer(&(cu)->__cancel_buf); \ } \ } while (0)
#define dce_exc_cleanup_pop(cu, execute) do \ { \ __pthread_unregister_cancel_restore(&(cu)->__cancel_buf); \ } while (0)
/* make this a NOOP because we called it above */ #define dce_exc_setjmp(jmpbuf, val)
/* we call __pthread_unwind() directly from dce_ptdexc_raise() */ #undef dce_exc_longjmp
-- Luke
--
----- End forwarded message -----