This is the mail archive of the pthreads-win32@sources.redhat.com mailing list for the pthreas-win32 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pthreads VCE: problem with destructor




> Due to the nature of the beast just as the responsibility lies with the
> programmer to design the program to "cleanly" (including running
destructors,
> ad nauseum) exit when exit() is called, it should also be the
responsibility of
> the programmer to design a thread to cleanly exit with pthread_exit() or
> pthread_cancel() are called.  Just as exit() should not be called in a
C++
> program if dtors are desired to run neither should pthread_exit() from a
> thread.  IMHO.

The C++ standard says:

"The function exit() has additional behavior in this
 International Standard:

 - First, objects with static storage duration are
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   destroyed and functions registered by calling
   ^^^^^^^^^
   atexit are called. Objects with static storage
   duration are destroyed in the reverse order of
   the completion of their constructor.
   (Automatic objects are not destroyed
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   as a result of calling exit().) "

but that has nothing to do with behavior
of pthread_cancel/exit wrt destruction of
automatic objects and C thread cleanup
handlers (see the last paragraph below).

The POSIX standard (non-normative Rationale volume) says:

"Thread Cancelation Cleanup Handlers
 .
 .
 .
 The alternative to providing these simple cancelation cleanup
 handlers (whose only use is for cleaning up when a thread is
 canceled) is to define a general exception package that could
 be used for handling and cleaning up after hardware traps and
 software-detected errors. This was too far removed from the
 charter of providing threads to handle asynchrony. However,
 it is an explicit goal of IEEE Std 1003.1-2001 to be compatible
 with existing exception facilities and languages having
 exceptions.

 The interaction of this facility and other procedure-based or
 language-level exception facilities is unspecified in this
 version of IEEE Std 1003.1-2001. However, it is intended that
 it be possible for an implementation to define the relationship
 between these cancelation cleanup handlers and Ada, C++, or
 other language-level exception handling facilities.

 It was suggested that the cancelation cleanup handlers should
 also be called when the process exits or calls the exec function.
 This was rejected partly due to the performance problem caused
 by having to call the cancelation cleanup handlers of every
 thread before the operation could continue. The other reason was
 that the only state expected to be cleaned up by the cancelation
 cleanup handlers would be the intraprocess state. Any handlers
 that are to clean up the interprocess state would be registered
 with atexit ( ). "

regards,
alexander.


reentrant <reentrant@yahoo.com>@sources.redhat.com on 12/19/2001 07:22:13
PM

Sent by:  pthreads-win32-owner@sources.redhat.com


To:   "Pthreads-Win32@Sources.Redhat.Com"
      <pthreads-win32@sources.redhat.com>
cc:
Subject:  Re: pthreads VCE: problem with destructor




Due to the nature of the beast just as the responsibility lies with the
programmer to design the program to "cleanly" (including running
destructors,
ad nauseum) exit when exit() is called, it should also be the
responsibility of
the programmer to design a thread to cleanly exit with pthread_exit() or
pthread_cancel() are called.  Just as exit() should not be called in a C++
program if dtors are desired to run neither should pthread_exit() from a
thread.  IMHO.

I would imagine that exit() was chosen not to be modified to account for
running C++ destructors for about the same reasons that pthread_exit()
should
not account for running C++ destructors.  Dtors not being called in these
cases
is and should be expected behavior.

Regardless as Mr. Bossom so well has already stated: I certainly wouldn't
depend on pthread_exit() or pthread_cancel() allowing destructors to run to
be
portable though.  Since the primary purpose of this library is to enhance
portability of programs using pthreads, counting on pthread_exit() or
pthread_cancel() to work in a non-portable way seems self-defeating.

Simple sample programs included in the distribution of pthreads to
demonstrate
the technique might help.  Maybe something like:

class AppExit
{
public:
    AppExit( int status ) :
        m_status( status )
    {}
    ~AppExit( void )
    {}

    int GetStatus( void ) const
    { return m_status; }

private:
    int m_status;
};

void function( void )
{
    // blah blah blah

    if( true )
    {
        // Error.  blah blah blah failed.
        throw AppExit( 3 );
    }

    // blah blah blah succeeded,
    // continue execution as usual...
}

int main( void )
{
    try
    {
        // Call functions and what not.
        // If an abrupt exit is required
        // throw AppExit to unwind the stack
        // and exit in the catch block.
        function( );
    }
    catch( const AppExit& ae )
    {
        // App requested to exit.
        // exit() itself not used here so
        // global and other dtors will run
        // correctly.
        return ae.GetStatus( );
    }
    return 0;
}

Replace "AppExit" with something like "ThreadExit" and "main" with the name
of
the thread entry point function, account for the return value type
difference
and there's an example for cleanly exiting a thread (I'm confident the
similar
parallel can be figured out without explicitly spelling it out :).

I'm not even going to attempt to touch the complexities or nuances of
issues
related to clean cancellation in any language or on any OS :).  I'd instead
recommend against cancellation altogether and recommend using a mechanism
to
signal the thread to exit itself (like throwing an exception above or
something).  But that's another story and just an opinion.  Cancellation is
covered in plenty depth elsewhere.

While attempting to allow dtors to be run upon a pthread_exit() or
pthread_cancel() is certainly a noble goal, it's beyond the scope of the
pthread library.  It's the programmer's responsibility IMHO.

So, as I hope is obvious by this point :), I am completely in support of
the
"nasty hacks" being removed and a clean C interface version of the library
being provided only.

My two cents,
Dave


--- Ross Johnson <rpj@ise.canberra.edu.au> wrote:
> I sense a rising and ruthless desire to deal with the problem of
> the exception-based versions of the library. It would certainly
> be a lot easier if they weren't there, and there are some
> hacks in pthread.h supporting them that really are nasty.
>
> So ... what to do about them?
>
> I will firstly put John's warning in the README file
> and the README.NONPORTABLE file, and on the Web page.
>
> Secondly, there is a standard C version of the library courtesy
> of Thomas Pfaff's contributions. It uses setjmp/longjmp.
> Does this need to be built differently to work with C++
> applications (assuming they are written as John suggests they
> should be)? I can try putting it through the VCE run of the
> test suite as soon as I reinstall my corrupted Windows 98 machine.
>
> Thirdly, if possible, consider phasing out all but the VC and GC
> versions of the library (currently the only standard C versions).
> That is, phase out the VCE, VSE, and GCE versions.
>
> Does anyone wan't to jump up and shout - NO!!
>
> Ross
>


__________________________________________________
Do You Yahoo!?
Check out Yahoo! Shopping and Yahoo! Auctions for all of
your unique holiday gifts! Buy at http://shopping.yahoo.com
or bid at http://auctions.yahoo.com




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]