Hi, Bit long, sorry. I build my own GTK+ stack with MinGW (TDM-4.6.1) and have been using 2.16 and Glib 2.28 (with Gtk2-Perl bindings mostly) for a long time, then switched to GTK+ 2.24 when that started to get stable enough. Wanting to start with WebKit I switched to Glib 2.30 to be able to use GObject-Introspection from Dieter's git repo. This still worked fine, but needing later G-O-I interfaces from WebKit, I tried to build 1.8 which needs Glib 2.31 or later, so I switched to Glib 2.32.3, and this is where my problems started. All threaded Gtk2-Perl apps locked up on startup and I initially thought it was a Gtk2-Perl problem, but building the example from the FAQ: http://developer.gnome.org/gtk-faq/stable/x481.html result in the same problem. The easiest way to reproduce it is to start the example and then move the window which immediately results in a deadlock. Searching around, I saw mention of GTK+ 2.24 being frozen at Glib 2.28, so I built GTK+ 3.4.3 and then the example against it, but it does exactly the same. I tried with Ruben's MinGW-x64 builds, but same thing. Searching some more, I found references of different threads on Windows updating the same window can have problems (for Gtk2-Perl this is anyhow a no-no, so I never do that), I moved updating the label outside the threads via g_idle_add() (see attached gtk-thread.c), but still the same result. Looking at the changes between Glib 2.30 and 2.32, I saw the threading was reworked, and as I was testing on Windows 7, I thought it could be the NT 6.0 or later primitives being used, and tried with Windows XP, but this triggered the assertion: ----- Glib:ERROR:glib-2.32.3\glib\gthread-win32.c:639:g_thread_xp_AcquireSRWLockExclusive: assertion failed: (!lock->writer_locked) ----- Basically: ----- /* CRITICAL_SECTION is reentrant, but SRWLock is not. * Detect the deadlock that would occur on later Windows version. */ g_assert (!lock->writer_locked); ----- With previous Glib versions, GMutex on Win32 was implemented with EnterCriticalSection() and friends, and taking a lock twice in the same thread did not cause any issues, for example: ----- gdk_threads_enter(); gdk_threads_enter(); ----- would work fine, but with the new code, it either aborts or deadlocks. As I am not that closely familiar with all the inner workings, and what was intended, I am not sure if this is supposed to be, but that change currently with even GTK+ 3.4 makes Glib 2.32 unusable on Windows, so I tried to debug further. Unable to get decent backtraces with GDB, I rebuild the whole stack with VS2010 and although I could actually get the backtrace of where the deadlock is taking place, it still was unclear where the first lock was taken. I added the code in gdk_threads_enter() and gdk_threads_leave to print below info, basically: - for gdk_threads_enter(): - print the function name and current thread pointer - print "deadlock" if the lock is already held - print the backtrace - for gdk_threads_leave() - print the function name and current thread pointer As can be seen below (StackWalker did not use the Symbols location, so I added a better trace at the end): - the first few gdk_threads_enter/gdk_threads_leave traces are pretty much repeated a lot with the same thread pointer (main thread) - when the window is moved (last gdk_threads_enter before the deadlock), a new lock is taken while the first is still held within the same main thread and thus the deadlock. I am unsure of where the problem exactly is, or if Win32 should maybe just use a GRecMutex for the GDK lock for the time being with Glib 2.32? Anyway, if I can give more information or help with testing/debugging let me know. *********************** gdk_threads_enter: 032CB3C0 *********************** c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\stackwalker.cpp (920): StackWalker::ShowCallstack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\show_stack.cpp (8): show_stack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (692): gdk_threads_impl_lock c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (669): gdk_threads_enter c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3374): gdk_event_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (2541): g_main_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3075): g_main_context_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3146): g_main_context_iterate c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3340): g_main_loop_run c:\opt\vs10-gtk2\gtk+-3.4.3\gtk\gtkmain.c (1161): gtk_main c:\opt\vs10-gtk2\gtk+-3.4.3\build\win32\vs10\gtk-thread.c (155): main f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): mainCRTStartup ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74A2339A) 74A2339A (kernel32): (filename not available): BaseThreadInitThunk ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EF2) 77019EF2 (ntdll): (filename not available): RtlInitializeExceptionChain ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EC5) 77019EC5 (ntdll): (filename not available): RtlInitializeExceptionChain *********************** gdk_threads_leave: 032CB3C0 *********************** *********************** gdk_threads_enter: 032CB3C0 *********************** c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\stackwalker.cpp (920): StackWalker::ShowCallstack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\show_stack.cpp (8): show_stack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (692): gdk_threads_impl_lock c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (669): gdk_threads_enter c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3331): gdk_event_prepare c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (2836): g_main_context_prepare c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3126): g_main_context_iterate c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3340): g_main_loop_run c:\opt\vs10-gtk2\gtk+-3.4.3\gtk\gtkmain.c (1161): gtk_main c:\opt\vs10-gtk2\gtk+-3.4.3\build\win32\vs10\gtk-thread.c (155): main f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): mainCRTStartup ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74A2339A) 74A2339A (kernel32): (filename not available): BaseThreadInitThunk ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EF2) 77019EF2 (ntdll): (filename not available): RtlInitializeExceptionChain ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EC5) 77019EC5 (ntdll): (filename not available): RtlInitializeExceptionChain *********************** gdk_threads_leave: 032CB3C0 *********************** *********************** gdk_threads_enter: 032CB3C0 *********************** c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\stackwalker.cpp (920): StackWalker::ShowCallstack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\show_stack.cpp (8): show_stack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (692): gdk_threads_impl_lock c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (669): gdk_threads_enter c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3374): gdk_event_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (2541): g_main_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3075): g_main_context_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3146): g_main_context_iterate c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3340): g_main_loop_run c:\opt\vs10-gtk2\gtk+-3.4.3\gtk\gtkmain.c (1161): gtk_main c:\opt\vs10-gtk2\gtk+-3.4.3\build\win32\vs10\gtk-thread.c (155): main f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): mainCRTStartup ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74A2339A) 74A2339A (kernel32): (filename not available): BaseThreadInitThunk ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EF2) 77019EF2 (ntdll): (filename not available): RtlInitializeExceptionChain ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EC5) 77019EC5 (ntdll): (filename not available): RtlInitializeExceptionChain *********************** gdk_threads_enter: 032CB3C0 *********************** c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\stackwalker.cpp (920): StackWalker::ShowCallstack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\show_stack.cpp (8): show_stack c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (692): gdk_threads_impl_lock c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\gdk.c (669): gdk_threads_enter c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3331): gdk_event_prepare c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (2836): g_main_context_prepare c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3126): g_main_context_iterate c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3172): g_main_context_pending c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (1604): modal_timer_proc c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (2820): gdk_event_translate c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (261): inner_window_procedure c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (292): _gdk_win32_window_procedure ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB62FA) 74BB62FA (USER32): (filename not available): gapfnScSendMessage ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB7316) 74BB7316 (USER32): (filename not available): GetDC ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6DE8) 74BB6DE8 (USER32): (filename not available): GetThreadDesktop ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB8FA7) 74BB8FA7 (USER32): (filename not available): LoadStringW ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 76FF010A) 76FF010A (ntdll): (filename not available): KiUserCallbackDispatcher ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6A8C) 74BB6A8C (USER32): (filename not available): gapfnScSendMessage ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71287744) 71287744 (uxtheme): (filename not available): GetThemeBool ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7128A092) 7128A092 (uxtheme): (filename not available): SetWindowThemeAttribute ERROR: SymGetSymFromAddr64, GetLastError: 487 (Address: 71280B0D) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71280B0D) 71280B0D (uxtheme): (filename not available): (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 487 (Address: 71280B96) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71280B96) 71280B96 (uxtheme): (filename not available): (function-name not available) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB729A) 74BB729A (USER32): (filename not available): GetPropW c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (275): inner_window_procedure c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (292): _gdk_win32_window_procedure ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB62FA) 74BB62FA (USER32): (filename not available): gapfnScSendMessage ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB7316) 74BB7316 (USER32): (filename not available): GetDC ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6DE8) 74BB6DE8 (USER32): (filename not available): GetThreadDesktop ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6E44) 74BB6E44 (USER32): (filename not available): GetThreadDesktop ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 76FF010A) 76FF010A (ntdll): (filename not available): KiUserCallbackDispatcher ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6A8C) 74BB6A8C (USER32): (filename not available): gapfnScSendMessage ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71287744) 71287744 (uxtheme): (filename not available): GetThemeBool ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71296E85) 71296E85 (uxtheme): (filename not available): GetCurrentThemeName ERROR: SymGetSymFromAddr64, GetLastError: 487 (Address: 71280B0D) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71280B0D) 71280B0D (uxtheme): (filename not available): (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 487 (Address: 71280B96) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 71280B96) 71280B96 (uxtheme): (filename not available): (function-name not available) ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB729A) 74BB729A (USER32): (filename not available): GetPropW c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (275): inner_window_procedure c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (292): _gdk_win32_window_procedure ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB62FA) 74BB62FA (USER32): (filename not available): gapfnScSendMessage ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB6D3A) 74BB6D3A (USER32): (filename not available): GetThreadDesktop ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB77C4) 74BB77C4 (USER32): (filename not available): CharPrevW ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74BB788A) 74BB788A (USER32): (filename not available): DispatchMessageW c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3319): _gdk_win32_display_queue_events c:\opt\vs10-gtk2\gtk+-3.4.3\gdk\win32\gdkevents-win32.c (3374): gdk_event_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (2541): g_main_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3075): g_main_context_dispatch c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3146): g_main_context_iterate c:\opt\vs10-gtk2\glib-2.32.3\glib\gmain.c (3340): g_main_loop_run c:\opt\vs10-gtk2\gtk+-3.4.3\gtk\gtkmain.c (1161): gtk_main c:\opt\vs10-gtk2\gtk+-3.4.3\build\win32\vs10\gtk-thread.c (155): main f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): mainCRTStartup ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 74A2339A) 74A2339A (kernel32): (filename not available): BaseThreadInitThunk ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EF2) 77019EF2 (ntdll): (filename not available): RtlInitializeExceptionChain ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 77019EC5) 77019EC5 (ntdll): (filename not available): RtlInitializeExceptionChain *********************** deadlock: 032CB3C0 *********************** --------------------- VS2010 callstack ------------------- ntdll.dll!_ZwWaitForKeyedEvent@16() + 0x15 bytes ntdll.dll!_ZwWaitForKeyedEvent@16() + 0x15 bytes > glib-2-vs10.dll!g_mutex_lock(_GMutex * mutex=0x0f644b00) Line 139 + 0xc bytes C gdk-win32-3-vs10.dll!gdk_threads_impl_lock() Line 687 + 0xa bytes C gdk-win32-3-vs10.dll!gdk_threads_enter() Line 669 + 0x8 bytes C gdk-win32-3-vs10.dll!gdk_event_prepare(_GSource * source=0x030bd3c8, int * timeout=0x0018defc) Line 3331 C glib-2-vs10.dll!g_main_context_prepare(_GMainContext * context=0x030be5d8, int * priority=0x0018e05c) Line 2836 + 0xd bytes C glib-2-vs10.dll!g_main_context_iterate(_GMainContext * context=0x030be5d8, int block=0, int dispatch=0, _GThread * self=0x030fa3c0) Line 3126 + 0xd bytes C glib-2-vs10.dll!g_main_context_pending(_GMainContext * context=0x030be5d8) Line 3172 + 0x13 bytes C gdk-win32-3-vs10.dll!modal_timer_proc(HWND__ * hwnd=0x00000000, unsigned int msg=0, unsigned int id=0, unsigned long time=0) Line 1604 + 0x10 bytes C gdk-win32-3-vs10.dll!gdk_event_translate(tagMSG * msg=0x0018ea78, int * ret_valp=0x0018ea60) Line 2820 C gdk-win32-3-vs10.dll!inner_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=71, unsigned int wparam=0, long lparam=1633520) Line 261 + 0xd bytes C gdk-win32-3-vs10.dll!_gdk_win32_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=71, unsigned int wparam=0, long lparam=1633520) Line 292 + 0x15 bytes C user32.dll!_InternalCallWinProc@20() + 0x23 bytes user32.dll!_UserCallWinProcCheckWow@32() + 0x693 bytes user32.dll!_DispatchClientMessage@24() + 0x51 bytes user32.dll!___fnINLPWINDOWPOS@4() + 0x2c bytes ntdll.dll!_KiUserCallbackDispatcher@12() + 0x2e bytes user32.dll!_NtUserMessageCall@28() + 0x15 bytes user32.dll!_RealDefWindowProcWorker@24() + 0xace bytes user32.dll!_RealDefWindowProcW@16() + 0x2a bytes uxtheme.dll!DoMsgDefault() + 0x29 bytes uxtheme.dll!OnDwpSysCommand() + 0x29 bytes uxtheme.dll!_ThemeDefWindowProc() + 0xfb bytes uxtheme.dll!_ThemeDefWindowProcW@16() + 0x18 bytes user32.dll!_DefWindowProcW@16() + 0x805 bytes gdk-win32-3-vs10.dll!inner_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=274, unsigned int wparam=61458, long lparam=7602404) Line 275 + 0x18 bytes C gdk-win32-3-vs10.dll!_gdk_win32_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=274, unsigned int wparam=61458, long lparam=7602404) Line 292 + 0x15 bytes C user32.dll!_InternalCallWinProc@20() + 0x23 bytes user32.dll!_UserCallWinProcCheckWow@32() + 0x693 bytes user32.dll!_DispatchClientMessage@24() + 0x51 bytes user32.dll!___fnDWORD@4() + 0x2b bytes ntdll.dll!_KiUserCallbackDispatcher@12() + 0x2e bytes user32.dll!_NtUserMessageCall@28() + 0x15 bytes user32.dll!_RealDefWindowProcWorker@24() + 0xace bytes user32.dll!_RealDefWindowProcW@16() + 0x2a bytes uxtheme.dll!DoMsgDefault() + 0x29 bytes uxtheme.dll!OnDwpNcLButtonDown() + 0x4b bytes uxtheme.dll!_ThemeDefWindowProc() + 0xfb bytes uxtheme.dll!_ThemeDefWindowProcW@16() + 0x18 bytes user32.dll!_DefWindowProcW@16() + 0x805 bytes gdk-win32-3-vs10.dll!inner_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=161, unsigned int wparam=2, long lparam=7602404) Line 275 + 0x18 bytes C gdk-win32-3-vs10.dll!_gdk_win32_window_procedure(HWND__ * hwnd=0x013f0622, unsigned int message=161, unsigned int wparam=2, long lparam=7602404) Line 292 + 0x15 bytes C user32.dll!_InternalCallWinProc@20() + 0x23 bytes user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 bytes user32.dll!_DispatchMessageWorker@8() + 0xed bytes user32.dll!_DispatchMessageW@4() + 0xf bytes gdk-win32-3-vs10.dll!_gdk_win32_display_queue_events(_GdkDisplay * display=0x030a4020) Line 3319 + 0xc bytes C gdk-win32-3-vs10.dll!gdk_event_dispatch(_GSource * source=0x030bd3c8, int (void *)* callback=0x00000000, void * user_data=0x00000000) Line 3374 + 0xb bytes C glib-2-vs10.dll!g_main_dispatch(_GMainContext * context=0x030be5d8) Line 2541 + 0x11 bytes C glib-2-vs10.dll!g_main_context_dispatch(_GMainContext * context=0x030be5d8) Line 3075 + 0x9 bytes C glib-2-vs10.dll!g_main_context_iterate(_GMainContext * context=0x030be5d8, int block=1, int dispatch=1, _GThread * self=0x030fa3c0) Line 3146 + 0x9 bytes C glib-2-vs10.dll!g_main_loop_run(_GMainLoop * loop=0x03178bc0) Line 3340 + 0x13 bytes C gtk-win32-3-vs10.dll!gtk_main() Line 1161 + 0x9 bytes C gtk3-thread.exe!main(int argc=1, char * * argv=0x017a1cf0) Line 150 C gtk3-thread.exe!__tmainCRTStartup() Line 555 + 0x19 bytes C gtk3-thread.exe!mainCRTStartup() Line 371 C kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
/*------------------------------------------------------------------------- * Filename: gtk-thread.c * Version: 1.99.1 * Copyright: Copyright (C) 1999, Erik Mouw * Author: Erik Mouw <J.A.K.Mouw@xxxxxxxxxxxxxx> * Description: GTK threads example. * Created at: Sun Oct 17 21:27:09 1999 * Modified by: Owen Taylor <otaylor@xxxxxxx> * Modified at: Wed May 28 10:43:00 2003 *-----------------------------------------------------------------------*/ /* * Compile with: * * gcc -mms-bitfields -mthreads -o gtk-thread gtk-thread.c `pkg-config --cflags --libs gtk+-2.0 gthread-2.0` * * Thanks to Sebastian Wilhelmi for pointing out some bugs in earlier versions. * */ #include <windows.h> //#include <unistd.h> #include <gtk/gtk.h> #define YES_IT_IS (1) #define NO_IT_IS_NOT (0) typedef struct { GtkWidget *label; int what; } yes_or_no_args; G_LOCK_DEFINE_STATIC (yes_or_no); static volatile int yes_or_no = YES_IT_IS; void destroy(GtkWidget *widget, gpointer data) { gtk_main_quit(); } gint myfunc(void *args) { yes_or_no_args *data = (yes_or_no_args *)args; /* get GTK thread lock */ //gdk_threads_enter(); G_LOCK(yes_or_no); /* set label text */ if(data->what == YES_IT_IS) gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!"); else gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!"); G_UNLOCK(yes_or_no); /* Make sure all X commands are sent to the X server; not strictly * necessary here, but always a good idea when you do anything * from a thread other than the one where the main loop is running. */ gdk_flush (); /* release GTK thread lock */ //gdk_threads_leave(); return FALSE; // call only once } void *argument_thread(void *args) { yes_or_no_args *data = (yes_or_no_args *)args; gboolean say_something; for(;;) { /* sleep a while */ _sleep(g_random_int_range (1, 4)); /* lock the yes_or_no_variable */ G_LOCK(yes_or_no); /* do we have to say something? */ say_something = (yes_or_no != data->what); if(say_something) { /* set the variable */ yes_or_no = data->what; } /* Unlock the yes_or_no variable */ G_UNLOCK(yes_or_no); if(say_something) { //g_idle_add(myfunc, data); gdk_threads_add_idle(myfunc, data); } } return NULL; } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *label; GError *error = NULL; yes_or_no_args yes_args, no_args; /* init threads */ //g_thread_init(NULL); gdk_threads_init(); /* init gtk */ gtk_init(&argc, &argv); /* create a window */ window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL); gtk_container_set_border_width(GTK_CONTAINER (window), 10); /* create a label */ label = gtk_label_new("And now for something completely different ..."); gtk_container_add(GTK_CONTAINER(window), label); /* show everything */ gtk_widget_show(label); gtk_widget_show (window); /* create the threads */ yes_args.label = label; yes_args.what = YES_IT_IS; if (!g_thread_create(argument_thread, &yes_args, FALSE, &error)) { g_printerr ("Failed to create YES thread: %s\n", error->message); return 1; } no_args.label = label; no_args.what = NO_IT_IS_NOT; if (!g_thread_create(argument_thread, &no_args, FALSE, &error)) { g_printerr ("Failed to create NO thread: %s\n", error->message); return 1; } /* enter the GTK main loop */ gdk_threads_enter(); gtk_main(); gdk_threads_leave(); return 0; }
_______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx https://mail.gnome.org/mailman/listinfo/gtk-list