[PATCH] pthread key patch

Thomas Pfaff tpfaff@gmx.net
Mon May 27 04:25:00 GMT 2002


This patch is an improvement to the pthread key code (pthread_key_create,
pthread_getspecific, pthread_setspecific).
This patch will fix some problems if you build gcc
with --enable-threads=posix. I would like to discuss the reason for this
in the cygwin-developers list but unfortunately i am not a member ( i
tried to subscribe but got no answer for my confirmation ).

Here is a small test program

#include <stdio.h>

#include <pthread.h>
static void * TestThread( void * );

int main( void )
{
   for(;;)
   {
      pthread_t t;
      void * result;

      pthread_create(&t, NULL, TestThread, NULL);
      pthread_join(t,  &result);
   }

   return 0;
}

static void * TestThread( void * )
{

   try {

      pthread_exit(NULL);
   }

   catch( ... )
   {
      printf( "Got exception\n" );
   }

   return NULL;
}

Even if i build this with with my pthread patched version of cygwin i see
that the program memory leaks. The reason is that the exception handler of
the newly created thread never gets freed.

This is from gthr-win32.h in gcc/gcc:

#if __MINGW32_MAJOR_VERSION >= 1 || \
  (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
#define MINGW32_SUPPORTS_MT_EH 1
extern int __mingwthr_key_dtor PROTO((DWORD, void (*) (void *)));
/* Mingw runtime >= v0.3 provides a magic variable that is set to
non-zero if -mthreads option was specified, or 0 otherwise. This is to
get around the lack of weak symbols in PE-COFF.  */
extern int _CRT_MT;
#endif

You will see that the exception handler removal via mthreads is limited
to mingw. To work around this problem cygwin1.dll will need a helper dll
like mingwm10.dll or use a different approach.

IMHO the cleanest way is to configure gcc with posix thread handling.
I have already build my gcc this way.

The disadvantages are:

1. A posix build libgcc.a will break the no-cygwin feature.
To work around this the mingw runtime should be shipped with a native
build libgcc.a (and libstdc++.a) .
2. The cygwin1.dll can't be build with this libgcc.a.
Even if the dll is build with no-exceptions it does make some
__get_eh_context calls that will result in __pthread_once, __mutex_lock
and and unlock calls while the dll is not initialized. The cygwin1.dll
will hang at some point during initialization. To get a working dll i
build cygwin1.dll with a single-threaded libgcc.a. I have renamed the
single-threaded libgcc.a to libgcc-single.a and modified the Makefile in
winsup/cygwin to link against libgcc-single instead of libgcc. Since
cygwin1.dll does not use exception handling internally it is save to do
so.

Changelog:

2002-05-27  Thomas Pfaff  <tpfaff@gmx.net>

	* init.cc (dll_entry): Run the pthread_key destructors on thread
	and process detach. This will make sure that regardless a thread
	is created with pthread_create or CreateThread its eh context
	will be freed.
	* thread.cc: Moved #define MT_INTERFACE from thread.cc to
	thread.h.
	(pthread_key_destructor_list::IterateNull): Run
	destructor only if the value is not NULL.
	(pthread_key::get): Save and restore WIN32 LastError to avoid
	that the Lasterror is cleared in the exception handling code.
	(__pthread_exit): Removed IterateNull call. This will be done
	during thread detach.
	* thread.h (pthread::cleanup_stack): Renamed from
	cleanup_handlers to cleanup_stack.
	Moved #define MT_INTERFACE user_data->threadinterface from
	thread.cc to this location.




-------------- next part --------------
A non-text attachment was scrubbed...
Name: pthread_key.patch
Type: application/octet-stream
Size: 2158 bytes
Desc: 
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20020527/e7817ec4/attachment.obj>


More information about the Cygwin-patches mailing list