Game Development Community

Semaphore never attained during CreateWindow

by Ian Omroth Hardingham · in Torque 3D Professional · 07/08/2009 (4:19 am) · 7 replies

Hey guys.

Continuing my epic Torque3D process project, I am now at a new stage. I'll take you through it.

I have a DLL called Haxmio. The DLL has a method which, when called, basically tries to spawn Torque3D in a separate thread.

The thread is created with:

hThread2 = CreateThread( 
        NULL,                   // default security attributes
        0,                      // use default stack size  
        threadFunction,       // thread function name
        pData2,          // argument to thread function 
        0,                      // use default creation flags 
        &dwThreadId2);   // returns the thread identifier

As soon as the thread is created, it calls the following, which we basically just took directly from the Torque3D exe:

int (*torque_winmain)( HINSTANCE hInstance, HINSTANCE h, LPSTR lpszCmdLine, int nShow) = NULL;

   char filename[4096];
   char gameLib[4096];

   GetModuleFileNameA(NULL, filename, 4096);
   filename[strlen(filename)-4] = 0;
   sprintf(gameLib, "%s", "C:\Torque\Torque 3D 2009 Beta 3\Genre Kits\FPS Genre Kit\game\FPS Genre Kit_DEBUG.dll");

HMODULE hGame = LoadLibraryA(gameLib);
torque_winmain = (int (*)(HINSTANCE hInstance, HINSTANCE h, LPSTR lpszCmdLine, int nShow))GetProcAddress(hGame, "torque_winmain");

   char error[4096];
   if (!hGame)
   {
      sprintf(error, "Unable to load game library: %s.  Please make sure it exists and the latest DirectX is installed.", gameLib);
      MessageBoxA(NULL, error, "Error",  MB_OK|MB_ICONWARNING);
      return -1;
   }

   if (!torque_winmain)
   {
      sprintf(error, "Missing torque_winmain export in game library: %s.  Please make sure that it exists and the latest DirectX is installed.", gameLib);
      MessageBoxA(NULL, error, "Error",  MB_OK|MB_ICONWARNING);
      return -1;
   }

	LPSTR szOutput("");


	torque_winmain((HINSTANCE)GetModuleHandle(NULL), NULL, szOutput, 1);

   FreeLibrary(hGame);

	return 0;
}


This seems to go fine, but during initialisation Torque hangs waiting for a semaphore. Here's the trace:

>	FPS Genre Kit_DEBUG.dll!Semaphore::acquire(bool block=true)  Line 45	C++
 	FPS Genre Kit_DEBUG.dll!SimConsoleThreadExecCallback::waitForResult()  Line 98 + 0xc bytes	C++
 	FPS Genre Kit_DEBUG.dll!Con::execute(int argc=2, const char * * argv=0x06886658)  Line 966 + 0x8 bytes	C++
 	FPS Genre Kit_DEBUG.dll!Con::_executef(int checkArgc=2, int argc=2, const char * a=0x0271a230, const char * b=0x0951aef8, const char * c=0x00000000, const char * d=0x00000000, const char * e=0x00000000, const char * f=0x00000000, const char * g=0x00000000, const char * h=0x00000000, const char * i=0x00000000, const char * j=0x00000000)  Line 1084 + 0xd bytes	C++
 	FPS Genre Kit_DEBUG.dll!Con::executef(const char * a=0x0271a230, const char * b=0x0951aef8)  Line 1089 + 0x2a bytes	C++
 	FPS Genre Kit_DEBUG.dll!GFXCardProfiler::loadProfileScript(const char * aScriptName=0x06886a14)  Line 35 + 0x11 bytes	C++
 	FPS Genre Kit_DEBUG.dll!GFXCardProfiler::loadProfileScripts(const char * render=0x0951a998, const char * vendor=0x0951a9e0, const char * card=0x0951aa38, const char * version=0x0951aa88)  Line 46	C++
 	FPS Genre Kit_DEBUG.dll!GFXCardProfiler::init()  Line 110	C++
 	FPS Genre Kit_DEBUG.dll!GFXD3D9CardProfiler::init()  Line 54	C++
 	FPS Genre Kit_DEBUG.dll!GFXPCD3D9Device::init(const GFXVideoMode & mode={...}, PlatformWindow * window=0x095139b8)  Line 384	C++
 	FPS Genre Kit_DEBUG.dll!GFXD3D9Device::allocWindowTarget(PlatformWindow * window=0x095139b8)  Line 1101	C++
 	FPS Genre Kit_DEBUG.dll!Win32WindowManager::createWindow(GFXDevice * device=0x0956add0, const GFXVideoMode & mode={...})  Line 180 + 0x14 bytes	C++
 	FPS Genre Kit_DEBUG.dll!GuiCanvas::onAdd()  Line 143 + 0x26 bytes	C++


I'm not experienced with windows thread management, and am pretty stuck. Can anyone advise?

Thanks,
Ian

#1
07/09/2009 (11:14 am)
Looks to me like Torque isn't properly detecting its main thread here. It does a console execute, but should really do it on the main thread. Instead, it thinks it's not on the main thread and does a threaded execute and waits for the result from the main thread (which never arrives as it is on the main thread).

Put a breakpoint in Con::execute and see if isMainThread() returns the correct value. If not, that's the problem.

//EDIT: corrected function names
#2
07/10/2009 (1:59 am)
Hi Rene, many thanks for the reply.

I did manage to fix this issue, but I'm not really totally sure what the problem was.
#3
07/10/2009 (3:42 am)
the problem is that you start torque in a thread. As such its main thread (the process thread) actually is your application that started torque, not the thread within which torque is beeing started, although thats the idea you likely followed with it.

Interesting things for which people are using T3D :)
#4
07/10/2009 (3:43 am)
Thankyou Marc - that was indeed the problem (I think).
#5
07/10/2009 (3:46 am)
I say I managed to fix this issue, but Doug Baker actually fixed this for me - thanks to him.
#6
07/10/2009 (6:10 am)
Actually, I'm a bit surprised because judging from the code above, the LoadLibrary call comes on the thread running Torque and *not* on the thread spawning Torque. Torque 3D takes as its main thread whichever thread it is that is running global ctors, so with the code above it really should properly detect its main thread. If that was the problem here.

I'm glad it is working for you. If Doug fixed a bug in Torque 3D here, I'd be happy to integrate the fix.
#7
07/10/2009 (6:15 am)
It was just a fix to our code actually, no change to Torque. The change was to move the loadLibrary call from within the torque dll (being called externally) to within the calling dll's project, but within the same thread.