[ros-dev] [lukeh@padl.com: NPTL and FreeDCE]

Luke Kenneth Casson Leighton lkcl at lkcl.net
Mon Apr 24 13:54:24 CEST 2006


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 at padl.com> -----

Envelope-to: lkcl at localhost
Delivery-date: Mon, 24 Apr 2006 12:51:50 +0100
X-Original-To: lkcl at lkcl.net
Resent-Date: 24 Apr 2006 10:22:43 -0000
From: Luke Howard <lukeh at padl.com>
Organization: PADL Software Pty Ltd
To: freedce-devel at lists.sourceforge.net
Subject: NPTL and FreeDCE
Cc: opendce at opengroup.org
Reply-To: lukeh at 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 at mailman>
Resent-To: opendce at opengroup.org
Resent-From: opendce at opengroup.org
X-Mailing-List: opendce:archive/latest/626
Resent-Sender: opendce-request at opengroup.org
X-hands-com-MailScanner: Found to be clean
X-MailScanner-From: opendce-request at 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 -----

-- 
--
lkcl.net - mad free software computer person, visionary and poet.
--


More information about the Ros-dev mailing list