summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-11-07 16:34:22 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-11-30 14:26:49 +0000
commit2f02b9294d68d1fc2632464e790665cd0525dd3f (patch)
tree61e894774a02adbdc04749f9dd5ca11316236c50
parent05d2da4169ec7951d8ee18917b5aa34e8ccc3519 (diff)
Make window creation and destruction be synchronous
At the moment, because Windows windows must be created and destroyed by the thread that we want to process events with, XCWM_EVENT_WINDOW_CREATE just posts a message to another thread to create the window, we can then receive and try to process additional events (usually damage) on that window before the window creation has completed. Likewise XCWM_EVENT_WINDOW_DELETE just posts a message to another thread to delete the window, then releases the xcwm_window_t. If a different WM_* message is recieved for that window before the WM_DELETE is processed, the xcw_window_t pointer stored in the WIN_XCWM_PROP property will be invalid. Block the processing of additional X events until window creation or destruction completes.
-rw-r--r--src/main.c20
-rw-r--r--src/wndproc.c2
2 files changed, 18 insertions, 4 deletions
diff --git a/src/main.c b/src/main.c
index b3a1245..68b4e04 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <getopt.h>
#include <xcwm/xcwm.h>
+#include <semaphore.h>
#include "debug.h"
#include "global.h"
@@ -33,6 +34,8 @@
xcwm_context_t *context;
DWORD msgPumpThread;
+static sem_t semaphore;
+
static void
eventHandler(const xcwm_event_t *event)
{
@@ -51,6 +54,7 @@ eventHandler(const xcwm_event_t *event)
message pump in to create the window...
*/
PostThreadMessage(msgPumpThread, WM_XCWM_CREATE, 0, (LPARAM)window);
+ sem_wait(&semaphore);
break;
case XCWM_EVENT_WINDOW_DESTROY:
@@ -58,6 +62,7 @@ eventHandler(const xcwm_event_t *event)
Only the owner thread is allowed to destroy a window
*/
PostThreadMessage(msgPumpThread, WM_XCWM_DESTROY, 0, (LPARAM)window);
+ sem_wait(&semaphore);
break;
case XCWM_EVENT_WINDOW_NAME:
@@ -139,6 +144,9 @@ int main(int argc, char **argv)
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
msgPumpThread = GetCurrentThreadId();
+ // initialize semaphore used for synchronization
+ sem_init(&semaphore, 0, 0);
+
// Get access to DwmEnableBlurBehindWindow, if available, so we can take advantage of it
// on Vista and later, but still run on earlier versions of Windows
HMODULE hDwmApiLib = LoadLibraryEx("dwmapi.dll", NULL, 0);
@@ -161,9 +169,15 @@ int main(int argc, char **argv)
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
if (msg.message == WM_XCWM_CREATE)
- winCreateWindowsWindow((xcwm_window_t *)msg.lParam);
+ {
+ winCreateWindowsWindow((xcwm_window_t *)msg.lParam);
+ sem_post(&semaphore);
+ }
else if (msg.message == WM_XCWM_DESTROY)
- winDestroyWindowsWindow((xcwm_window_t *)msg.lParam);
+ {
+ winDestroyWindowsWindow((xcwm_window_t *)msg.lParam);
+ sem_post(&semaphore);
+ }
else
DispatchMessage(&msg);
}
@@ -177,4 +191,6 @@ int main(int argc, char **argv)
xcwm_context_close(context);
FreeLibrary(hDwmApiLib);
+
+ sem_destroy(&semaphore);
}
diff --git a/src/wndproc.c b/src/wndproc.c
index f50fde0..dbc0c07 100644
--- a/src/wndproc.c
+++ b/src/wndproc.c
@@ -836,8 +836,6 @@ winTopLevelWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CLOSE:
xcwm_window_request_close(window);
- // XXX: RACE!!! window will become invalid when we get XCB_DESTROY_NOTIFY back from server
- // but this wndproc may continue to touch it until we get WM_DESTROY..
return 0;
case WM_DESTROY: