From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mo DeJong To: cygwin@cygwin.com Subject: Re: Linking to cygwin1.dll and msvcrt.dll ? Date: Thu, 19 Jul 2001 16:13:00 -0000 Message-id: References: <20010718104452.C730@cygbert.vinschen.de> X-SW-Source: 2001-07/msg01138.html On Wed, 18 Jul 2001, Corinna Vinschen wrote: > > > I'm somehow missing a > > > > > > CloseHandle ((HANDLE)code); > > > > > > at this point which at least closes the handle to the thread. Otherwise > > > the following from MSDN is valid: > > > > > > The thread object remains in the system until the thread has > > > terminated and all handles to it have been closed through a > > > call to CloseHandle. > > > > > > Corinna > > > > That is interesting. The code variable is a local and the > > pointer is not saved. Would this call to CloseHandle() > > need to be done after a call to ExitThread()? > > No. After CreateThread() the thread is up and running. The > handle returned by CreateThread() is just the handle for the > parent thread to have control over the child thread. If the > parent is not further interested in controlling the child > it simply closes the handle immediately and forgets about > the child thread: > > if ((thdl = CreateThread (...)) != NULL) > CloseHandle (thdl): I implemented the change you suggested and took care of calling CloseHandle() for the handle returned by CreateThread() or _beginthreadex(). Once the following patch is applied to the CVS version of Tcl, it will build with Cygwin gcc. Index: win/tclWinThrd.c =================================================================== RCS file: /cvsroot/tcl/tcl/win/tclWinThrd.c,v retrieving revision 1.12 diff -u -r1.12 tclWinThrd.c --- win/tclWinThrd.c 2001/07/16 23:30:16 1.12 +++ win/tclWinThrd.c 2001/07/19 07:15:41 @@ -131,14 +131,21 @@ int flags; /* Flags controlling behaviour of * the new thread */ { - unsigned long code; + HANDLE tHandle; EnterCriticalSection(&joinLock); - code = _beginthreadex(NULL, (unsigned) stackSize, proc, clientData, 0, - (unsigned *)idPtr); - - if (code == 0) { +#ifdef __CYGWIN__ + tHandle = CreateThread(NULL, (DWORD) stackSize, + (LPTHREAD_START_ROUTINE) proc, (LPVOID) clientData, + (DWORD) 0, (LPDWORD)idPtr); + if (tHandle == NULL) { +#else + tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, + proc, (void *) clientData, + (unsigned) 0, (unsigned *)idPtr); + if (tHandle == 0) { +#endif /* CYGWIN */ LeaveCriticalSection(&joinLock); return TCL_ERROR; } else { @@ -146,6 +153,7 @@ TclRememberJoinableThread (*idPtr); } + CloseHandle(tHandle); LeaveCriticalSection(&joinLock); return TCL_OK; } @@ -202,7 +210,11 @@ TclSignalExitThread (Tcl_GetCurrentThread (), status); LeaveCriticalSection(&joinLock); - _endthreadex((DWORD)status); +#ifdef __CYGWIN__ + ExitThread((DWORD) status); +#else + _endthreadex((unsigned) status); +#endif /* __CYGWIN__ */ } Of course, there may still be a problem. The reason Tcl started using _beginthreadex() instead of CreateThread() was related to memory that would not be deallocated after a call to ExitThread(). Here are some docs I found on the subject. http://support.microsoft.com/support/kb/articles/q132/0/78.asp http://www.microsoft.com/msj/0799/win32/win320799.htm http://technology.niagarac.on.ca/courses/comp831/win32/_beginthread.htm http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_crt__beginthread.2c_._beginthreadex.asp My question is, is this same memory leak problem going to show up when using Cygwin's CreateThread() and C library APIs? Even if this is not going to be a problem, should Cygwin provide the _beginthread, _beginthreadex, _endthread, and _endthreadex methods to ease porting existing apps that have already dealt with this issue? thanks Mo DeJong Red Hat Inc -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/