[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / glib / gthread-win32.c
index 29065b5..275ecc6 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -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;