public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: pthread_cleanup_pop and egcs (g++) not calling destructors.
       [not found] <199906161647.JAA05894@rtl.cygnus.com>
@ 1999-06-16 10:02 ` Dima Volodin
  1999-06-17  6:36   ` george
  1999-06-30 15:43   ` Dima Volodin
  0 siblings, 2 replies; 4+ messages in thread
From: Dima Volodin @ 1999-06-16 10:02 UTC (permalink / raw)
  To: Andrew Macleod; +Cc: martin, egcs

On Wed, 16 Jun 1999 09:47:51 -0700, Andrew Macleod wrote:

>Passing exceptions through non-gcc compiled functions
>is a totally different issue, as we dont know where to go looking
>for registers which have been saved.

And that's the most interesting thing to have, that is I'd very much
like to have something like this: a thread goes sleeping in a system
call, gets canceled, unwinds. This all is only possible with the
tightest integration between egcs and the OS code, which is not the case
in environments like Solaris. :-(

>  The alternative to this is
>to use -fsjlj-exceptions, which produces much uglier code,  but can
>throw through anything. You can't mix and match sjljs-exceptions with
>dwarf2 exceptions.

Hmmm, never tried this one...

>Andrew

Dima

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: pthread_cleanup_pop and egcs (g++) not calling destructors.
  1999-06-16 10:02 ` pthread_cleanup_pop and egcs (g++) not calling destructors Dima Volodin
@ 1999-06-17  6:36   ` george
  1999-06-30 15:43     ` george
  1999-06-30 15:43   ` Dima Volodin
  1 sibling, 1 reply; 4+ messages in thread
From: george @ 1999-06-17  6:36 UTC (permalink / raw)
  To: dvv; +Cc: egcs, martin, Andrew Macleod

On 16-Jun-99 Dima Volodin wrote:
> On Wed, 16 Jun 1999 09:47:51 -0700, Andrew Macleod wrote:
> 
>>Passing exceptions through non-gcc compiled functions
>>is a totally different issue, as we dont know where to go looking
>>for registers which have been saved.
> 
> And that's the most interesting thing to have, that is I'd very much
> like to have something like this: a thread goes sleeping in a system
> call, gets canceled, unwinds. This all is only possible with the
> tightest integration between egcs and the OS code, which is not the case
> in environments like Solaris. :-(
> 
>>  The alternative to this is
>>to use -fsjlj-exceptions, which produces much uglier code,  but can
>>throw through anything. You can't mix and match sjljs-exceptions with
>>dwarf2 exceptions.
> 
> Hmmm, never tried this one...
> 
>>Andrew
> 
> Dima

I got this to work on Linux by doing the following:

 1)  Recompile the C library with -fexceptions
 2)  At the start of each thread push a cancellation function
     which throws a "ThreadCancelled" exception, and catch it
     in the thread function:

        class ThreadCancelled { int unused; };

        void    ExceptionFunction(void *arg)
        {
                throw ThreadCancelled;
        }

        void *ThreadFunction(void *arg)
        {
                void    *rv;
        
                pthread_cleanup_push(&ExceptionFunction, 0);

                try
                {
                        rv = CallRealThreadFunction(arg);
                }
                catch (ThreadCancelled c)
                {
                        pthread_exit(PTHREAD_CANCELLED);
                }

                pthread_cleanup_pop(0);
        
                return rv;
        }

This'll run all the cancellation functions, then run all the destructors on the
stack for that thread.  It only works if the C library has been recompiled with
-fexceptions so exceptions can be thrown through it.  I'd like to get such a
change into the mainstream distribution for glibc myself, but I'm not sure whom
to ask.

The above technique is VERY non-portable, as pthread_cleanup_push() and
pthread_cleanup_pop() are only really intended to be used by C code--the fact
that this works on Linux with a recompiled C library is sort-of by accident.  A
C++ binding for Pthreads isn't defined by the POSIX standard, unfortunately.  A
proper binding would probably call the destructors for you without having to do
such rigamarole.

If you're using Solaris, and you're linking to Sun's C library, you're probably
S.O.L.  If you're linking against glibc on Solaris, and you've got the source
to it on your computer, you might try recompiling it with -fexceptions, and
then doing this trick.  It might still not work, depending on how glibc
implements pthreads on Solaris.  This trick works on Linux because pthreads is
implemented within glibc.

I'm honestly surprised that Solaris doesn't handle the destructor issue when
cancelling threads--Sun pushes the use of threads under Solaris for performance
reasons, and I know they write code in C++ themselves.
---
George T. Talbot
<george@moberg.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: pthread_cleanup_pop and egcs (g++) not calling destructors.
  1999-06-17  6:36   ` george
