X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgthread-win32.c;h=275ecc63c552abbf9d8f135e9343651e2a7ba460;hb=7e3d32b7053b47ca7feecf185abac96b619770c2;hp=29065b55bb2ec1e3ab1b90bf6a23b816b812721d;hpb=11015f165229ac3cb5f008a8824f8135ec45c89a;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gthread-win32.c b/glib/gthread-win32.c index 29065b5..275ecc6 100644 --- a/glib/gthread-win32.c +++ b/glib/gthread-win32.c @@ -16,9 +16,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* @@ -43,6 +41,7 @@ #include "config.h" #include "glib.h" +#include "glib-init.h" #include "gthread.h" #include "gthreadprivate.h" #include "gslice.h" @@ -307,16 +306,8 @@ g_cond_wait_until (GCond *cond, gint64 end_time) { gint64 span; - FILETIME ft; - gint64 now; - GetSystemTimeAsFileTime (&ft); - memmove (&now, &ft, sizeof (FILETIME)); - - now -= G_GINT64_CONSTANT (116444736000000000); - now /= 10; - - span = end_time - now; + span = end_time - g_get_monotonic_time (); if G_UNLIKELY (span < 0) span = 0; @@ -520,8 +511,9 @@ static DWORD g_thread_xp_waiter_tls; typedef struct _GThreadXpWaiter GThreadXpWaiter; struct _GThreadXpWaiter { - HANDLE event; - volatile GThreadXpWaiter *next; + HANDLE event; + volatile GThreadXpWaiter *next; + volatile GThreadXpWaiter **my_owner; }; static GThreadXpWaiter * @@ -539,6 +531,7 @@ g_thread_xp_waiter_get (void) waiter->event = CreateEvent (0, FALSE, FALSE, NULL); if (waiter->event == NULL) g_thread_abort (GetLastError (), "CreateEvent"); + waiter->my_owner = NULL; TlsSetValue (g_thread_xp_waiter_tls, waiter); } @@ -848,6 +841,7 @@ g_thread_xp_SleepConditionVariableSRW (gpointer cond, waiter->next = NULL; EnterCriticalSection (&g_thread_xp_lock); + waiter->my_owner = cv->last_ptr; *cv->last_ptr = waiter; cv->last_ptr = &waiter->next; LeaveCriticalSection (&g_thread_xp_lock); @@ -857,9 +851,23 @@ g_thread_xp_SleepConditionVariableSRW (gpointer cond, if (status != WAIT_TIMEOUT && status != WAIT_OBJECT_0) g_thread_abort (GetLastError (), "WaitForSingleObject"); - g_mutex_lock (mutex); + if (status == WAIT_TIMEOUT) + { + EnterCriticalSection (&g_thread_xp_lock); + if (waiter->my_owner) + { + if (waiter->next) + waiter->next->my_owner = waiter->my_owner; + else + cv->last_ptr = waiter->my_owner; + *waiter->my_owner = waiter->next; + waiter->my_owner = NULL; + } + LeaveCriticalSection (&g_thread_xp_lock); + } + return status == WAIT_OBJECT_0; } @@ -870,17 +878,22 @@ g_thread_xp_WakeConditionVariable (gpointer cond) volatile GThreadXpWaiter *waiter; EnterCriticalSection (&g_thread_xp_lock); + waiter = cv->first; if (waiter != NULL) { + waiter->my_owner = NULL; cv->first = waiter->next; - if (cv->first == NULL) + if (cv->first != NULL) + cv->first->my_owner = &cv->first; + else cv->last_ptr = &cv->first; } - LeaveCriticalSection (&g_thread_xp_lock); if (waiter != NULL) SetEvent (waiter->event); + + LeaveCriticalSection (&g_thread_xp_lock); } static void __stdcall @@ -890,10 +903,10 @@ g_thread_xp_WakeAllConditionVariable (gpointer cond) volatile GThreadXpWaiter *waiter; EnterCriticalSection (&g_thread_xp_lock); + waiter = cv->first; cv->first = NULL; cv->last_ptr = &cv->first; - LeaveCriticalSection (&g_thread_xp_lock); while (waiter != NULL) { @@ -901,8 +914,11 @@ g_thread_xp_WakeAllConditionVariable (gpointer cond) next = waiter->next; SetEvent (waiter->event); + waiter->my_owner = NULL; waiter = next; } + + LeaveCriticalSection (&g_thread_xp_lock); } /* {{{2 XP Setup */ @@ -965,7 +981,7 @@ g_thread_lookup_native_funcs (void) return TRUE; } -G_GNUC_INTERNAL void +void g_thread_win32_init (void) { if (!g_thread_lookup_native_funcs ()) @@ -974,7 +990,7 @@ g_thread_win32_init (void) InitializeCriticalSection (&g_private_lock); } -G_GNUC_INTERNAL void +void g_thread_win32_thread_detach (void) { gboolean dtors_called;