From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2116 invoked by alias); 19 Dec 2001 19:30:21 -0000 Mailing-List: contact pthreads-win32-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: pthreads-win32-owner@sources.redhat.com Received: (qmail 2094 invoked from network); 19 Dec 2001 19:30:19 -0000 Received: from unknown (HELO d12lmsgate.de.ibm.com) (195.212.91.199) by sources.redhat.com with SMTP; 19 Dec 2001 19:30:19 -0000 Received: from d12relay02.de.ibm.com (d12relay02.de.ibm.com [9.165.215.23]) by d12lmsgate.de.ibm.com (1.0.0) with ESMTP id UAA122976 for ; Wed, 19 Dec 2001 20:30:17 +0100 Received: from d12ml007.de.ibm.com (d12ml007_cs0 [9.165.223.36]) by d12relay02.de.ibm.com (8.11.1m3/NCO v5.01) with ESMTP id fBJJUp2189668 for ; Wed, 19 Dec 2001 20:30:51 +0100 Importance: Normal Subject: Re: pthreads VCE: problem with destructor To: pthreads-win32@sources.redhat.com X-Mailer: Lotus Notes Release 5.0.8 June 18, 2001 Message-ID: From: "Alexander Terekhov" Date: Thu, 01 Feb 2001 06:46:00 -0000 X-MIMETrack: Serialize by Router on D12ML007/12/M/IBM(Release 5.0.8 |June 18, 2001) at 19/12/2001 20:30:57 MIME-Version: 1.0 Content-type: text/plain; charset=us-ascii X-SW-Source: 2001/txt/msg00015.txt.bz2 > 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 @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" 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 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 From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Alexander Terekhov" To: pthreads-win32@sources.redhat.com Subject: Re: pthreads VCE: problem with destructor Date: Wed, 19 Dec 2001 11:30:00 -0000 Message-ID: X-SW-Source: 2001/msg00153.html Message-ID: <20011219113000.s6b01nfNgS0ub687ZdlcFYP6GP4NcICSihJjmFastR4@z> > 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 @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" 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 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