@ 1999-06-30 15:43     ` george
  0 siblings, 0 replies; 4+ messages in thread
From: george @ 1999-06-30 15:43 UTC (permalink / raw)
  To: dvv; +Cc: egcs, martin, Andrew Macleod

On 16-Jun-99 Dima Volodin wrote:
> On Wed, 16 Jun 1999 09:47:51 -0700, Andrew Macleod wrote:
> 
>>Passing exceptions through non-gcc compiled functions
>>is a totally different issue, as we dont know where to go looking
>>for registers which have been saved.
> 
> And that's the most interesting thing to have, that is I'd very much
> like to have something like this: a thread goes sleeping in a system
> call, gets canceled, unwinds. This all is only possible with the
> tightest integration between egcs and the OS code, which is not the case
> in environments like Solaris. :-(
> 
>>  The alternative to this is
>>to use -fsjlj-exceptions, which produces much uglier code,  but can
>>throw through anything. You can't mix and match sjljs-exceptions with
>>dwarf2 exceptions.
> 
> Hmmm, never tried this one...
> 
>>Andrew
> 
> Dima

I got this to work on Linux by doing the following:

 1)  Recompile the C library with -fexceptions
 2)  At the start of each thread push a cancellation function
     which throws a "ThreadCancelled" exception, and catch it
     in the thread function:

        class ThreadCancelled { int unused; };

        void    ExceptionFunction(void *arg)
        {
                throw ThreadCancelled;
        }

        void *ThreadFunction(void *arg)
        {
                void    *rv;
        
                pthread_cleanup_push(&ExceptionFunction, 0);

                try
                {
                        rv = CallRealThreadFunction(arg);
                }
                catch (ThreadCancelled c)
                {
                        pthread_exit(PTHREAD_CANCELLED);
                }

                pthread_cleanup_pop(0);
        
                return rv;
        }

This'll run all the cancellation functions, then run all the destructors on the
stack for that thread.  It only works if the C library has been recompiled with
-fexceptions so exceptions can be thrown through it.  I'd like to get such a
change into the mainstream distribution for glibc myself, but I'm not sure whom
to ask.

The above technique is VERY non-portable, as pthread_cleanup_push() and
pthread_cleanup_pop() are only really intended to be used by C code--the fact
that this works on Linux with a recompiled C library is sort-of by accident.  A
C++ binding for Pthreads isn't defined by the POSIX standard, unfortunately.  A
proper binding would probably call the destructors for you without having to do
such rigamarole.

If you're using Solaris, and you're linking to Sun's C library, you're probably
S.O.L.  If you're linking against glibc on Solaris, and you've got the source
to it on your computer, you might try recompiling it with -fexceptions, and
then doing this trick.  It might still not work, depending on how glibc
implements pthreads on Solaris.  This trick works on Linux because pthreads is
implemented within glibc.

I'm honestly surprised that Solaris doesn't handle the destructor issue when
cancelling threads--Sun pushes the use of threads under Solaris for performance
reasons, and I know they write code in C++ themselves.
---
George T. Talbot
<george@moberg.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: pthread_cleanup_pop and egcs (g++) not calling destructors.
  1999-06-16 10:02 ` pthread_cleanup_pop and egcs (g++) not calling destructors Dima Volodin
  1999-06-17  6:36   ` george
@ 1999-06-30 15:43   ` Dima Volodin
  1 sibling, 0 replies; 4+ messages in thread
From: Dima Volodin @ 1999-06-30 15:43 UTC (permalink / raw)
  To: Andrew Macleod; +Cc: martin, egcs

On Wed, 16 Jun 1999 09:47:51 -0700, Andrew Macleod wrote:

>Passing exceptions through non-gcc compiled functions
>is a totally different issue, as we dont know where to go looking
>for registers which have been saved.

And that's the most interesting thing to have, that is I'd very much
like to have something like this: a thread goes sleeping in a system
call, gets canceled, unwinds. This all is only possible with the
tightest integration between egcs and the OS code, which is not the case
in environments like Solaris. :-(

>  The alternative to this is
>to use -fsjlj-exceptions, which produces much uglier code,  but can
>throw through anything. You can't mix and match sjljs-exceptions with
>dwarf2 exceptions.

Hmmm, never tried this one...

>Andrew

Dima

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1999-06-30 15:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <199906161647.JAA05894@rtl.cygnus.com>
1999-06-16 10:02 ` pthread_cleanup_pop and egcs (g++) not calling destructors Dima Volodin
1999-06-17  6:36   ` george
1999-06-30 15:43     ` george
1999-06-30 15:43   ` Dima Volodin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).