This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin 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]

[PATCH] Patch for MTinterface


I have discovered some problems with the current MTinterface
implementation. Here are 2 test cases:

1: mainthread related

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static void * Thread (void *);

static pthread_t main_thread;

int main(void)
{
  pthread_t t;

  main_thread = pthread_self ();

  pthread_create (&t, NULL, Thread, NULL);
  sleep (5);
  pthread_exit (t);

  return 0;
}

static void * Thread (void *not_used)
{
  pthread_join (main_thread, NULL);

  return NULL;
}

This valid code doesn't work at all. The mainthread object in MTinterface
is not properly initialized, the cancel_event is NULL and the win32_obj_id
is NULL because myself->hProcess is NULL when MTinterface is initialized
(and i don't think that a process handle can be used as thread handle).
Even if the handles would be valid the pthread_join call would try to
delete a thread object that is created static which would result in a
corrupted heap.


2: fork related

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>

static void * TestThread ( void * );

int main (void)
{
  pthread_t t;

  printf ("main: %p\n", pthread_self ());

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

  return 0;
}

static void * TestThread ( void *not_used )
{
  switch (fork ())
    {
    case -1:
      return NULL;
    case 0:
      printf ("child:  %p\n", pthread_self());
      break;
    default:
      printf ("parent: %p\n", pthread_self());
      wait (NULL);
    }

  return NULL;
}

The forked child will not get the same thread handle as its parent, it
will get the thread handle from the main thread instead. The child will
not terminate because the threadcount is still 2 after the fork (it is
set to 1 in MTinterface::Init and then set back to 2 after the childs
memory gets overwritten by the parent).



And i do not agree with the the current pthread_self code where the
threadcount is incremented if a new thread handle has been created but
never gets decremented (i do not expect that threads that are not created
by pthread_created will terminate via pthread_exit). And the newly created
object never gets freed.


To avoid these errors i have made changes that will create the mainthread
object dynamic and store the reents and thread self pointer via fork safe
keys.

Thomas

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

	* dcrt0.cc (dll_crt0_1): Add call to pthread::initMainThread to
	initialize mainthread when it is safe to call new.
	* init.cc (dll_entry): Change call to store reents in tls key.
	* thread.cc (_reent_clib) : Change call to get reents from tls
	key.
	(_reent_winsup): Ditto.
	(MTinterface::Init): Key handling changed. Remove initialization
	of member variables.
	(MTinterface::fixup_after_fork): Reinitialize mainthread object
	after fork. Reset threadount to 1.
	(pthread::initMainThread): Create mainthread object dynamically.
	and initialize with valid handles.
	(pthread::self): Remove calls to create thread objects.
	(pthread::setTlsSelfPointer): Change call to store thread self
	handle in tls key.
	(pthread::getTlsSelfPointer): New static method.
	(pthread::exit): Remove setTlsSelfPointer call.
	(pthread::initCurrentThread): New method.
	(pthread::thread_init_wrapper): Change call to store thread self
	handle in tls key.
	(pthread::join): Check for a valid joiner.
	(pthreadNull::pthreadNull): Mark Null object as detached.
	(pthreadNull::exit): Terminate thread via ExitThread.
	* thread.h (pthread::initMainThread): Change parameter in function
	call.
	(pthread::getTlsSelfPointer): New static method.
	(pthread::initCurrentThread): New method.
	(MTinterface::reent_key): Remove.
	(MTinterface::thread_self_dwTlsIndex): Ditto..
	(MTinterface::indexallocated): Ditto.
	(MTinterface::mainthread): Ditto.
	(MTinterface::reent_key): New member.
	(MTinterface::thread_self_key): Ditto.
	(MTinterface::MTinterface): Initialize all members.

Attachment: mtinterface.patch
Description: Text document


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