# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1378754316 0 # Node ID 09860ba329a4a3e8055c76f35928c3baed29e6f7 # Parent f7d408a477526766e31505d0dcaa574525217c4d Divided thread initialization and deinitialization into separate exported functions so they can be accessed from language bindings. diff -r f7d408a47752 -r 09860ba329a4 dw.h --- a/dw.h Thu Sep 05 17:58:40 2013 +0000 +++ b/dw.h Mon Sep 09 19:18:36 2013 +0000 @@ -1770,5 +1770,8 @@ void API dw_print_cancel(HPRINT print); wchar_t * API dw_utf8_to_wchar(char *utf8string); char * API dw_wchar_to_utf8(wchar_t *wstring); +/* Exported for language bindings */ +void API _dw_init_thread(void); +void API _dw_deinit_thread(void); #endif diff -r f7d408a47752 -r 09860ba329a4 gtk/dw.c --- a/gtk/dw.c Thu Sep 05 17:58:40 2013 +0000 +++ b/gtk/dw.c Mon Sep 09 19:18:36 2013 +0000 @@ -1983,15 +1983,6 @@ } #endif -void _init_thread(void) -{ - GdkColor *foreground = malloc(sizeof(GdkColor)); - - foreground->pixel = foreground->red = foreground->green = foreground->blue = 0; - pthread_setspecific(_dw_fg_color_key, foreground); - pthread_setspecific(_dw_bg_color_key, NULL); -} - /* Try to load the mozilla embed shared libary */ #ifdef USE_GTKMOZEMBED #include @@ -2177,7 +2168,7 @@ pthread_key_create(&_dw_bg_color_key, NULL); pthread_key_create(&_dw_mutex_key, NULL); - _init_thread(); + _dw_init_thread(); gtk_rc_parse_string("style \"gtk-tooltips-style\" { bg[NORMAL] = \"#eeee00\" } widget \"gtk-tooltips\" style \"gtk-tooltips-style\""); @@ -10106,6 +10097,37 @@ return DW_ERROR_NONE; } +/* + * Generally an internal function called from a newly created + * thread to setup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they create threads that require access to Dynamic Windows. + */ +void API _dw_init_thread(void) +{ + GdkColor *foreground = malloc(sizeof(GdkColor)); + + foreground->pixel = foreground->red = foreground->green = foreground->blue = 0; + pthread_setspecific(_dw_fg_color_key, foreground); + pthread_setspecific(_dw_bg_color_key, NULL); +} + +/* + * Generally an internal function called from a terminating + * thread to cleanup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they exit threads that require access to Dynamic Windows. + */ +void API _dw_deinit_thread(void) +{ + GdkColor *foreground, *background; + + if((foreground = pthread_getspecific(_dw_fg_color_key))) + free(foreground); + if((background = pthread_getspecific(_dw_bg_color_key))) + free(background); +} + /* * Setup thread independent color sets. */ @@ -10113,21 +10135,17 @@ { void (*threadfunc)(void *) = NULL; void **tmp = (void **)data; - GdkColor *foreground, *background; threadfunc = (void (*)(void *))tmp[0]; /* Initialize colors */ - _init_thread(); + _dw_init_thread(); threadfunc(tmp[1]); free(tmp); /* Free colors */ - if((foreground = pthread_getspecific(_dw_fg_color_key))) - free(foreground); - if((background = pthread_getspecific(_dw_bg_color_key))) - free(background); + _dw_deinit_thread(); } /* diff -r f7d408a47752 -r 09860ba329a4 gtk3/dw.c --- a/gtk3/dw.c Thu Sep 05 17:58:40 2013 +0000 +++ b/gtk3/dw.c Mon Sep 09 19:18:36 2013 +0000 @@ -1783,15 +1783,6 @@ return NULL; } -void _init_thread(void) -{ - GdkRGBA *foreground = malloc(sizeof(GdkRGBA)); - - foreground->alpha = foreground->red = foreground->green = foreground->blue = 0.0; - pthread_setspecific(_dw_fg_color_key, foreground); - pthread_setspecific(_dw_bg_color_key, NULL); -} - /* Try to load the WebKitGtk shared libary */ #ifdef USE_WEBKIT void init_webkit(void) @@ -1879,7 +1870,7 @@ pthread_key_create(&_dw_bg_color_key, NULL); pthread_key_create(&_dw_mutex_key, NULL); - _init_thread(); + _dw_init_thread(); /* Create a global object for glib activities */ _DWObject = g_object_new(G_TYPE_OBJECT, NULL); @@ -8323,6 +8314,37 @@ return DW_ERROR_NONE; } +/* + * Generally an internal function called from a newly created + * thread to setup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they create threads that require access to Dynamic Windows. + */ +void API _dw_init_thread(void) +{ + GdkRGBA *foreground = malloc(sizeof(GdkRGBA)); + + foreground->alpha = foreground->red = foreground->green = foreground->blue = 0.0; + pthread_setspecific(_dw_fg_color_key, foreground); + pthread_setspecific(_dw_bg_color_key, NULL); +} + +/* + * Generally an internal function called from a terminating + * thread to cleanup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they exit threads that require access to Dynamic Windows. + */ +void API _dw_deinit_thread(void) +{ + GdkRGBA *foreground, *background; + + if((foreground = pthread_getspecific(_dw_fg_color_key))) + free(foreground); + if((background = pthread_getspecific(_dw_bg_color_key))) + free(background); +} + /* * Setup thread independent color sets. */ @@ -8330,21 +8352,17 @@ { void (*threadfunc)(void *) = NULL; void **tmp = (void **)data; - GdkRGBA *foreground, *background; threadfunc = (void (*)(void *))tmp[0]; /* Initialize colors */ - _init_thread(); + _dw_init_thread(); threadfunc(tmp[1]); free(tmp); /* Free colors */ - if((foreground = pthread_getspecific(_dw_fg_color_key))) - free(foreground); - if((background = pthread_getspecific(_dw_bg_color_key))) - free(background); + _dw_deinit_thread(); } /* diff -r f7d408a47752 -r 09860ba329a4 mac/dw.m --- a/mac/dw.m Thu Sep 05 17:58:40 2013 +0000 +++ b/mac/dw.m Mon Sep 09 19:18:36 2013 +0000 @@ -10911,27 +10911,32 @@ #endif } -/* - * Setup thread independent pools. - */ -void _dwthreadstart(void *data) -{ - void (*threadfunc)(void *) = NULL; - void **tmp = (void **)data; - NSColor *color; - +/* + * Generally an internal function called from a newly created + * thread to setup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they create threads that require access to Dynamic Windows. + */ +void API _dw_init_thread(void) +{ /* If we aren't using garbage collection we need autorelease pools */ #if !defined(GARBAGE_COLLECT) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; pthread_setspecific(_dw_pool_key, pool); #endif _init_colors(); - - threadfunc = (void (*)(void *))tmp[0]; - - /* Start our thread function */ - threadfunc(tmp[1]); - +} + +/* + * Generally an internal function called from a terminating + * thread to cleanup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they exit threads that require access to Dynamic Windows. + */ +void API _dw_deinit_thread(void) +{ + NSColor *color; + /* Release the pool when we are done so we don't leak */ color = pthread_getspecific(_dw_fg_color_key); [color release]; @@ -10941,7 +10946,26 @@ pool = pthread_getspecific(_dw_pool_key); [pool drain]; #endif +} + +/* + * Setup thread independent pools. + */ +void _dwthreadstart(void *data) +{ + void (*threadfunc)(void *) = NULL; + void **tmp = (void **)data; + + _dw_init_thread(); + + threadfunc = (void (*)(void *))tmp[0]; + + /* Start our thread function */ + threadfunc(tmp[1]); + free(tmp); + + _dw_deinit_thread(); } /* diff -r f7d408a47752 -r 09860ba329a4 os2/dw.c --- a/os2/dw.c Thu Sep 05 17:58:40 2013 +0000 +++ b/os2/dw.c Mon Sep 09 19:18:36 2013 +0000 @@ -11912,28 +11912,66 @@ return 0; } +/* + * Generally an internal function called from a newly created + * thread to setup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they create threads that require access to Dynamic Windows. + */ +void API _dw_init_thread(void) +{ + HAB thishab = WinInitialize(0); + HMQ thishmq = WinCreateMsgQueue(thishab, 0); + void **threadinfo = (void **)malloc(sizeof(void *) * 2); + + threadinfo[0] = (void *)thishab; + threadinfo[1] = (void *)thishmq; + + _threadstore() = (void *)threadinfo; + +#ifdef UNICODE + /* Set the codepage to 1208 (UTF-8) */ + WinSetCp(thishmq, 1208); +#endif +} + +/* + * Generally an internal function called from a terminating + * thread to cleanup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they exit threads that require access to Dynamic Windows. + */ +void API _dw_deinit_thread(void) +{ + void **threadinfo = (void **)_threadstore(); + + if(threadinfo) + { + HAB thishab = (HAB)threadinfo[0]; + HMQ thishmq = (HMQ)threadinfo[1]; + + WinDestroyMsgQueue(thishmq); + WinTerminate(thishab); + free(threadinfo); + } +} + /* * Encapsulate the message queues on OS/2. */ void _dwthreadstart(void *data) { - HAB thishab = WinInitialize(0); - HMQ thishmq = WinCreateMsgQueue(thishab, 0); void (API_FUNC threadfunc)(void *) = NULL; void **tmp = (void **)data; -#ifdef UNICODE - /* Set the codepage to 1208 (UTF-8) */ - WinSetCp(thishmq, 1208); -#endif + _dw_init_thread(); threadfunc = (void (API_FUNC)(void *))tmp[0]; threadfunc(tmp[1]); free(tmp); - WinDestroyMsgQueue(thishmq); - WinTerminate(thishab); + _dw_deinit_thread(); } /* diff -r f7d408a47752 -r 09860ba329a4 os2/dw.def --- a/os2/dw.def Thu Sep 05 17:58:40 2013 +0000 +++ b/os2/dw.def Mon Sep 09 19:18:36 2013 +0000 @@ -24,6 +24,9 @@ dw_app_dir @25 dw_main_quit @26 dw_shutdown @27 + + _dw_init_thread @30 + _dw_deinit_thread @31 dw_box_new @40 dw_groupbox_new @41 diff -r f7d408a47752 -r 09860ba329a4 os2/dw.lnk --- a/os2/dw.lnk Thu Sep 05 17:58:40 2013 +0000 +++ b/os2/dw.lnk Mon Sep 09 19:18:36 2013 +0000 @@ -19,6 +19,9 @@ export dw_app_dir.25 export dw_main_quit.26 export dw_shutdown.27 + +export _dw_init_thread.30 +export _dw_deinit_thread.31 export dw_box_new.40 export dw_groupbox_new.41 diff -r f7d408a47752 -r 09860ba329a4 win/dw-mingw.def --- a/win/dw-mingw.def Thu Sep 05 17:58:40 2013 +0000 +++ b/win/dw-mingw.def Mon Sep 09 19:18:36 2013 +0000 @@ -23,6 +23,9 @@ dw_app_dir @25 dw_main_quit @26 dw_shutdown @27 + + _dw_init_thread @30 + _dw_deinit_thread @31 dw_box_new @40 dw_groupbox_new @41 diff -r f7d408a47752 -r 09860ba329a4 win/dw.c --- a/win/dw.c Thu Sep 05 17:58:40 2013 +0000 +++ b/win/dw.c Mon Sep 09 19:18:36 2013 +0000 @@ -3761,27 +3761,6 @@ } #endif -/* Initialize thread local values to the defaults */ -void _init_thread(void) -{ - COLORREF foreground = RGB(128,128,128); - COLORREF background = DW_RGB_TRANSPARENT; -#ifdef GDIPLUS - ARGB gpfore = MAKEARGB(255, 128, 128, 128); - GpBrush *brush; - GpPen *pen; - - GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen); - TlsSetValue(_gpPen, (LPVOID)pen); - GdipCreateSolidFill(gpfore, &brush); - TlsSetValue(_gpBrush, brush); -#endif - TlsSetValue(_foreground, DW_UINT_TO_POINTER(foreground)); - TlsSetValue(_background, DW_UINT_TO_POINTER(background)); - TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground)); - TlsSetValue(_hBrush, CreateSolidBrush(foreground)); -} - /* * Initializes the Dynamic Windows engine. * Parameters: @@ -3978,8 +3957,8 @@ GdiplusStartup(&gdiplusToken, &si, NULL); #endif - /* GDI+ Needs to be initialized before calling _init_thread(); */ - _init_thread(); + /* GDI+ Needs to be initialized before calling _dw_init_thread(); */ + _dw_init_thread(); if((huxtheme = LoadLibrary(TEXT("uxtheme")))) _SetWindowTheme = (HRESULT (WINAPI *)(HWND, LPCWSTR, LPCWSTR ))GetProcAddress(huxtheme, "SetWindowTheme"); @@ -11385,13 +11364,40 @@ return 0; } -/* - * Encapsulate thread creation on Win32. - */ -void _dwthreadstart(void *data) -{ - void (* threadfunc)(void *) = NULL; - void **tmp = (void **)data; +/* + * Generally an internal function called from a newly created + * thread to setup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they create threads that require access to Dynamic Windows. + */ +void API _dw_init_thread(void) +{ + COLORREF foreground = RGB(128,128,128); + COLORREF background = DW_RGB_TRANSPARENT; +#ifdef GDIPLUS + ARGB gpfore = MAKEARGB(255, 128, 128, 128); + GpBrush *brush; + GpPen *pen; + + GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen); + TlsSetValue(_gpPen, (LPVOID)pen); + GdipCreateSolidFill(gpfore, &brush); + TlsSetValue(_gpBrush, brush); +#endif + TlsSetValue(_foreground, DW_UINT_TO_POINTER(foreground)); + TlsSetValue(_background, DW_UINT_TO_POINTER(background)); + TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground)); + TlsSetValue(_hBrush, CreateSolidBrush(foreground)); +} + +/* + * Generally an internal function called from a terminating + * thread to cleanup the Dynamic Windows environment for the thread. + * However it is exported so language bindings can call it when + * they exit threads that require access to Dynamic Windows. + */ +void API _dw_deinit_thread(void) +{ HPEN hPen; HBRUSH hBrush; #ifdef GDIPLUS @@ -11399,12 +11405,6 @@ GpPen *pen; #endif - _init_thread(); - - threadfunc = (void (*)(void *))tmp[0]; - threadfunc(tmp[1]); - - free(tmp); if((hPen = TlsGetValue(_hPen))) DeleteObject(hPen); if((hBrush = TlsGetValue(_hBrush))) @@ -11418,6 +11418,23 @@ } /* + * Encapsulate thread creation on Win32. + */ +void _dwthreadstart(void *data) +{ + void (* threadfunc)(void *) = NULL; + void **tmp = (void **)data; + + _dw_init_thread(); + + threadfunc = (void (*)(void *))tmp[0]; + threadfunc(tmp[1]); + + free(tmp); + _dw_deinit_thread(); +} + +/* * Creates a new thread with a starting point of func. * Parameters: * func: Function which will be run in the new thread. diff -r f7d408a47752 -r 09860ba329a4 win/dw.def --- a/win/dw.def Thu Sep 05 17:58:40 2013 +0000 +++ b/win/dw.def Mon Sep 09 19:18:36 2013 +0000 @@ -23,6 +23,9 @@ dw_app_dir @25 dw_main_quit @26 dw_shutdown @27 + + _dw_init_thread @30 + _dw_deinit_thread @31 dw_box_new @40 dw_groupbox_new @41