Use InterlockedExchange to get a full memory barrier on Windows
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Mon, 13 Aug 2012 17:00:23 +0000 (18:00 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 9 Nov 2012 15:31:30 +0000 (15:31 +0000)
See the bug for extensive discussion.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=41423
Reviewed-by: Ralf Habacker <ralf.habacker@freenet.de>
dbus/dbus-sysdeps-win.c

index bc4951b..5a2fb20 100644 (file)
@@ -3121,8 +3121,18 @@ _dbus_atomic_dec (DBusAtomic *atomic)
 dbus_int32_t
 _dbus_atomic_get (DBusAtomic *atomic)
 {
-  /* this is what GLib does, hopefully it's right... */
-  MemoryBarrier ();
+  /* In this situation, GLib issues a MemoryBarrier() and then returns
+   * atomic->value. However, mingw from mingw.org (not to be confused with
+   * mingw-w64 from mingw-w64.sf.net) does not have MemoryBarrier in its
+   * headers, so we have to get a memory barrier some other way.
+   *
+   * InterlockedIncrement is older, and is documented on MSDN to be a full
+   * memory barrier, so let's use that.
+   */
+  long dummy = 0;
+
+  InterlockedExchange (&dummy, 1);
+
   return atomic->value;
 }