Hi guys,
I've been investigating a bug with threads in
the Corel tree of WINE for a little while, and I noticed
that it can be replicated with the current CVS build
from WineHQ as well.
To replicate the bug, all you have to do is create a lot
of threads very rapidly. All the created thread does is
exit, and there is a synchronization to ensure that only one
thread is created at any time. If you do it enough times
in rapid succession, you will not be able to create any more
threads. (on my pc, between 2500 ~ 4000 thread creations
causes this.)
It seems that somewhere between the client and the wine server
a file descriptor is not being closed, and eventually there
are too many open files, thus the client is not able to
open a connection with the server to create more new threads.
In the WineHQ build, it dies in THREAD_Create
(/scheduler/thread.c), in the following code snippet:
=======
/* Create the thread on the server side */
if (teb->socket == -1)
{
req->suspend = ((flags & CREATE_SUSPENDED) != 0);
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
/**************** The call below fails ***************/
if (server_call_fd( REQ_NEW_THREAD, -1, &teb->socket )) goto error;
/* ************************************************* */
teb->tid = req->tid;
*server_handle = req->handle;
fcntl( teb->socket, F_SETFD, 1 ); /* set close on exec flag */
}
=======
To quickly see the bug, stick a printf before the "goto error"
in the above code, and use the following test app (start with
CTestApp2Dlg::OnWineThreadCrash() method):
=======
void CTestApp2Dlg::OnWineThreadCrash()
{
for (int j=0; j<5000; j++)
{
// printf (" DEBUG - Thread #%d Attempted\n\n", ++count1);
StartThread();
Sleep(1);
}
}
void StartThread()
{
const DWORD cbStack = 4096;
DWORD idThread;
EndPreviousThread();
m_hPreviousThread = CreateThread(0, cbStack,
ThreadMethod, NULL, 0,
&idThread);
}
BOOL EndPreviousThread()
{
if (m_hPreviousThread)
{
WaitForSingleObject (m_hPreviousThread, INFINITE);
}
return TRUE;
}
DWORD WINAPI ThreadMethod(LPVOID lpvParam)
{
m_hPreviousThread = 0;
// printf (" DEBUG - Thread #%d Finished \n\n", count1);
ExitThread (0);
return 0;
}
=======
Does anybody have any clues or ideas why this might be happening?
The test app works in windows...
Thanks a lot!
-James
--
James Hatheway
Software Developer - Macadamian Technologies, Inc.
[EMAIL PROTECTED] ~ http://www.macadamian.com
"Nothing is a problem once you debug the code."
John Carmack