Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Message-Id: <199912070351.VAA26863@mercury.xraylith.wisc.edu> To: cygwin-developers AT sourceware DOT cygnus DOT com Subject: (patch) enable signals in dynamically loaded Cygwin DLL Date: Mon, 06 Dec 1999 21:51:31 -0600 From: Mumit Khan Completely forgot about the synchronization used in makethread to avoid stack corruption, and that's why enabling signals for dynamically loaded Cygwin was crashing in newly created threads. This change removes the synchronization and uses dynamically allocated memory to the thread stub routine, which frees the memory. The overhead should be roughly the same, perhaps a tiny bit higher due to malloc's internal MT synchronization. A gotcha for future users of makethread -- if you pass a thread parameter, make sure it's not on the stack (which is the case currently, so it should be safe). Patch against today's snapshot. Mon Dec 6 21:32:01 1999 Mumit Khan * dcrt0.cc (dll_crt0_1): Enable signal handling for dynamically loaded case. * debug.cc: Include stdlib.h. (thread_start): Delete sync field. (thread_stub): Remove use of thread_start.sync field, and free the memory for the argument. (makethread): Dynamically allocate the argument passed to thread_stub, and remove synchronization. Index: dcrt0.cc =================================================================== RCS file: /home/khan/CVSROOT/cygwin/winsup/dcrt0.cc,v retrieving revision 1.1.1.2 diff -u -3 -p -r1.1.1.2 dcrt0.cc --- dcrt0.cc 1999/12/07 01:36:15 1.1.1.2 +++ dcrt0.cc 1999/12/07 02:43:28 @@ -713,13 +713,8 @@ dll_crt0_1 () /* Allocate dtable */ dtable_init (); - /* Can't use signals in non-cygwin apps since it depends on synchronizing - with a a helper thread. */ - if (!dynamically_loaded) - { - /* Initialize signal/subprocess handling. */ - sigproc_init (); - } + /* Initialize signal/subprocess handling. */ + sigproc_init (); /* Connect to tty. */ tty_init (); Index: debug.cc =================================================================== RCS file: /home/khan/CVSROOT/cygwin/winsup/debug.cc,v retrieving revision 1.1.1.2 diff -u -3 -p -r1.1.1.2 debug.cc --- debug.cc 1999/12/07 01:36:15 1.1.1.2 +++ debug.cc 1999/12/07 02:51:22 @@ -9,6 +9,7 @@ details. */ #define NO_DEBUG_DEFINES #include "winsup.h" #include "exceptions.h" +#include static muto NO_COPY *__tn = NULL; #define lock_thread_name() \ @@ -27,7 +28,6 @@ typedef struct { LPTHREAD_START_ROUTINE func; VOID *arg; - HANDLE sync; } thread_start; static NO_COPY thread_info threads[32]; // increase as necessary @@ -72,9 +72,7 @@ thread_stub (VOID *arg) api_fatal(" Sig proc MT init failed\n"); #endif - /* Signal the initiating thread that we've copied 'info' here and that it's - safe to continue. */ - SetEvent (info.sync); + free (arg); init_exceptions (&except_entry); @@ -90,18 +88,18 @@ makethread (LPTHREAD_START_ROUTINE start DWORD tid; HANDLE h; SECURITY_ATTRIBUTES *sa; - thread_start info; /* Various information needed by the newly created thread */ + /* Various information needed by the newly created thread. The memory + is released by thread_stub. */ + thread_start* info = (thread_start *) malloc (sizeof (thread_start)); - info.func = start; /* Real function to start */ - info.arg = param; /* The single parameter to the thread */ + if (!info) + { + debug_printf ("malloc failed, %E"); + return INVALID_HANDLE_VALUE; + } - /* This event is used to synchronize with the newly created thread. It ensures - that this function will not exit before the 'info' information above is copied - to the thread's stack from *this* thread's stack. - - Without this synchronization, this function would just continue and the stack - for makethread could be overwritten before the thread_stub gets to it. */ - info.sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + info->func = start; /* Real function to start */ + info->arg = param; /* The single parameter to the thread */ if (*name != '+') sa = &sec_none_nih; /* The handle should not be inherited by subprocesses. */ @@ -111,13 +109,10 @@ makethread (LPTHREAD_START_ROUTINE start sa = &sec_none; /* The handle should be inherited by subprocesses. */ } - if ((h = CreateThread (sa, 0, thread_stub, (VOID *)&info, flags, &tid))) + if ((h = CreateThread (sa, 0, thread_stub, (VOID *)info, flags, &tid))) { regthread (name, tid); /* Register this name/thread id for debugging output. */ - WaitForSingleObject (info.sync, INFINITE); /* Wait for go ahead from the new thread. */ } - CloseHandle (info.sync); - return h; }