We've run into a bit of a nasty issue with the DDraw OWN_WINDOW code.  This code exists
to create a fake 'full screen' window for DDraw apps that ask for exclusive full-screen
control.  

The window is created in dlls/ddraw/dsurface/user.c.  It gets created in the DDraw 
update thread that is used to periodically refresh that window.  As the thread 
starts, it creates the window and uses SetWindowPos to position it and show it.
We have to create the window in the update thread, since there's no guarantee that 
the thread that puts DDraw into full-screen mode has a message loop.  

The problem arises here: in the call to SetWindowPos, we end up calling 
EVENT_Synchronize,
which tries to send a focus-change message to a window in the main thread.  The 
inter-thread SendMessage in the update thread then blocks, waiting for a reply.

In the meantime, the main thread goes about it's merry way, and in the case below,
tries to initialize Direct3D.  For various reasons, this also requires us to 
do a SetWindowPos call on the full-screen window.  Problem is, that the update
thread is holding the SysLevel lock, but it can't release it until the main thread
processes the focus-out message.  A trace is included below....

We're at a bit of a loss for coming up with a reasonable solution here.  We could
peek for messages in the main thread immediately after creating the update thread, 
but this seems not quite right.  

Oddly enough, putting a sleep(1) immediately after creating the update thread allows
the main thread to get past the deadlock and into 3d rendering (which doesn't actually
require the update thread), but the update thread still sits there waiting for the
focus message to be processed for some reason.

Suggestions anyone?

============================ ============================ ============================

Update Thread

#0  0x402df634 in   ()
#1  0x400f3b74 in   ()
#2  0x400bf187 in wine_server_call (req=REQ_SELECT) at client.c:243
#3  0x400c3ac4 in WaitForMultipleObjectsEx (count=1, handles=0x49f96b60, wait_all=0,
    timeout=4294967295, alertable=0) at ../include/server.h:1622
#4  0x400c3906 in WaitForSingleObject (handle=1414155695, timeout=4294967295)
    at synchro.c:110
#5  0x40708c47 in QUEUE_WaitBits (bits=32768, timeout=4294967295) at queue.c:729
#6  0x406fc0d5 in MSG_SendMessageInterThread (hDestQueue=583, hwnd=432, msg=31, 
wParam=0,
    lParam=0, timeout=4294967295, flags=4096, pRes=0x49f96c2c) at message.c:888
#7  0x406fd761 in MSG_SendMessage (hwnd=432, msg=31, wParam=0, lParam=0,
    timeout=4294967295, flags=4096, pRes=0x49f96c2c) at message.c:1795
#8  0x406fd8a3 in SendMessageA (hwnd=432, msg=31, wParam=0, lParam=0) at message.c:1845
#9  0x407ba02a in EVENT_FocusOut (hWnd=432, event=0x49f96d58) at event.c:851
#10 0x407b95c9 in EVENT_ProcessEvent (event=0x49f96d58) at event.c:413
#11 0x407b8f4a in EVENT_ProcessAllEvents (arg=0) at event.c:200
#12 0x407b8fa2 in X11DRV_Synchronize () at event.c:214
#13 0x406f2c5e in EVENT_Synchronize () at event.c:23
#14 0x40719bc0 in SetWindowPos (hwnd=792, hwndInsertAfter=0, x=0, y=0, cx=0, cy=0,
    flags=9563) at winpos.c:2943
#15 0x407772da in User_create_own_window (This=0x40362004) at dsurface/user.c:320
#16 0x40777370 in User_update_thread (arg=0x40362004) at dsurface/user.c:352
#17 0x400c4a90 in THREAD_Start () at thread.c:276
#18 0x400c3cbe in SYSDEPS_StartThread (teb=0x49fa7000) at sysdeps.c:134

===================================================================
Main Thread

(gdb) bt
#0  0x402df634 in   ()
#1  0x400f3b74 in   ()
#2  0x400bf187 in wine_server_call (req=REQ_SELECT) at client.c:243
#3  0x400c3ac4 in WaitForMultipleObjectsEx (count=1, handles=0x40564a14,
    wait_all=0, timeout=4294967295, alertable=0) at ../include/server.h:1622
#4  0x400c3906 in WaitForSingleObject (handle=84, timeout=4294967295)
    at synchro.c:110
#5  0x40058b72 in RtlpWaitForCriticalSection (crit=0x40745928)
    at critsection.c:190
#6  0x40058d07 in RtlEnterCriticalSection (crit=0x40745928)
    at critsection.c:240
#7  0x400c4138 in _EnterSysLevel (lock=0x40745928) at syslevel.c:77
#8  0x40710d0c in WIN_LockWnds () at win.c:55
#9  0x40710df8 in WIN_FindWndPtr (hwnd=640) at win.c:108
#10 0x407193be in SetWindowPos (hwnd=640, hwndInsertAfter=0, x=0, y=0, cx=0,
    cy=0, flags=9499) at winpos.c:2625
#11 0x407771aa in get_display_window (This=0x403606d8, pt=0x40564bf4)
    at dsurface/user.c:260
#12 0x40777263 in User_DirectDrawSurface_get_display_window (This=0x403606d8)
    at dsurface/user.c:301
#13 0x4075d54b in common_inst_OpenGL (rguid=0x1014c4c, surface=0x4036095c,
    device=0x40360ab8, d3d=0x40363da0) at d3ddevice/mesa.c:667
#14 0x4075df35 in d3d7inst_OpenGL (rguid=0x1014c4c, surface=0x4036095c,
    device=0x49800c7c, d3d=0x40363da0, vtable=0x40786500)
    at d3ddevice/mesa.c:966
#15 0x4076c518 in MESA_IDirect3D7Impl_CreateDevice (iface=0x40363da0,
    rguid=0x1014c4c, surface=0x4036095c, device=0x49800c7c)
    at direct3d/mesa.c:396


-- 
Gavriel State, CEO
TransGaming Technologies Inc.
http://www.transgaming.com
[EMAIL PROTECTED]

Reply via email to