<pre style='margin:0'>
Renee Otten (reneeotten) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/2a2a43b3da768075d71a38c3215c87513309fa0b">https://github.com/macports/macports-ports/commit/2a2a43b3da768075d71a38c3215c87513309fa0b</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 2a2a43b3da7 wine-devel,wine-staging: Fix msync & revbump
</span>2a2a43b3da7 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 2a2a43b3da768075d71a38c3215c87513309fa0b
</span>Author: Dean M Greer <38226388+Gcenx@users.noreply.github.com>
AuthorDate: Thu Nov 14 10:57:03 2024 -0500

<span style='display:block; white-space:pre;color:#404040;'>    wine-devel,wine-staging: Fix msync & revbump
</span>---
 emulators/wine-devel/Portfile                      |   12 +-
 .../{macos_hacks.diff => 0002-macos_hacks.diff}    |    0
 emulators/wine-devel/files/1001-devel-msync.diff   |  909 +++--------
 emulators/wine-devel/files/1001-staging-msync.diff | 1634 ++++++--------------
 4 files changed, 687 insertions(+), 1868 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-devel/Portfile b/emulators/wine-devel/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 1cde833b6eb..da4ea667341 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/emulators/wine-devel/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-devel/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -12,7 +12,7 @@ github.tarball_from         archive
</span> name                        wine-devel
 conflicts                   wine-stable wine-staging wine-crossover
 set my_name                 wine
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision                    0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision                    1
</span> platforms                   {darwin >= 19}
 set branch                  [lindex [split ${version} .] 0].x
 license                     LGPL-2.1+
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -67,7 +67,7 @@ patchfiles-append \
</span> 
 # Some required hacks to make wine work better on macOS & Rosetta2
 patchfiles-append \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    macos_hacks.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    0002-macos_hacks.diff
</span> 
 # wine requires the program specified in INSTALL to create intermediate
 # directories; /usr/bin/install doesn't.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -116,7 +116,7 @@ configure.args \
</span>     --without-wayland \
     --without-x
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-configure.env.x86_64-append ac_cv_lib_soname_vulkan=
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.env-append        ac_cv_lib_soname_vulkan=
</span> 
 # We need to tell the linker to add MacPorts to the rpath stack.
 configure.ldflags-append    -Wl,-rpath,${compiler.library_path}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -153,7 +153,7 @@ subport wine-staging {
</span>     # Applying staging after other patchfiles to avoid problems
     post-patch {
         system -W ${worksrcpath} \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            "${workpath}/wine-staging-${staging_version}/staging/patchinstall.py --all -W ntdll-Syscall_Emulation -W winemac.drv-no-flicker-patch"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            "${workpath}/wine-staging-${staging_version}/staging/patchinstall.py --all -W eventfd_synchronization -W ntdll-Syscall_Emulation -W winemac.drv-no-flicker-patch"
</span>         system -W ${worksrcpath} \
             "patch -p1 < ${filespath}/1001-staging-msync.diff"
     }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -212,10 +212,6 @@ configure.ldflags-delete    -L${compiler.library_path}
</span> configure.optflags          -g -O2
 configure.env-append        "CROSSCFLAGS=${configure.optflags}"
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# Needed due to commit
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# https://gitlab.winehq.org/wine/wine/-/commit/b21813fa135995449b7a4ba19b561d6faf087ee8
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-configure.cflags-append     -Wno-error=incompatible-function-pointer-types
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> # Were only installing wine not the development files
 destroot.target             install-lib
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-devel/files/macos_hacks.diff b/emulators/wine-devel/files/0002-macos_hacks.diff
</span>similarity index 100%
rename from emulators/wine-devel/files/macos_hacks.diff
rename to emulators/wine-devel/files/0002-macos_hacks.diff
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-devel/files/1001-devel-msync.diff b/emulators/wine-devel/files/1001-devel-msync.diff
</span><span style='display:block; white-space:pre;color:#808080;'>index 116d0f5d5c8..569c22ed2f1 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/emulators/wine-devel/files/1001-devel-msync.diff
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-devel/files/1001-devel-msync.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -32,10 +32,10 @@ index 0dfee19f714..e4d3d3c8e99 100644
</span>      init_files();
 diff --git a/dlls/ntdll/unix/msync.c b/dlls/ntdll/unix/msync.c
 new file mode 100644
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000000..2eef30dd0f2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 00000000000..f5f1f0aa82d
</span> --- /dev/null
 +++ b/dlls/ntdll/unix/msync.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,1689 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,1695 @@
</span> +/*
 + * mach semaphore-based synchronization objects
 + *
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1069,6 +1069,9 @@ index 00000000000..2eef30dd0f2
</span> +    if ((ret = get_object( handle, &obj ))) return ret;
 +    event = obj->shm;
 +
<span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (obj->type != MSYNC_MANUAL_EVENT && obj->type != MSYNC_AUTO_EVENT)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return STATUS_OBJECT_TYPE_MISMATCH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    current = __atomic_exchange_n( &event->signaled, 0, __ATOMIC_SEQ_CST );
 +
 +    if (prev) *prev = current;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1088,6 +1091,9 @@ index 00000000000..2eef30dd0f2
</span> +    if ((ret = get_object( handle, &obj ))) return ret;
 +    event = obj->shm;
 +
<span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (obj->type != MSYNC_MANUAL_EVENT && obj->type != MSYNC_AUTO_EVENT)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return STATUS_OBJECT_TYPE_MISMATCH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    /* This isn't really correct; an application could miss the write.
 +     * Unfortunately we can't really do much better. Fortunately this is rarely
 +     * used (and publicly deprecated). */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2179,76 +2185,22 @@ index 7e571ac2ba6..dabe3fe83a8 100644
</span>   handle.c \
        hook.c \
        mach.c \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/async.c b/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 749c547af4f..ec39e9dc56b 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -78,6 +78,7 @@ static const struct object_ops async_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     async_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     async_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -698,6 +699,7 @@ static const struct object_ops iosb_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/atom.c b/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index ff0799f5880..7d53bd5e3bb 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -79,6 +79,7 @@ static const struct object_ops atom_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span> diff --git a/server/change.c b/server/change.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index f42ce066340..a1dd0308e92 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f42ce066340..7e94edf8eaa 100644
</span> --- a/server/change.c
 +++ b/server/change.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -112,6 +112,7 @@ static const struct object_ops dir_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx, /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     dir_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/clipboard.c b/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 91f159bc7c9..7ea941b63ee 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +76,7 @@ static const struct object_ops clipboard_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/completion.c b/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f9e68c523f1..bd1391855c4 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -166,6 +166,7 @@ static const struct object_ops completion_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     completion_signaled,       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -125,7 +125,8 @@ static const struct object_ops dir_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,             /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,       /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     dir_close_handle,         /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    dir_destroy               /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    dir_destroy,              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx  /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static int dir_get_poll_events( struct fd *fd );
</span> diff --git a/server/console.c b/server/console.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index b64283baf4a..3b552346871 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b64283baf4a..a9d9687dbf1 100644
</span> --- a/server/console.c
 +++ b/server/console.c
 @@ -41,6 +41,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2259,15 +2211,7 @@ index b64283baf4a..3b552346871 100644
</span>  
  struct screen_buffer;
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -81,6 +82,7 @@ static const struct object_ops console_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_add_queue,                /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_signaled,                 /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_get_fd,                   /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -139,11 +141,13 @@ struct console_server
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -139,11 +140,13 @@ struct console_server
</span>      unsigned int          once_input : 1; /* flag if input thread has already been requested */
      int                   term_fd;        /* UNIX terminal fd */
      struct termios        termios;        /* original termios */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2281,55 +2225,17 @@ index b64283baf4a..3b552346871 100644
</span>  static struct fd *console_server_get_fd( struct object *obj );
  static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
                                                  unsigned int attr, struct object *root );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -158,6 +162,7 @@ static const struct object_ops console_server_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                        /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_server_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    console_server_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_server_get_fd,            /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -227,6 +232,7 @@ static const struct object_ops screen_buffer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     screen_buffer_add_queue,          /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     screen_buffer_get_fd,             /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -276,6 +282,7 @@ static const struct object_ops console_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -313,6 +320,7 @@ static const struct object_ops console_input_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_input_add_queue,          /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_input_get_fd,             /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -370,6 +378,7 @@ static const struct object_ops console_output_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_output_add_queue,         /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_output_get_fd,            /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -428,6 +437,7 @@ static const struct object_ops console_connection_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_connection_get_fd,        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -590,6 +600,10 @@ static void disconnect_console_server( struct console_server *server )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -171,7 +174,8 @@ static const struct object_ops console_server_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     console_server_open_file,         /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,               /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,                  /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    console_server_destroy            /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    console_server_destroy,           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    console_server_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -590,6 +594,10 @@ static void disconnect_console_server( struct console_server *server )
</span>          list_remove( &call->entry );
          console_host_ioctl_terminate( call, STATUS_CANCELLED );
      }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2340,7 +2246,7 @@ index b64283baf4a..3b552346871 100644
</span>      while (!list_empty( &server->read_queue ))
      {
          struct console_host_ioctl *call = LIST_ENTRY( list_head( &server->read_queue ), struct console_host_ioctl, entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -872,6 +886,7 @@ static void console_server_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -872,6 +880,7 @@ static void console_server_destroy( struct object *obj )
</span>      assert( obj->ops == &console_server_ops );
      disconnect_console_server( server );
      if (server->fd) release_object( server->fd );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2348,7 +2254,7 @@ index b64283baf4a..3b552346871 100644
</span>  }
  
  static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -913,6 +928,13 @@ static int console_server_signaled( struct object *obj, struct wait_queue_entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -913,6 +922,13 @@ static int console_server_signaled( struct object *obj, struct wait_queue_entry
</span>      return !server->console || !list_empty( &server->queue );
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2362,7 +2268,7 @@ index b64283baf4a..3b552346871 100644
</span>  static struct fd *console_server_get_fd( struct object* obj )
  {
      struct console_server *server = (struct console_server*)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -945,6 +967,9 @@ static struct object *create_console_server( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -945,6 +961,9 @@ static struct object *create_console_server( void )
</span>      }
      allow_fd_caching(server->fd);
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2372,7 +2278,7 @@ index b64283baf4a..3b552346871 100644
</span>      return &server->obj;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1557,6 +1582,10 @@ DECL_HANDLER(get_next_console_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1557,6 +1576,10 @@ DECL_HANDLER(get_next_console_request)
</span>          /* set result of previous ioctl */
          ioctl = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
          list_remove( &ioctl->entry );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2383,7 +2289,7 @@ index b64283baf4a..3b552346871 100644
</span>      }
  
      if (ioctl)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1643,5 +1672,9 @@ DECL_HANDLER(get_next_console_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1643,5 +1666,9 @@ DECL_HANDLER(get_next_console_request)
</span>          set_error( STATUS_PENDING );
      }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2393,28 +2299,8 @@ index b64283baf4a..3b552346871 100644
</span> +
      release_object( server );
  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/debugger.c b/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c59a0abea77..273a75840e5 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -86,6 +86,7 @@ static const struct object_ops debug_event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     debug_event_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -114,6 +115,7 @@ static const struct object_ops debug_obj_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     debug_obj_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span> diff --git a/server/device.c b/server/device.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 436dac6bfe9..225f8b9890d 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 436dac6bfe9..8274f3f0f83 100644
</span> --- a/server/device.c
 +++ b/server/device.c
 @@ -38,6 +38,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2425,15 +2311,7 @@ index 436dac6bfe9..225f8b9890d 100644
</span>  
  /* IRP object */
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -66,6 +67,7 @@ static const struct object_ops irp_call_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -92,10 +94,12 @@ struct device_manager
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -92,10 +93,12 @@ struct device_manager
</span>      struct list            requests;       /* list of pending irps across all devices */
      struct irp_call       *current_call;   /* call currently executed on client side */
      struct wine_rb_tree    kernel_objects; /* map of objects that have client side pointer associated */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2446,31 +2324,17 @@ index 436dac6bfe9..225f8b9890d 100644
</span>  static void device_manager_destroy( struct object *obj );
  
  static const struct object_ops device_manager_ops =
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -106,6 +110,7 @@ static const struct object_ops device_manager_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                        /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     device_manager_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_manager_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -163,6 +168,7 @@ static const struct object_ops device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -215,6 +221,7 @@ static const struct object_ops device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                        /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,              /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     device_file_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -747,6 +754,9 @@ static void delete_file( struct device_file *file )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -119,7 +122,8 @@ static const struct object_ops device_manager_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                     /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,               /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,                  /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    device_manager_destroy            /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_manager_destroy,           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_manager_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -747,6 +751,9 @@ static void delete_file( struct device_file *file )
</span>      /* terminate all pending requests */
      LIST_FOR_EACH_ENTRY_SAFE( irp, next, &file->requests, struct irp_call, dev_entry )
      {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2480,7 +2344,7 @@ index 436dac6bfe9..225f8b9890d 100644
</span>          list_remove( &irp->mgr_entry );
          set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -782,6 +792,13 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -782,6 +789,13 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
</span>      return !list_empty( &manager->requests );
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2494,7 +2358,7 @@ index 436dac6bfe9..225f8b9890d 100644
</span>  static void device_manager_destroy( struct object *obj )
  {
      struct device_manager *manager = (struct device_manager *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -816,6 +833,9 @@ static void device_manager_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -816,6 +830,9 @@ static void device_manager_destroy( struct object *obj )
</span>          assert( !irp->file && !irp->async );
          release_object( irp );
      }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2504,7 +2368,7 @@ index 436dac6bfe9..225f8b9890d 100644
</span>  }
  
  static struct device_manager *create_device_manager(void)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -828,6 +848,9 @@ static struct device_manager *create_device_manager(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -828,6 +845,9 @@ static struct device_manager *create_device_manager(void)
</span>          list_init( &manager->devices );
          list_init( &manager->requests );
          wine_rb_init( &manager->kernel_objects, compare_kernel_object );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2514,7 +2378,7 @@ index 436dac6bfe9..225f8b9890d 100644
</span>      }
      return manager;
  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1017,6 +1040,9 @@ DECL_HANDLER(get_next_device_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1017,6 +1037,9 @@ DECL_HANDLER(get_next_device_request)
</span>                  /* we already own the object if it's only on manager queue */
                  if (irp->file) grab_object( irp );
                  manager->current_call = irp;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2524,28 +2388,8 @@ index 436dac6bfe9..225f8b9890d 100644
</span>              }
              else close_handle( current->process, reply->next );
          }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/directory.c b/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b37ec969a9e..96275aabdac 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -69,6 +69,7 @@ static const struct object_ops object_type_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -119,6 +120,7 @@ static const struct object_ops directory_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span> diff --git a/server/event.c b/server/event.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index f1b79b1b35e..0162b78a5be 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f1b79b1b35e..8b941db7179 100644
</span> --- a/server/event.c
 +++ b/server/event.c
 @@ -35,6 +35,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2556,7 +2400,7 @@ index f1b79b1b35e..0162b78a5be 100644
</span>  
  static const WCHAR event_name[] = {'E','v','e','n','t'};
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -56,11 +57,13 @@ struct event
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -56,13 +57,16 @@ struct event
</span>      struct list    kernel_object;   /* list of kernel object pointers */
      int            manual_reset;    /* is it a manual reset event? */
      int            signaled;        /* event has been signaled */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2569,23 +2413,20 @@ index f1b79b1b35e..0162b78a5be 100644
</span> +static unsigned int event_get_msync_idx( struct object *obj, enum msync_type *type );
  static int event_signal( struct object *obj, unsigned int access);
  static struct list *event_get_kernel_obj_list( struct object *obj );
<span style='display:block; white-space:pre;background:#e0ffe0;'>++static void event_destroy( struct object *obj );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -85,7 +89,8 @@ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     event_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    no_destroy                 /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    event_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    event_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -72,6 +75,7 @@ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    event_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -119,6 +123,7 @@ static const struct object_ops keyed_event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                   /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     keyed_event_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                   /* get_fd */
</span> @@ -150,6 +155,9 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
              list_init( &event->kernel_object );
              event->manual_reset = manual_reset;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2674,7 +2515,7 @@ index f1b79b1b35e..0162b78a5be 100644
</span>                                          unsigned int attr, const struct security_descriptor *sd )
  {
 diff --git a/server/fd.c b/server/fd.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 04688c5eb0d..07869ed311b 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 04688c5eb0d..83a042137f0 100644
</span> --- a/server/fd.c
 +++ b/server/fd.c
 @@ -94,6 +94,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2693,39 +2534,7 @@ index 04688c5eb0d..07869ed311b 100644
</span>  };
  
  static void fd_dump( struct object *obj, int verbose );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -167,6 +169,7 @@ static const struct object_ops fd_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -208,6 +211,7 @@ static const struct object_ops device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -248,6 +252,7 @@ static const struct object_ops inode_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -290,6 +295,7 @@ static const struct object_ops file_lock_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                  /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     file_lock_signaled,         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1563,6 +1569,9 @@ static void fd_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1563,6 +1565,9 @@ static void fd_destroy( struct object *obj )
</span>          if (fd->unix_fd != -1) close( fd->unix_fd );
          free( fd->unix_name );
      }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2735,7 +2544,7 @@ index 04688c5eb0d..07869ed311b 100644
</span>  }
  
  /* check if the desired access is possible without violating */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1681,12 +1690,16 @@ static struct fd *alloc_fd_object(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1681,12 +1686,16 @@ static struct fd *alloc_fd_object(void)
</span>      fd->poll_index = -1;
      fd->completion = NULL;
      fd->comp_flags = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2752,7 +2561,7 @@ index 04688c5eb0d..07869ed311b 100644
</span>      if ((fd->poll_index = add_poll_user( fd )) == -1)
      {
          release_object( fd );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1722,11 +1735,15 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1722,11 +1731,15 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
</span>      fd->completion = NULL;
      fd->comp_flags = 0;
      fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2768,7 +2577,7 @@ index 04688c5eb0d..07869ed311b 100644
</span>      return fd;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2131,6 +2148,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2131,6 +2144,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
</span>      if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
      fd->signaled = signaled;
      if (signaled) wake_up( fd->user, 0 );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2778,7 +2587,7 @@ index 04688c5eb0d..07869ed311b 100644
</span>  }
  
  /* check if events are pending and if yes return which one(s) */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2156,6 +2176,15 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2156,6 +2172,15 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
</span>      return ret;
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2794,18 +2603,6 @@ index 04688c5eb0d..07869ed311b 100644
</span>  int default_fd_get_poll_events( struct fd *fd )
  {
      int events = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/file.c b/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 8f6566a0077..74bb8336bbb 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -94,6 +94,7 @@ static const struct object_ops file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     file_get_fd,                  /* get_fd */
</span> diff --git a/server/file.h b/server/file.h
 index 3d7cdc460ff..db54555a883 100644
 --- a/server/file.h
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2818,66 +2615,6 @@ index 3d7cdc460ff..db54555a883 100644
</span>  extern int default_fd_get_poll_events( struct fd *fd );
  extern void default_poll_event( struct fd *fd, int event );
  extern void fd_cancel_async( struct fd *fd, struct async *async );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/handle.c b/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e65831b3b22..5a60a528ff3 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -126,6 +126,7 @@ static const struct object_ops handle_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                            /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                       /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                       /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/hook.c b/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c2d2823cd61..dfb210b9de6 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -81,6 +81,7 @@ static const struct object_ops hook_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mailslot.c b/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 61eceec94e2..573789b65f6 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -81,6 +81,7 @@ static const struct object_ops mailslot_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mailslot_get_fd,           /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -142,6 +143,7 @@ static const struct object_ops mail_writer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,               /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mail_writer_get_fd,         /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -207,6 +209,7 @@ static const struct object_ops mailslot_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                   /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                           /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                           /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                           /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                   /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                      /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                      /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -237,6 +240,7 @@ static const struct object_ops mailslot_device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                              /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                           /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                                   /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mailslot_device_file_get_fd,            /* get_fd */
</span> diff --git a/server/main.c b/server/main.c
 index 1248b92f24d..f5dcebe8d87 100644
 --- a/server/main.c
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2903,37 +2640,9 @@ index 1248b92f24d..f5dcebe8d87 100644
</span>      if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
      set_current_time();
      init_signals();
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mapping.c b/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 2bf45780375..476669ea0f4 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +67,7 @@ static const struct object_ops ranges_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,              /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -103,6 +104,7 @@ static const struct object_ops shared_map_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,              /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -176,6 +178,7 @@ static const struct object_ops mapping_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mapping_get_fd,              /* get_fd */
</span> diff --git a/server/msync.c b/server/msync.c
 new file mode 100644
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000000..58c3542b7fc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 00000000000..8715d38634f
</span> --- /dev/null
 +++ b/server/msync.c
 @@ -0,0 +1,991 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3546,7 +3255,6 @@ index 00000000000..58c3542b7fc
</span> +    no_add_queue,              /* add_queue */
 +    NULL,                      /* remove_queue */
 +    NULL,                      /* signaled */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msync_get_msync_idx,       /* get_msync_idx */
</span> +    NULL,                      /* satisfied */
 +    no_signal,                 /* signal */
 +    no_get_fd,                 /* get_fd */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3560,7 +3268,8 @@ index 00000000000..58c3542b7fc
</span> +    no_open_file,              /* open_file */
 +    no_kernel_obj_list,        /* get_kernel_obj_list */
 +    no_close_handle,           /* close_handle */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msync_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msync_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msync_get_msync_idx        /* get_msync_idx */
</span> +};
 +
 +static void msync_dump( struct object *obj, int verbose )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3970,97 +3679,45 @@ index 00000000000..000aa48c53d
</span> +extern void msync_set_event( struct msync *msync );
 +extern void msync_reset_event( struct msync *msync );
 +extern void msync_abandon_mutexes( struct thread *thread );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mutex.c b/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index af0efe72132..0f6d013a119 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -73,6 +73,7 @@ static const struct object_ops mutex_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span> diff --git a/server/named_pipe.c b/server/named_pipe.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 59a90c36663..903c4aaf2ec 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 59a90c36663..7110a3ddfcf 100644
</span> --- a/server/named_pipe.c
 +++ b/server/named_pipe.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -119,6 +119,7 @@ static const struct object_ops named_pipe_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -167,6 +168,7 @@ static const struct object_ops pipe_server_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pipe_end_get_fd,              /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -211,6 +213,7 @@ static const struct object_ops pipe_client_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pipe_end_get_fd,              /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -258,6 +261,7 @@ static const struct object_ops named_pipe_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -289,6 +293,7 @@ static const struct object_ops named_pipe_device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                               /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                            /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     named_pipe_device_file_get_fd,           /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/object.c b/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b1665fb5372..55727c2e118 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -108,6 +108,7 @@ static const struct object_ops apc_reserve_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,               /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -132,6 +133,7 @@ static const struct object_ops completion_reserve_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,              /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -180,7 +180,8 @@ static const struct object_ops pipe_server_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pipe_server_open_file,        /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,           /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     async_close_obj_handle,       /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    pipe_server_destroy           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pipe_server_destroy,          /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops pipe_server_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -224,7 +225,8 @@ static const struct object_ops pipe_client_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                 /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,           /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     async_close_obj_handle,       /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    pipe_end_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pipe_end_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops pipe_client_fd_ops =
</span> diff --git a/server/object.h b/server/object.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 6222e3352ed..eabef90097d 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 6222e3352ed..3d8b9e992ce 100644
</span> --- a/server/object.h
 +++ b/server/object.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -78,6 +78,8 @@ struct object_ops
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     void (*remove_queue)(struct object *,struct wait_queue_entry *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* is object signaled? */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int  (*signaled)(struct object *,struct wait_queue_entry *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -107,6 +107,8 @@ struct object_ops
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int (*close_handle)(struct object *,struct process *,obj_handle_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* destroy on refcount == 0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     void (*destroy)(struct object *);
</span> +    /* return the msync shm idx for this object */
 +    unsigned int (*get_msync_idx)(struct object *, enum msync_type *type);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* wait satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     void (*satisfied)(struct object *,struct wait_queue_entry *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* signal an object */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct object
</span> diff --git a/server/process.c b/server/process.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 49f5c75005f..1477c2587a7 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 49f5c75005f..11d684746f0 100644
</span> --- a/server/process.c
 +++ b/server/process.c
 @@ -63,6 +63,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4079,39 +3736,25 @@ index 49f5c75005f..1477c2587a7 100644
</span>  static void terminate_process( struct process *process, struct thread *skip, int exit_code );
  
  static const struct object_ops process_ops =
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -105,6 +107,7 @@ static const struct object_ops process_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                   /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     process_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    process_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                   /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -156,6 +159,7 @@ static const struct object_ops startup_info_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     startup_info_signaled,         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -217,6 +221,7 @@ static const struct object_ops job_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     job_signaled,                  /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -685,6 +690,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -118,7 +120,8 @@ static const struct object_ops process_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     process_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,             /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    process_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    process_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    process_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops process_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -684,6 +687,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     process->rawinput_mouse  = NULL;
</span>      process->rawinput_kbd    = NULL;
      memset( &process->image_info, 0, sizeof(process->image_info) );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     list_init( &process->rawinput_entry );
</span> +    process->msync_idx       = 0;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     list_init( &process->rawinput_entry );
</span>      list_init( &process->kernel_object );
      list_init( &process->thread_list );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     list_init( &process->locks );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -735,6 +741,9 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -735,6 +739,9 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span>      if (!process->handles || !process->token) goto error;
      process->session_id = token_get_session_id( process->token );
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4121,7 +3764,7 @@ index 49f5c75005f..1477c2587a7 100644
</span>      set_fd_events( process->msg_fd, POLLIN );  /* start listening to events */
      return process;
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -783,6 +792,7 @@ static void process_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -783,6 +790,7 @@ static void process_destroy( struct object *obj )
</span>      free( process->rawinput_devices );
      free( process->dir_cache );
      free( process->image );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4129,7 +3772,7 @@ index 49f5c75005f..1477c2587a7 100644
</span>  }
  
  /* dump a process on stdout for debugging purposes */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -800,6 +810,13 @@ static int process_signaled( struct object *obj, struct wait_queue_entry *entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -800,6 +808,13 @@ static int process_signaled( struct object *obj, struct wait_queue_entry *entry
</span>      return !process->running_threads;
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4218,7 +3861,7 @@ index 9ecb14cbac4..09de9793118 100644
</span> +    unsigned int shm_idx;
 +@END
 diff --git a/server/queue.c b/server/queue.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 2641a9ba037..e4b58406fdc 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 2641a9ba037..3911b58eea2 100644
</span> --- a/server/queue.c
 +++ b/server/queue.c
 @@ -44,6 +44,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4246,23 +3889,17 @@ index 2641a9ba037..e4b58406fdc 100644
</span>  static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry );
  static void msg_queue_destroy( struct object *obj );
  static void msg_queue_poll_event( struct fd *fd, int event );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -164,6 +168,7 @@ static const struct object_ops msg_queue_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_add_queue,       /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_remove_queue,    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msg_queue_get_msync_idx,   /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_satisfied,       /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -201,6 +206,7 @@ static const struct object_ops thread_input_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -312,6 +318,8 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -177,7 +181,8 @@ static const struct object_ops msg_queue_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,        /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    msg_queue_destroy          /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msg_queue_destroy,         /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msg_queue_get_msync_idx    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops msg_queue_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -312,6 +317,8 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span>          queue->hooks           = NULL;
          queue->last_get_msg    = current_time;
          queue->keystate_lock   = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4271,7 +3908,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>          list_init( &queue->send_result );
          list_init( &queue->callback_result );
          list_init( &queue->pending_timers );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -334,6 +342,9 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -334,6 +341,9 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span>          }
          SHARED_WRITE_END;
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4281,17 +3918,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>          thread->queue = queue;
  
          if ((desktop = get_thread_desktop( thread, 0 )))
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -748,6 +759,9 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (queue->keystate_lock) unlock_input_keystate( queue->input );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         queue->keystate_lock = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (do_msync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        msync_clear( &queue->obj );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* check if message is matched by the filter */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1227,6 +1241,10 @@ static int is_queue_hung( struct msg_queue *queue )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1227,6 +1237,10 @@ static int is_queue_hung( struct msg_queue *queue )
</span>          if (get_wait_queue_thread(entry)->queue == queue)
              return 0;  /* thread is waiting on queue -> not hung */
      }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4302,7 +3929,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>      return 1;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1281,6 +1299,13 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1281,6 +1295,13 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
</span>      return ret || is_signaled( queue );
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4316,7 +3943,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>  static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry )
  {
      struct msg_queue *queue = (struct msg_queue *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1337,6 +1362,8 @@ static void msg_queue_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1337,6 +1358,8 @@ static void msg_queue_destroy( struct object *obj )
</span>      if (queue->hooks) release_object( queue->hooks );
      if (queue->fd) release_object( queue->fd );
      if (queue->shared) free_shared_object( queue->shared );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4325,7 +3952,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>  }
  
  static void msg_queue_poll_event( struct fd *fd, int event )
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3115,6 +3142,9 @@ DECL_HANDLER(set_queue_mask)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3115,6 +3138,9 @@ DECL_HANDLER(set_queue_mask)
</span>              }
              else wake_up( &queue->obj, 0 );
          }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4335,7 +3962,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>      }
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3135,6 +3165,9 @@ DECL_HANDLER(get_queue_status)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3135,6 +3161,9 @@ DECL_HANDLER(get_queue_status)
</span>              shared->changed_bits &= ~req->clear_bits;
          }
          SHARED_WRITE_END;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4345,7 +3972,7 @@ index 2641a9ba037..e4b58406fdc 100644
</span>      }
      else reply->wake_bits = reply->changed_bits = 0;
  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3392,6 +3425,11 @@ DECL_HANDLER(get_message)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3392,6 +3421,11 @@ DECL_HANDLER(get_message)
</span>      SHARED_WRITE_END;
  
      set_error( STATUS_PENDING );  /* FIXME */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4357,54 +3984,25 @@ index 2641a9ba037..e4b58406fdc 100644
</span>  }
  
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -4164,6 +4202,23 @@ DECL_HANDLER(update_rawinput_devices)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4182,3 +4216,18 @@ DECL_HANDLER(set_keyboard_repeat)
</span>  
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     release_object( desktop );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +DECL_HANDLER(msync_msgwait)
 +{
 +    struct msg_queue *queue = get_current_queue();
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const queue_shm_t *queue_shm;
</span> +
 +    if (!queue) return;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    queue_shm = queue->shared;
</span> +    queue->msync_in_msgwait = req->in_msgwait;
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (current->process->idle_event && !(queue_shm->wake_mask & QS_SMRESULT))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (current->process->idle_event && !(queue->shared->wake_mask & QS_SMRESULT))
</span> +        set_event( current->process->idle_event );
 +
 +    /* and start/stop waiting on the driver */
 +    if (queue->fd)
 +        set_fd_events( queue->fd, req->in_msgwait ? POLLIN : 0 );
 +}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DECL_HANDLER(set_keyboard_repeat)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct desktop *desktop;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/registry.c b/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index cc9a33fff1d..1aa587faee7 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -180,6 +180,7 @@ static const struct object_ops key_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,            /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/request.c b/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index dabcea68309..0ffc4a0a726 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -90,6 +90,7 @@ static const struct object_ops master_socket_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                  /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span> diff --git a/server/request.h b/server/request.h
 index 0ec527f2b4f..0144a9bbf4b 100644
 --- a/server/request.h
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4468,84 +4066,8 @@ index 0ec527f2b4f..0144a9bbf4b 100644
</span>  
  #endif  /* WANT_REQUEST_HANDLERS */
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/semaphore.c b/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 53b42a886df..bbcbc831793 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -70,6 +70,7 @@ static const struct object_ops semaphore_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                     /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/serial.c b/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 209f2e9174e..62eafa87408 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -91,6 +91,7 @@ static const struct object_ops serial_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     serial_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/signal.c b/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 19b76d44c16..57415604d07 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -62,6 +62,7 @@ static const struct object_ops handler_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/sock.c b/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index d2ec882554f..53d73e6de4d 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -471,6 +471,7 @@ static const struct object_ops sock_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                    /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     sock_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3599,6 +3600,7 @@ static const struct object_ops ifchange_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,            /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ifchange_get_fd,         /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3820,6 +3822,7 @@ static const struct object_ops socket_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,               /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/symlink.c b/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index dd28efd3a75..d6a51f0091d 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -71,6 +71,7 @@ static const struct object_ops symlink_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span> diff --git a/server/thread.c b/server/thread.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index f3880eebedb..7cec9704f55 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f3880eebedb..78c635fc524 100644
</span> --- a/server/thread.c
 +++ b/server/thread.c
 @@ -50,6 +50,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4556,23 +4078,7 @@ index f3880eebedb..7cec9704f55 100644
</span>  
  
  /* thread queues */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -96,6 +97,7 @@ static const struct object_ops thread_apc_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                  /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_apc_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -138,6 +140,7 @@ static const struct object_ops context_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                  /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     context_signaled,           /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -174,6 +177,7 @@ struct type_descr thread_type =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -174,6 +175,7 @@ struct type_descr thread_type =
</span>  
  static void dump_thread( struct object *obj, int verbose );
  static int thread_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4580,15 +4086,17 @@ index f3880eebedb..7cec9704f55 100644
</span>  static unsigned int thread_map_access( struct object *obj, unsigned int access );
  static void thread_poll_event( struct fd *fd, int event );
  static struct list *thread_get_kernel_obj_list( struct object *obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -187,6 +191,7 @@ static const struct object_ops thread_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                  /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    thread_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -226,6 +231,8 @@ static inline void init_thread_structure( struct thread *thread )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -200,7 +202,8 @@ static const struct object_ops thread_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,               /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     thread_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,            /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    destroy_thread              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    destroy_thread,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    thread_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops thread_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -226,6 +229,8 @@ static inline void init_thread_structure( struct thread *thread )
</span>      thread->context         = NULL;
      thread->teb             = 0;
      thread->entry_point     = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4597,7 +4105,7 @@ index f3880eebedb..7cec9704f55 100644
</span>      thread->system_regs     = 0;
      thread->queue           = NULL;
      thread->wait            = NULL;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -373,6 +380,12 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -373,6 +378,12 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
</span>          }
      }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4610,7 +4118,7 @@ index f3880eebedb..7cec9704f55 100644
</span>      set_fd_events( thread->request_fd, POLLIN );  /* start listening to events */
      add_process_thread( thread->process, thread );
      return thread;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -452,6 +465,12 @@ static void destroy_thread( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -452,6 +463,12 @@ static void destroy_thread( struct object *obj )
</span>      release_object( thread->process );
      if (thread->id) free_ptid( thread->id );
      if (thread->token) release_object( thread->token );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4623,7 +4131,7 @@ index f3880eebedb..7cec9704f55 100644
</span>  }
  
  /* dump a thread on stdout for debugging purposes */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -470,6 +489,13 @@ static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -470,6 +487,13 @@ static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
</span>      return (mythread->state == TERMINATED);
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4637,15 +4145,7 @@ index f3880eebedb..7cec9704f55 100644
</span>  static unsigned int thread_map_access( struct object *obj, unsigned int access )
  {
      access = default_map_access( obj, access );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -522,6 +548,7 @@ static struct thread_apc *create_apc( struct object *owner, const apc_call_t *ca
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         apc->result.type = APC_NONE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (owner) grab_object( owner );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return apc;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1065,6 +1092,9 @@ void wake_up( struct object *obj, int max )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1065,6 +1089,9 @@ void wake_up( struct object *obj, int max )
</span>      struct list *ptr;
      int ret;
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4655,7 +4155,7 @@ index f3880eebedb..7cec9704f55 100644
</span>      LIST_FOR_EACH( ptr, &obj->wait_queue )
      {
          struct wait_queue_entry *entry = LIST_ENTRY( ptr, struct wait_queue_entry, entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1149,8 +1179,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1149,8 +1176,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
</span>      grab_object( apc );
      list_add_tail( queue, &apc->entry );
      if (!list_prev( queue, &apc->entry ))  /* first one */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4668,7 +4168,7 @@ index f3880eebedb..7cec9704f55 100644
</span>      return 1;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1196,6 +1230,10 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1196,6 +1227,10 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system
</span>          apc = LIST_ENTRY( ptr, struct thread_apc, entry );
          list_remove( ptr );
      }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4679,7 +4179,7 @@ index f3880eebedb..7cec9704f55 100644
</span>      return apc;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1291,6 +1329,8 @@ void kill_thread( struct thread *thread, int violent_death )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1291,6 +1326,8 @@ void kill_thread( struct thread *thread, int violent_death )
</span>      }
      kill_console_processes( thread, 0 );
      abandon_mutexes( thread );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4702,7 +4202,7 @@ index 3448f332b0b..44a4bab1148 100644
</span>      struct msg_queue      *queue;         /* message queue */
      struct thread_wait    *wait;          /* current wait condition if sleeping */
 diff --git a/server/timer.c b/server/timer.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 96dc9d00ca1..75756b27c66 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 96dc9d00ca1..2b3880dbb31 100644
</span> --- a/server/timer.c
 +++ b/server/timer.c
 @@ -35,6 +35,7 @@
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4726,25 +4226,28 @@ index 96dc9d00ca1..75756b27c66 100644
</span>  static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry );
  static void timer_destroy( struct object *obj );
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +79,7 @@ static const struct object_ops timer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     timer_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    timer_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     timer_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -110,6 +114,9 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -89,7 +92,8 @@ static const struct object_ops timer_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,        /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    timer_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    timer_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    timer_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -110,6 +114,10 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
</span>              timer->period   = 0;
              timer->timeout  = NULL;
              timer->thread   = NULL;
<span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +            if (do_msync())
 +                timer->msync_idx = msync_alloc_shm( 0, 0 );
 +
          }
      }
      return timer;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -181,6 +188,9 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -181,6 +189,9 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
</span>      {
          period = 0;  /* period doesn't make any sense for a manual timer */
          timer->signaled = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4754,7 +4257,7 @@ index 96dc9d00ca1..75756b27c66 100644
</span>      }
      timer->when     = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
      timer->period   = period;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -208,6 +218,13 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -208,6 +219,13 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
</span>      return timer->signaled;
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4768,7 +4271,7 @@ index 96dc9d00ca1..75756b27c66 100644
</span>  static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry )
  {
      struct timer *timer = (struct timer *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -222,6 +239,8 @@ static void timer_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -222,6 +240,8 @@ static void timer_destroy( struct object *obj )
</span>  
      if (timer->timeout) remove_timeout_user( timer->timeout );
      if (timer->thread) release_object( timer->thread );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4777,18 +4280,6 @@ index 96dc9d00ca1..75756b27c66 100644
</span>  }
  
  /* create a timer */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/token.c b/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 48ee1eca8fe..e3990874159 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -145,6 +145,7 @@ static const struct object_ops token_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,              /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span> diff --git a/server/trace.c b/server/trace.c
 index 5fd69aa420b..8a6825b0b84 100644
 --- a/server/trace.c
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4893,35 +4384,3 @@ index 5fd69aa420b..8a6825b0b84 100644
</span>  };
  
  static const struct
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/window.c b/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 7b2a146f406..b646203022f 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -107,6 +107,7 @@ static const struct object_ops window_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,             /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/winstation.c b/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 1cd7d325fd1..4106d014503 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +76,7 @@ static const struct object_ops winstation_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -116,6 +117,7 @@ static const struct object_ops desktop_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_add_queue,                 /* add_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/emulators/wine-devel/files/1001-staging-msync.diff b/emulators/wine-devel/files/1001-staging-msync.diff
</span><span style='display:block; white-space:pre;color:#808080;'>index 3d9c5db42c8..d9680e0c323 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/emulators/wine-devel/files/1001-staging-msync.diff
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/emulators/wine-devel/files/1001-staging-msync.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,100 +1,41 @@
</span> diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 78b3fdf94aa..061c730bf63 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f9a15d28ed2..33c11b1a63c 100644
</span> --- a/dlls/ntdll/Makefile.in
 +++ b/dlls/ntdll/Makefile.in
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -50,6 +50,7 @@ SOURCES = \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -49,6 +49,7 @@ SOURCES = \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   unix/debug.c \
</span>   unix/env.c \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        unix/esync.c \
</span>   unix/file.c \
 +      unix/msync.c \
        unix/loader.c \
        unix/loadorder.c \
        unix/process.c \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 86809b610c7..55c15e02c09 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/dlls/ntdll/unix/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/dlls/ntdll/unix/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -51,6 +51,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "unix_private.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "msync.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- WINE_DEFAULT_DEBUG_CHANNEL(esync);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -60,13 +61,16 @@ int do_esync(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     static int do_esync_cached = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync_cached == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC"));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC")) && !do_msync();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return do_esync_cached;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     static int once;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (!once++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        FIXME("eventfd not supported on this platform.\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (getenv("WINEESYNC") && atoi(getenv("WINEESYNC")) && !do_msync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            FIXME("eventfd not supported on this platform.\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -571,6 +575,9 @@ NTSTATUS esync_reset_event( HANDLE handle )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if ((ret = get_object( handle, &obj ))) return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event = obj->shm;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (obj->type != ESYNC_MANUAL_EVENT && obj->type != ESYNC_AUTO_EVENT)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return STATUS_OBJECT_TYPE_MISMATCH;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (obj->type == ESYNC_MANUAL_EVENT)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         /* Acquire the spinlock. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -861,7 +868,7 @@ static NTSTATUS __esync_wait_objects( unsigned int count, const HANDLE *handles,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    if (objs[count - 1] && objs[count - 1]->type == ESYNC_QUEUE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (count && objs[count - 1] && objs[count - 1]->type == ESYNC_QUEUE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         msgwait = TRUE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (has_esync && has_server)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -890,7 +897,7 @@ static NTSTATUS __esync_wait_objects( unsigned int count, const HANDLE *handles,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    if (wait_any || count == 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (wait_any || count <= 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         /* Try to check objects now, so we can obviate poll() at least. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         for (i = 0; i < count; i++)
</span> diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index ecc26f3cceb..8784882161e 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0dfee19f714..e4d3d3c8e99 100644
</span> --- a/dlls/ntdll/unix/loader.c
 +++ b/dlls/ntdll/unix/loader.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -91,6 +91,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -90,6 +90,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "winioctl.h"
</span>  #include "winternl.h"
  #include "unix_private.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  #include "wine/list.h"
  #include "ntsyscalls.h"
  #include "wine/debug.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1901,6 +1902,7 @@ static void start_main_thread(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1900,6 +1901,7 @@ static void start_main_thread(void)
</span>      signal_alloc_thread( teb );
      dbg_init();
      startup_info_size = server_init_process();
 +    msync_init();
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     esync_init();
</span>      virtual_map_user_shared_data();
      init_cpu_info();
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     init_files();
</span> diff --git a/dlls/ntdll/unix/msync.c b/dlls/ntdll/unix/msync.c
 new file mode 100644
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000000..2eef30dd0f2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 00000000000..f5f1f0aa82d
</span> --- /dev/null
 +++ b/dlls/ntdll/unix/msync.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,1689 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,1695 @@
</span> +/*
 + * mach semaphore-based synchronization objects
 + *
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1128,6 +1069,9 @@ index 00000000000..2eef30dd0f2
</span> +    if ((ret = get_object( handle, &obj ))) return ret;
 +    event = obj->shm;
 +
<span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (obj->type != MSYNC_MANUAL_EVENT && obj->type != MSYNC_AUTO_EVENT)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return STATUS_OBJECT_TYPE_MISMATCH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    current = __atomic_exchange_n( &event->signaled, 0, __ATOMIC_SEQ_CST );
 +
 +    if (prev) *prev = current;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1147,6 +1091,9 @@ index 00000000000..2eef30dd0f2
</span> +    if ((ret = get_object( handle, &obj ))) return ret;
 +    event = obj->shm;
 +
<span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (obj->type != MSYNC_MANUAL_EVENT && obj->type != MSYNC_AUTO_EVENT)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return STATUS_OBJECT_TYPE_MISMATCH;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    /* This isn't really correct; an application could miss the write.
 +     * Unfortunately we can't really do much better. Fortunately this is rarely
 +     * used (and publicly deprecated). */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1841,180 +1788,184 @@ index 00000000000..3e6eb2c8b1e
</span> +extern NTSTATUS msync_signal_and_wait( HANDLE signal, HANDLE wait,
 +    BOOLEAN alertable, const LARGE_INTEGER *timeout );
 diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index bc723131d05..0cb08b1e505 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index cc09ab79cff..e1227c12956 100644
</span> --- a/dlls/ntdll/unix/server.c
 +++ b/dlls/ntdll/unix/server.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -84,6 +84,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -83,6 +83,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "wine/server.h"
</span>  #include "wine/debug.h"
  #include "unix_private.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  #include "ddk/wdm.h"
  
  WINE_DEFAULT_DEBUG_CHANNEL(server);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1899,6 +1900,9 @@ NTSTATUS WINAPI NtClose( HANDLE handle )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1898,6 +1899,9 @@ NTSTATUS WINAPI NtClose( HANDLE handle )
</span>       * retrieve it again */
      fd = remove_fd_from_cache( handle );
  
 +    if (do_msync())
 +        msync_close( handle );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_close( handle );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( close_handle )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span> diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index ead6d3bab80..0ffbb7bac2c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 80f82c18730..2781384229e 100644
</span> --- a/dlls/ntdll/unix/sync.c
 +++ b/dlls/ntdll/unix/sync.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -67,6 +67,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -66,6 +66,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "wine/server.h"
</span>  #include "wine/debug.h"
  #include "unix_private.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  WINE_DEFAULT_DEBUG_CHANNEL(sync);
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -316,6 +317,9 @@ NTSTATUS WINAPI NtCreateSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJ
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -315,6 +316,9 @@ NTSTATUS WINAPI NtCreateSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJ
</span>      if (max <= 0 || initial < 0 || initial > max) return STATUS_INVALID_PARAMETER;
      if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
  
 +    if (do_msync())
 +        return msync_create_semaphore( handle, access, attr, initial, max );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_create_semaphore( handle, access, attr, initial, max );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -344,6 +348,9 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( create_semaphore )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->access  = access;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -339,6 +343,10 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned int ret;
</span>  
      *handle = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        return msync_open_semaphore( handle, access, attr );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_open_semaphore( handle, access, attr );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ((ret = validate_open_object_attributes( attr ))) return ret;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -383,6 +390,9 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( open_semaphore )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -375,6 +383,9 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla
</span>  
      if (len != sizeof(SEMAPHORE_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
  
 +    if (do_msync())
 +        return msync_query_semaphore( handle, info, ret_len );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_query_semaphore( handle, info, ret_len );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -408,6 +418,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, ULONG *previous
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( query_semaphore )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -397,6 +408,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, ULONG *previous
</span>  {
      unsigned int ret;
  
 +    if (do_msync())
 +        return msync_release_semaphore( handle, count, previous );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_release_semaphore( handle, count, previous );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( release_semaphore )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -423,6 +437,10 @@ NTSTATUS WINAPI NtCreateEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -438,6 +451,9 @@ NTSTATUS WINAPI NtCreateEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_
</span>      *handle = 0;
      if (type != NotificationEvent && type != SynchronizationEvent) return STATUS_INVALID_PARAMETER;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        return msync_create_event( handle, access, attr, type, state );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_create_event( handle, access, attr, type, state );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -469,6 +485,9 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( create_event )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -451,6 +469,9 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT
</span>      *handle = 0;
      if ((ret = validate_open_object_attributes( attr ))) return ret;
  
 +    if (do_msync())
 +        return msync_open_event( handle, access, attr );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_open_event( handle, access, attr );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -495,6 +514,9 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* This comment is a dummy to make sure this patch applies in the right place. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( open_event )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->access     = access;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -473,6 +494,9 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, LONG *prev_state )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span>      unsigned int ret;
  
 +    if (do_msync())
 +        return msync_set_event( handle, prev_state );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_set_event( handle );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -518,6 +540,9 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* This comment is a dummy to make sure this patch applies in the right place. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( event_op )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -492,6 +516,10 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, LONG *prev_state )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span>      unsigned int ret;
  
 +    if (do_msync())
 +        return msync_reset_event( handle, prev_state );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_reset_event( handle );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -551,6 +576,9 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( event_op )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -521,6 +549,9 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, LONG *prev_state )
</span>  {
      unsigned int ret;
  
 +    if (do_msync())
 +        return msync_pulse_event( handle, prev_state );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_pulse_event( handle );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -585,6 +613,9 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( event_op )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -552,6 +583,9 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class,
</span>  
      if (len != sizeof(EVENT_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
  
 +    if (do_msync())
 +        return msync_query_event( handle, info, ret_len );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_query_event( handle, info, ret_len );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -615,6 +646,9 @@ NTSTATUS WINAPI NtCreateMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( query_event )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -578,6 +612,10 @@ NTSTATUS WINAPI NtCreateMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct object_attributes *objattr;
</span>  
      *handle = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        return msync_create_mutex( handle, access, attr, owned );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_create_mutex( handle, access, attr, owned );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -645,6 +679,9 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( create_mutex )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -605,6 +643,9 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A
</span>      *handle = 0;
      if ((ret = validate_open_object_attributes( attr ))) return ret;
  
 +    if (do_msync())
 +        return msync_open_mutex( handle, access, attr );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_open_mutex( handle, access, attr );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -670,6 +707,9 @@ NTSTATUS WINAPI NtReleaseMutant( HANDLE handle, LONG *prev_count )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( open_mutex )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->access  = access;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -627,6 +668,9 @@ NTSTATUS WINAPI NtReleaseMutant( HANDLE handle, LONG *prev_count )
</span>  {
      unsigned int ret;
  
 +    if (do_msync())
 +        return msync_release_mutex( handle, prev_count );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_release_mutex( handle, prev_count );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -703,6 +743,9 @@ NTSTATUS WINAPI NtQueryMutant( HANDLE handle, MUTANT_INFORMATION_CLASS class,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( release_mutex )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -657,6 +701,9 @@ NTSTATUS WINAPI NtQueryMutant( HANDLE handle, MUTANT_INFORMATION_CLASS class,
</span>  
      if (len != sizeof(MUTANT_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
  
 +    if (do_msync())
 +        return msync_query_mutex( handle, info, ret_len );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_query_mutex( handle, info, ret_len );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1626,6 +1669,13 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SERVER_START_REQ( query_mutex )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         req->handle = wine_server_obj_handle( handle );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1577,6 +1624,13 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, BO
</span>  
      if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2025,20 +1976,20 @@ index ead6d3bab80..0ffbb7bac2c 100644
</span> +            return ret;
 +    }
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         NTSTATUS ret = esync_wait_objects( count, handles, wait_any, alertable, timeout );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1658,6 +1708,9 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (alertable) flags |= SELECT_ALERTABLE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1602,6 +1656,9 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE signal, HANDLE wait,
</span>      select_op_t select_op;
      UINT flags = SELECT_INTERRUPTIBLE;
  
 +    if (do_msync())
 +        return msync_signal_and_wait( signal, wait, alertable, timeout );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return esync_signal_and_wait( signal, wait, alertable, timeout );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (!signal) return STATUS_INVALID_HANDLE;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1701,7 +1754,24 @@ NTSTATUS WINAPI NtYieldExecution(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (alertable) flags |= SELECT_ALERTABLE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1642,7 +1699,17 @@ NTSTATUS WINAPI NtYieldExecution(void)
</span>  NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeout )
  {
      /* if alertable, we need to query the server */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2052,50 +2003,43 @@ index ead6d3bab80..0ffbb7bac2c 100644
</span> +                return ret;
 +        }
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            NTSTATUS ret = esync_wait_objects( 0, NULL, TRUE, TRUE, timeout );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (ret != STATUS_NOT_IMPLEMENTED)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span> +        return server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
 +    }
  
      if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE)  /* sleep forever */
      {
 diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 4419e3feda3..dc7402ceee3 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index aed2b9792f4..6152572e4d7 100644
</span> --- a/dlls/ntdll/unix/unix_private.h
 +++ b/dlls/ntdll/unix/unix_private.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -104,6 +104,8 @@ struct ntdll_thread_data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -103,6 +103,8 @@ struct ntdll_thread_data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span>      void              *cpu_data[16];  /* reserved for CPU-specific data */
      void              *kernel_stack;  /* stack for thread startup and kernel syscalls */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                esync_apc_fd;  /* fd to wait on for user APCs */
</span> +    int               *msync_apc_addr;
 +    unsigned int       msync_apc_idx;
      int                request_fd;    /* fd for sending server requests */
      int                reply_fd;      /* fd for receiving server replies */
      int                wait_fd[2];    /* fd for sleeping server requests */
 diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index c4e30fbbbef..bafb959345e 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b448a6e0b6a..9ed7e037f8d 100644
</span> --- a/dlls/ntdll/unix/virtual.c
 +++ b/dlls/ntdll/unix/virtual.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3728,6 +3728,8 @@ static TEB *init_teb( void *ptr, BOOL is_wow )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3727,6 +3727,8 @@ static TEB *init_teb( void *ptr, BOOL is_wow )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
</span>      teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
      thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_data->esync_apc_fd = -1;
</span> +    thread_data->msync_apc_addr = NULL;
 +    thread_data->msync_apc_idx = 0;
      thread_data->request_fd = -1;
      thread_data->reply_fd   = -1;
      thread_data->wait_fd[0] = -1;
 diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 47d4edbabf2..78b6aa34322 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 060056b0509..4694ad70f2a 100644
</span> --- a/include/wine/server_protocol.h
 +++ b/include/wine/server_protocol.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -5976,6 +5976,92 @@ struct get_esync_apc_fd_reply
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct reply_header __header;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5894,6 +5894,92 @@ struct set_keyboard_repeat_reply
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char __pad_12[4];
</span>  };
  
 +enum msync_type
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2187,10 +2131,10 @@ index 47d4edbabf2..78b6aa34322 100644
</span>  
  enum request
  {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -6276,6 +6362,11 @@ enum request
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     REQ_esync_msgwait,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -6189,6 +6275,11 @@ enum request
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     REQ_resume_process,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     REQ_get_next_thread,
</span>      REQ_set_keyboard_repeat,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     REQ_get_esync_apc_fd,
</span> +    REQ_create_msync,
 +    REQ_open_msync,
 +    REQ_get_msync_idx,
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2199,10 +2143,10 @@ index 47d4edbabf2..78b6aa34322 100644
</span>      REQ_NB_REQUESTS
  };
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -6580,6 +6671,11 @@ union generic_request
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct esync_msgwait_request esync_msgwait_request;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -6488,6 +6579,11 @@ union generic_request
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct resume_process_request resume_process_request;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct get_next_thread_request get_next_thread_request;
</span>      struct set_keyboard_repeat_request set_keyboard_repeat_request;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct get_esync_apc_fd_request get_esync_apc_fd_request;
</span> +    struct create_msync_request create_msync_request;
 +    struct open_msync_request open_msync_request;
 +    struct get_msync_idx_request get_msync_idx_request;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2211,10 +2155,10 @@ index 47d4edbabf2..78b6aa34322 100644
</span>  };
  union generic_reply
  {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -6882,11 +6978,16 @@ union generic_reply
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct esync_msgwait_reply esync_msgwait_reply;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -6785,11 +6881,16 @@ union generic_reply
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct resume_process_reply resume_process_reply;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct get_next_thread_reply get_next_thread_reply;
</span>      struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct get_esync_apc_fd_reply get_esync_apc_fd_reply;
</span> +    struct create_msync_reply create_msync_reply;
 +    struct open_msync_reply open_msync_reply;
 +    struct get_msync_idx_reply get_msync_idx_reply;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2225,15 +2169,15 @@ index 47d4edbabf2..78b6aa34322 100644
</span>  /* ### protocol_version begin ### */
  
 -#define SERVER_PROTOCOL_VERSION 848
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SERVER_PROTOCOL_VERSION 852
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SERVER_PROTOCOL_VERSION 851
</span>  
  /* ### protocol_version end ### */
  
 diff --git a/server/Makefile.in b/server/Makefile.in
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 87103cb2002..85b7b8f6693 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 4468ff018c4..f848f51adc9 100644
</span> --- a/server/Makefile.in
 +++ b/server/Makefile.in
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -15,6 +15,7 @@ SOURCES = \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -14,6 +14,7 @@ SOURCES = \
</span>   event.c \
        fd.c \
        file.c \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2241,181 +2185,77 @@ index 87103cb2002..85b7b8f6693 100644
</span>   handle.c \
        hook.c \
        mach.c \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/async.c b/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 2377c737e98..5b0f09d7799 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/async.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -79,6 +79,7 @@ static const struct object_ops async_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     async_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     async_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -700,6 +701,7 @@ static const struct object_ops iosb_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/atom.c b/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index d9824de8eac..d99f10d6f19 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/atom.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -80,6 +80,7 @@ static const struct object_ops atom_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span> diff --git a/server/change.c b/server/change.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 682c7f724f0..f9ee9ef6329 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 50e0b7520f1..6628f52cf84 100644
</span> --- a/server/change.c
 +++ b/server/change.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -113,6 +113,7 @@ static const struct object_ops dir_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_get_esync_fd,  /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx, /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     dir_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/clipboard.c b/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0df7fd2f18e..ffc8ef20869 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/clipboard.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -77,6 +77,7 @@ static const struct object_ops clipboard_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/completion.c b/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 9093132efac..6d82b022599 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/completion.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -168,6 +168,7 @@ static const struct object_ops completion_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     completion_signaled,       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -125,7 +125,8 @@ static const struct object_ops dir_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,             /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,       /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     dir_close_handle,         /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    dir_destroy               /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    dir_destroy,              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx  /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static int dir_get_poll_events( struct fd *fd );
</span> diff --git a/server/console.c b/server/console.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index dbd4a97459c..2b023546907 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b64283baf4a..a9d9687dbf1 100644
</span> --- a/server/console.c
 +++ b/server/console.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -42,6 +42,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -41,6 +41,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "wincon.h"
</span>  #include "winternl.h"
  #include "wine/condrv.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  struct screen_buffer;
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -83,6 +84,7 @@ static const struct object_ops console_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_signaled,                 /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_get_fd,                   /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -142,12 +144,14 @@ struct console_server
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                   term_fd;     /* UNIX terminal fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct termios        termios;     /* original termios */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                   esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -139,11 +140,13 @@ struct console_server
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned int          once_input : 1; /* flag if input thread has already been requested */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int                   term_fd;        /* UNIX terminal fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct termios        termios;        /* original termios */
</span> +    unsigned int          msync_idx;
  };
  
  static void console_server_dump( struct object *obj, int verbose );
  static void console_server_destroy( struct object *obj );
  static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int console_server_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int console_server_get_msync_idx( struct object *obj, enum msync_type *type );
  static struct fd *console_server_get_fd( struct object *obj );
  static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
                                                  unsigned int attr, struct object *root );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -163,6 +167,7 @@ static const struct object_ops console_server_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_server_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_server_get_esync_fd,      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    console_server_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_server_get_fd,            /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -233,6 +238,7 @@ static const struct object_ops screen_buffer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     screen_buffer_get_fd,             /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -283,6 +289,7 @@ static const struct object_ops console_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -321,6 +328,7 @@ static const struct object_ops console_input_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_input_get_fd,             /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -379,6 +387,7 @@ static const struct object_ops console_output_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_output_get_fd,            /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -438,6 +447,7 @@ static const struct object_ops console_connection_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     console_connection_get_fd,        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -600,8 +610,13 @@ static void disconnect_console_server( struct console_server *server )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -171,7 +174,8 @@ static const struct object_ops console_server_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     console_server_open_file,         /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,               /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,                  /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    console_server_destroy            /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    console_server_destroy,           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    console_server_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -590,6 +594,10 @@ static void disconnect_console_server( struct console_server *server )
</span>          list_remove( &call->entry );
          console_host_ioctl_terminate( call, STATUS_CANCELLED );
      }
 +
 +    if (do_msync())
 +        msync_clear_shm( server->msync_idx );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( server->esync_fd );
</span> +
      while (!list_empty( &server->read_queue ))
      {
          struct console_host_ioctl *call = LIST_ENTRY( list_head( &server->read_queue ), struct console_host_ioctl, entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -885,6 +900,7 @@ static void console_server_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -872,6 +880,7 @@ static void console_server_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     assert( obj->ops == &console_server_ops );
</span>      disconnect_console_server( server );
      if (server->fd) release_object( server->fd );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync()) close( server->esync_fd );
</span> +    if (do_msync()) msync_destroy_semaphore( server->msync_idx );
  }
  
  static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -933,6 +949,13 @@ static int console_server_get_esync_fd( struct object *obj, enum esync_type *typ
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return server->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -913,6 +922,13 @@ static int console_server_signaled( struct object *obj, struct wait_queue_entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return !server->console || !list_empty( &server->queue );
</span>  }
  
 +static unsigned int console_server_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2428,17 +2268,17 @@ index dbd4a97459c..2b023546907 100644
</span>  static struct fd *console_server_get_fd( struct object* obj )
  {
      struct console_server *server = (struct console_server*)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -966,6 +989,9 @@ static struct object *create_console_server( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -945,6 +961,9 @@ static struct object *create_console_server( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span>      allow_fd_caching(server->fd);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     server->esync_fd = -1;
</span>  
 +    if (do_msync())
 +        server->msync_idx = msync_alloc_shm( 0, 0 );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         server->esync_fd = esync_create_fd( 0, 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return &server->obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1581,6 +1607,10 @@ DECL_HANDLER(get_next_console_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1557,6 +1576,10 @@ DECL_HANDLER(get_next_console_request)
</span>          /* set result of previous ioctl */
          ioctl = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
          list_remove( &ioctl->entry );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2446,110 +2286,66 @@ index dbd4a97459c..2b023546907 100644
</span> +        if (do_msync() && list_empty( &server->queue ))
 +            msync_clear_shm( server->msync_idx );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync() && list_empty( &server->queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_clear( server->esync_fd );
</span>      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1668,6 +1698,10 @@ DECL_HANDLER(get_next_console_request)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (ioctl)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1643,5 +1666,9 @@ DECL_HANDLER(get_next_console_request)
</span>          set_error( STATUS_PENDING );
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span> +    if (do_msync() && list_empty( &server->queue ))
 +        msync_clear_shm( server->msync_idx );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && list_empty( &server->queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( server->esync_fd );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/debugger.c b/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index ca04d4c71ce..946dc7b04b5 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/debugger.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -87,6 +87,7 @@ static const struct object_ops debug_event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     debug_event_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -116,6 +117,7 @@ static const struct object_ops debug_obj_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     debug_obj_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     release_object( server );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> diff --git a/server/device.c b/server/device.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index c45d0102a56..93e22bbd78a 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 436dac6bfe9..8274f3f0f83 100644
</span> --- a/server/device.c
 +++ b/server/device.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -39,6 +39,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -38,6 +38,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "handle.h"
</span>  #include "request.h"
  #include "process.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  /* IRP object */
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -68,6 +69,7 @@ static const struct object_ops irp_call_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -95,11 +97,13 @@ struct device_manager
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -92,10 +93,12 @@ struct device_manager
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct list            requests;       /* list of pending irps across all devices */
</span>      struct irp_call       *current_call;   /* call currently executed on client side */
      struct wine_rb_tree    kernel_objects; /* map of objects that have client side pointer associated */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                    esync_fd;       /* esync file descriptor */
</span> +    unsigned int           msync_idx;
  };
  
  static void device_manager_dump( struct object *obj, int verbose );
  static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int device_manager_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int device_manager_get_msync_idx( struct object *obj, enum msync_type *type );
  static void device_manager_destroy( struct object *obj );
  
  static const struct object_ops device_manager_ops =
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -111,6 +115,7 @@ static const struct object_ops device_manager_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     device_manager_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     device_manager_get_esync_fd,      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_manager_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -169,6 +174,7 @@ static const struct object_ops device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -222,6 +228,7 @@ static const struct object_ops device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,              /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     device_file_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -754,6 +761,9 @@ static void delete_file( struct device_file *file )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -119,7 +122,8 @@ static const struct object_ops device_manager_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                     /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,               /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,                  /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    device_manager_destroy            /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_manager_destroy,           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_manager_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -747,6 +751,9 @@ static void delete_file( struct device_file *file )
</span>      /* terminate all pending requests */
      LIST_FOR_EACH_ENTRY_SAFE( irp, next, &file->requests, struct irp_call, dev_entry )
      {
 +        if (do_msync() && file->device->manager && list_empty( &file->device->manager->requests ))
 +            msync_clear( &file->device->manager->obj );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync() && file->device->manager && list_empty( &file->device->manager->requests ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_clear( file->device->manager->esync_fd );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -799,6 +809,13 @@ static int device_manager_get_esync_fd( struct object *obj, enum esync_type *typ
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return manager->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         list_remove( &irp->mgr_entry );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -782,6 +789,13 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return !list_empty( &manager->requests );
</span>  }
  
 +static unsigned int device_manager_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2562,142 +2358,97 @@ index c45d0102a56..93e22bbd78a 100644
</span>  static void device_manager_destroy( struct object *obj )
  {
      struct device_manager *manager = (struct device_manager *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -834,6 +851,9 @@ static void device_manager_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -816,6 +830,9 @@ static void device_manager_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         assert( !irp->file && !irp->async );
</span>          release_object( irp );
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        msync_destroy_semaphore( manager->msync_idx );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         close( manager->esync_fd );
</span>  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -849,6 +869,9 @@ static struct device_manager *create_device_manager(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static struct device_manager *create_device_manager(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -828,6 +845,9 @@ static struct device_manager *create_device_manager(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         list_init( &manager->devices );
</span>          list_init( &manager->requests );
          wine_rb_init( &manager->kernel_objects, compare_kernel_object );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +        if (do_msync())
 +            manager->msync_idx = msync_alloc_shm( 0, 0 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             manager->esync_fd = esync_create_fd( 0, 0 );
</span>      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1041,6 +1064,9 @@ DECL_HANDLER(get_next_device_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return manager;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1017,6 +1037,9 @@ DECL_HANDLER(get_next_device_request)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 /* we already own the object if it's only on manager queue */
</span>                  if (irp->file) grab_object( irp );
                  manager->current_call = irp;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +                if (do_msync() && list_empty( &manager->requests ))
 +                    msync_clear( &manager->obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (do_esync() && list_empty( &manager->requests ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     esync_clear( manager->esync_fd );
</span>              }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/directory.c b/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a6c0e292071..076f8fe0d58 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/directory.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -70,6 +70,7 @@ static const struct object_ops object_type_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -121,6 +122,7 @@ static const struct object_ops directory_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/esync.c b/server/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e193f61b3a7..06e17c01874 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/esync.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -49,7 +49,7 @@ int do_esync(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     static int do_esync_cached = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync_cached == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC"));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        do_esync_cached = getenv("WINEESYNC") && atoi(getenv("WINEESYNC")) && !do_msync();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return do_esync_cached;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -128,6 +128,7 @@ const struct object_ops esync_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     esync_get_esync_fd,        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             else close_handle( current->process, reply->next );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span> diff --git a/server/event.c b/server/event.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index f4ca3e48c6f..2770d83e6d6 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f1b79b1b35e..8b941db7179 100644
</span> --- a/server/event.c
 +++ b/server/event.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -36,6 +36,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -35,6 +35,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "thread.h"
</span>  #include "request.h"
  #include "security.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  static const WCHAR event_name[] = {'E','v','e','n','t'};
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -58,12 +59,14 @@ struct event
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -56,13 +57,16 @@ struct event
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct list    kernel_object;   /* list of kernel object pointers */
</span>      int            manual_reset;    /* is it a manual reset event? */
      int            signaled;        /* event has been signaled */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int            esync_fd;        /* esync file descriptor */
</span> +    unsigned int   msync_idx;
  };
  
  static void event_dump( struct object *obj, int verbose );
  static int event_signaled( struct object *obj, struct wait_queue_entry *entry );
  static void event_satisfied( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int event_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int event_get_msync_idx( struct object *obj, enum msync_type *type );
  static int event_signal( struct object *obj, unsigned int access);
  static struct list *event_get_kernel_obj_list( struct object *obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static void event_destroy( struct object *obj );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -77,6 +80,7 @@ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_get_esync_fd,        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    event_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     event_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -125,6 +129,7 @@ static const struct object_ops keyed_event_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     keyed_event_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                   /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -157,6 +162,9 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void event_destroy( struct object *obj );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -85,7 +89,8 @@ static const struct object_ops event_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     event_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    no_destroy                 /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    event_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    event_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -150,6 +155,9 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             list_init( &event->kernel_object );
</span>              event->manual_reset = manual_reset;
              event->signaled     = initial_state;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +            if (do_msync())
 +                event->msync_idx = msync_alloc_shm( initial_state, 0 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 event->esync_fd = esync_create_fd( initial_state, 0 );
</span>          }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -167,6 +175,10 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return event;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -157,6 +165,10 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span>  struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access )
  {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct object *obj;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    struct object *obj;
</span> +    if (do_msync() && (obj = get_handle_obj( process, handle, access, &msync_ops)))
 +        return (struct event *)obj; /* even though it's not an event */
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && (obj = get_handle_obj( process, handle, access, &esync_ops)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return (struct event *)obj; /* even though it's not an event */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return (struct event *)get_handle_obj( process, handle, access, &event_ops );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -179,10 +191,19 @@ static void pulse_event( struct event *event )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -166,10 +178,19 @@ static void pulse_event( struct event *event )
</span>      /* wake up all waiters if manual reset, a single one otherwise */
      wake_up( &event->obj, !event->manual_reset );
      event->signaled = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2714,10 +2465,10 @@ index f4ca3e48c6f..2770d83e6d6 100644
</span> +        return;
 +    }
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && event->obj.ops == &esync_ops)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_set_event( (struct esync *)event );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -196,6 +217,12 @@ void set_event( struct event *event )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     event->signaled = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* wake up all waiters if manual reset, a single one otherwise */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     wake_up( &event->obj, !event->manual_reset );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -177,7 +198,16 @@ void set_event( struct event *event )
</span>  
  void reset_event( struct event *event )
  {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2727,21 +2478,15 @@ index f4ca3e48c6f..2770d83e6d6 100644
</span> +        return;
 +    }
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && event->obj.ops == &esync_ops)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_reset_event( (struct esync *)event );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -203,6 +230,9 @@ void reset_event( struct event *event )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span>      event->signaled = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        msync_clear( &event->obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( event->esync_fd );
</span>  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -229,6 +259,13 @@ static int event_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return event->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void event_dump( struct object *obj, int verbose )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -195,6 +225,13 @@ static int event_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return event->signaled;
</span>  }
  
 +static unsigned int event_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2754,89 +2499,61 @@ index f4ca3e48c6f..2770d83e6d6 100644
</span>  static void event_satisfied( struct object *obj, struct wait_queue_entry *entry )
  {
      struct event *event = (struct event *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -261,6 +298,9 @@ static void event_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct event *event = (struct event *)obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -223,6 +260,14 @@ static struct list *event_get_kernel_obj_list( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return &event->kernel_object;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>  
<span style='display:block; white-space:pre;background:#e0ffe0;'>++static void event_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    struct event *event = (struct event *)obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        msync_destroy_semaphore( event->msync_idx );
<span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span> +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         close( event->esync_fd );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct keyed_event *create_keyed_event( struct object *root, const struct unicode_str *name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                         unsigned int attr, const struct security_descriptor *sd )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span> diff --git a/server/fd.c b/server/fd.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 7054d46aea0..7cb0a1897ae 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 16328063df6..dfc0f13130c 100644
</span> --- a/server/fd.c
 +++ b/server/fd.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -96,6 +96,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -95,6 +95,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "handle.h"
</span>  #include "process.h"
  #include "request.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  #include "winternl.h"
  #include "winioctl.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -161,6 +162,7 @@ struct fd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -159,6 +160,7 @@ struct fd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct completion   *completion;  /* completion object attached to this fd */
</span>      apc_param_t          comp_key;    /* completion key to set in completion events */
      unsigned int         comp_flags;  /* completion flags */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                  esync_fd;    /* esync file descriptor */
</span> +    unsigned int         msync_idx;   /* msync shm index */
  };
  
  static void fd_dump( struct object *obj, int verbose );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -175,6 +177,7 @@ static const struct object_ops fd_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -217,6 +220,7 @@ static const struct object_ops device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -258,6 +262,7 @@ static const struct object_ops inode_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -301,6 +306,7 @@ static const struct object_ops file_lock_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     file_lock_signaled,         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1650,6 +1656,9 @@ static void fd_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1643,6 +1645,9 @@ static void fd_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (fd->unix_fd != -1) close( fd->unix_fd );
</span>          free( fd->unix_name );
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        msync_destroy_semaphore( fd->msync_idx );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         close( fd->esync_fd );
</span>  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1771,6 +1780,7 @@ static struct fd *alloc_fd_object(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* check if the desired access is possible without violating */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1761,12 +1766,16 @@ static struct fd *alloc_fd_object(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     fd->poll_index = -1;
</span>      fd->completion = NULL;
      fd->comp_flags = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     fd->esync_fd   = -1;
</span> +    fd->msync_idx  = 0;
      init_async_queue( &fd->read_q );
      init_async_queue( &fd->write_q );
      init_async_queue( &fd->wait_q );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1780,6 +1790,9 @@ static struct fd *alloc_fd_object(void)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         fd->esync_fd = esync_create_fd( 1, 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     list_init( &fd->inode_entry );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     list_init( &fd->locks );
</span>  
 +    if (do_msync())
 +        fd->msync_idx = msync_alloc_shm( 1, 0 );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2844,37 +2561,33 @@ index 7054d46aea0..7cb0a1897ae 100644
</span>      if ((fd->poll_index = add_poll_user( fd )) == -1)
      {
          release_object( fd );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1816,14 +1829,19 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1802,11 +1811,15 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     fd->completion = NULL;
</span>      fd->comp_flags = 0;
      fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     fd->esync_fd   = -1;
</span> +    fd->msync_idx  = 0;
      init_async_queue( &fd->read_q );
      init_async_queue( &fd->write_q );
      init_async_queue( &fd->wait_q );
      list_init( &fd->inode_entry );
      list_init( &fd->locks );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync())
 +        fd->msync_idx = msync_alloc_shm( 0, 0 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         fd->esync_fd = esync_create_fd( 0, 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span>      return fd;
  }
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2275,6 +2293,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2257,6 +2270,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
</span>      fd->signaled = signaled;
      if (signaled) wake_up( fd->user, 0 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync() && !signaled)
 +        msync_clear( fd->user );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && !signaled)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( fd->esync_fd );
</span>  }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2311,6 +2332,15 @@ int default_fd_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* check if events are pending and if yes return which one(s) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2282,6 +2298,15 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
</span>      return ret;
  }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2890,152 +2603,49 @@ index 7054d46aea0..7cb0a1897ae 100644
</span>  int default_fd_get_poll_events( struct fd *fd )
  {
      int events = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/file.c b/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 330d956ac15..124321cfb06 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/file.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -124,6 +124,7 @@ static const struct object_ops file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     file_get_fd,                  /* get_fd */
</span> diff --git a/server/file.h b/server/file.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 5e192216abe..aefecfbd6e4 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index afc7c7cb0d3..59b71736433 100644
</span> --- a/server/file.h
 +++ b/server/file.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -109,6 +109,7 @@ extern void get_nt_name( struct fd *fd, struct unicode_str *name );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -108,6 +108,7 @@ extern char *dup_fd_name( struct fd *root, const char *name ) __WINE_DEALLOC(fre
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern void get_nt_name( struct fd *fd, struct unicode_str *name );
</span>  
  extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- extern int default_fd_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +extern unsigned int default_fd_get_msync_idx( struct object *obj, enum msync_type *type );
  extern int default_fd_get_poll_events( struct fd *fd );
  extern void default_poll_event( struct fd *fd, int event );
  extern void fd_cancel_async( struct fd *fd, struct async *async );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/handle.c b/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e6c5707556f..d605bcea752 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/handle.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -127,6 +127,7 @@ static const struct object_ops handle_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                            /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                       /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                       /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/hook.c b/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index ab4d0e9dd31..0bbdcc5aa88 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/hook.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -82,6 +82,7 @@ static const struct object_ops hook_table_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mailslot.c b/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 92fe938d3b9..5c39ba6fa73 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mailslot.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -82,6 +82,7 @@ static const struct object_ops mailslot_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mailslot_get_fd,           /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -144,6 +145,7 @@ static const struct object_ops mail_writer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mail_writer_get_fd,         /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -210,6 +212,7 @@ static const struct object_ops mailslot_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                           /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                           /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                           /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                           /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                   /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                      /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                      /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -241,6 +244,7 @@ static const struct object_ops mailslot_device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                           /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                                   /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                                   /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mailslot_device_file_get_fd,            /* get_fd */
</span> diff --git a/server/main.c b/server/main.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 5062d0999fa..f0299e5fa70 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index ddda5f4e86e..8de05a0c932 100644
</span> --- a/server/main.c
 +++ b/server/main.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -35,6 +35,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -34,6 +34,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "thread.h"
</span>  #include "request.h"
  #include "unicode.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  /* command-line options */
  int debug_level = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -230,9 +231,15 @@ int main( int argc, char *argv[] )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -229,6 +230,12 @@ int main( int argc, char *argv[] )
</span>      sock_init();
      open_master_socket();
  
 +    if (do_msync())
 +        msync_init();
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_init();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (!do_msync() && !do_esync() && debug_level)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!do_msync() && debug_level)
</span> +        fprintf( stderr, "wineserver: using server-side synchronization.\n" );
 +
      if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
      set_current_time();
      init_scheduler();
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mapping.c b/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b84bb08a77b..9ec2d28932c 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mapping.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -68,6 +68,7 @@ static const struct object_ops ranges_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -105,6 +106,7 @@ static const struct object_ops shared_map_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -179,6 +181,7 @@ static const struct object_ops mapping_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                        /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mapping_get_fd,              /* get_fd */
</span> diff --git a/server/msync.c b/server/msync.c
 new file mode 100644
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 00000000000..b6e98cbffbe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 00000000000..8715d38634f
</span> --- /dev/null
 +++ b/server/msync.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,992 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,991 @@
</span> +/*
 + * mach semaphore-based synchronization objects
 + *
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3645,8 +3255,6 @@ index 00000000000..b6e98cbffbe
</span> +    no_add_queue,              /* add_queue */
 +    NULL,                      /* remove_queue */
 +    NULL,                      /* signaled */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msync_get_msync_idx,       /* get_msync_idx */
</span> +    NULL,                      /* satisfied */
 +    no_signal,                 /* signal */
 +    no_get_fd,                 /* get_fd */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -3660,7 +3268,8 @@ index 00000000000..b6e98cbffbe
</span> +    no_open_file,              /* open_file */
 +    no_kernel_obj_list,        /* get_kernel_obj_list */
 +    no_close_handle,           /* close_handle */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msync_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msync_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msync_get_msync_idx        /* get_msync_idx */
</span> +};
 +
 +static void msync_dump( struct object *obj, int verbose )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4070,167 +3679,101 @@ index 00000000000..000aa48c53d
</span> +extern void msync_set_event( struct msync *msync );
 +extern void msync_reset_event( struct msync *msync );
 +extern void msync_abandon_mutexes( struct thread *thread );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/mutex.c b/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 4785a830e92..6a60adee0bd 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/mutex.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -74,6 +74,7 @@ static const struct object_ops mutex_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     mutex_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span> diff --git a/server/named_pipe.c b/server/named_pipe.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 06a8e9d4625..49547a4b381 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 59a90c36663..7110a3ddfcf 100644
</span> --- a/server/named_pipe.c
 +++ b/server/named_pipe.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -120,6 +120,7 @@ static const struct object_ops named_pipe_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -169,6 +170,7 @@ static const struct object_ops pipe_server_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_get_esync_fd,      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pipe_end_get_fd,              /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -214,6 +216,7 @@ static const struct object_ops pipe_client_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_get_esync_fd,      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default_fd_get_msync_idx,     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pipe_end_get_fd,              /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -262,6 +265,7 @@ static const struct object_ops named_pipe_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                             /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                             /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                        /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                        /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -294,6 +298,7 @@ static const struct object_ops named_pipe_device_file_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                            /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                                    /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     named_pipe_device_file_get_fd,           /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/object.c b/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f0423a305de..c53e0c0fda2 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/object.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -109,6 +109,7 @@ static const struct object_ops apc_reserve_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -134,6 +135,7 @@ static const struct object_ops completion_reserve_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,              /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -180,7 +180,8 @@ static const struct object_ops pipe_server_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pipe_server_open_file,        /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,           /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     async_close_obj_handle,       /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    pipe_server_destroy           /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pipe_server_destroy,          /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops pipe_server_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -224,7 +225,8 @@ static const struct object_ops pipe_client_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                 /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,           /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     async_close_obj_handle,       /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    pipe_end_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pipe_end_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default_fd_get_msync_idx      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops pipe_client_fd_ops =
</span> diff --git a/server/object.h b/server/object.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 9f508083a6a..0c6cbc02a93 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 899e71b1188..fab25254d1a 100644
</span> --- a/server/object.h
 +++ b/server/object.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -80,6 +80,8 @@ struct object_ops
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int  (*signaled)(struct object *,struct wait_queue_entry *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* return the esync fd for this object */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int (*get_esync_fd)(struct object *, enum esync_type *type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -107,6 +107,8 @@ struct object_ops
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int (*close_handle)(struct object *,struct process *,obj_handle_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* destroy on refcount == 0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     void (*destroy)(struct object *);
</span> +    /* return the msync shm idx for this object */
 +    unsigned int (*get_msync_idx)(struct object *, enum msync_type *type);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* wait satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     void (*satisfied)(struct object *,struct wait_queue_entry *);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     /* signal an object */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct object
</span> diff --git a/server/process.c b/server/process.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index dcc8be09c69..654b610fc9a 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 49f5c75005f..11d684746f0 100644
</span> --- a/server/process.c
 +++ b/server/process.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -64,6 +64,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -63,6 +63,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "request.h"
</span>  #include "user.h"
  #include "security.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  /* process object */
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -97,6 +98,7 @@ static void process_poll_event( struct fd *fd, int event );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -95,6 +96,7 @@ static struct security_descriptor *process_get_sd( struct object *obj );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void process_poll_event( struct fd *fd, int event );
</span>  static struct list *process_get_kernel_obj_list( struct object *obj );
  static void process_destroy( struct object *obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int process_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int process_get_msync_idx( struct object *obj, enum msync_type *type );
  static void terminate_process( struct process *process, struct thread *skip, int exit_code );
  
  static const struct object_ops process_ops =
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -108,6 +110,7 @@ static const struct object_ops process_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     process_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     process_get_esync_fd,        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    process_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                   /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                   /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -160,6 +163,7 @@ static const struct object_ops startup_info_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     startup_info_signaled,         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -222,6 +226,7 @@ static const struct object_ops job_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     job_signaled,                  /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                  /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -691,6 +696,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -118,7 +120,8 @@ static const struct object_ops process_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,                /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     process_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,             /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    process_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    process_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    process_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops process_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -684,6 +687,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     process->rawinput_mouse  = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     process->rawinput_kbd    = NULL;
</span>      memset( &process->image_info, 0, sizeof(process->image_info) );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     list_init( &process->rawinput_entry );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     process->esync_fd        = -1;
</span> +    process->msync_idx       = 0;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     list_init( &process->rawinput_entry );
</span>      list_init( &process->kernel_object );
      list_init( &process->thread_list );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     list_init( &process->locks );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -741,6 +747,9 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -735,6 +739,9 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
</span>      if (!process->handles || !process->token) goto error;
      process->session_id = token_get_session_id( process->token );
  
 +    if (do_msync())
 +        process->msync_idx = msync_alloc_shm( 0, 0 );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         process->esync_fd = esync_create_fd( 0, 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     set_fd_events( process->msg_fd, POLLIN );  /* start listening to events */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return process;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -793,6 +802,7 @@ static void process_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -783,6 +790,7 @@ static void process_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     free( process->rawinput_devices );
</span>      free( process->dir_cache );
      free( process->image );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync()) close( process->esync_fd );
</span> +    if (do_msync()) msync_destroy_semaphore( process->msync_idx );
  }
  
  /* dump a process on stdout for debugging purposes */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -817,6 +827,13 @@ static int process_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return process->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -800,6 +808,13 @@ static int process_signaled( struct object *obj, struct wait_queue_entry *entry
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return !process->running_threads;
</span>  }
  
 +static unsigned int process_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4244,24 +3787,24 @@ index dcc8be09c69..654b610fc9a 100644
</span>  {
      access = default_map_access( obj, access );
 diff --git a/server/process.h b/server/process.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index bedd8bb4586..24276142a63 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 1e73e9d47dc..217d94aa63a 100644
</span> --- a/server/process.h
 +++ b/server/process.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -87,6 +87,7 @@ struct process
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -86,6 +86,7 @@ struct process
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct list          rawinput_entry;  /* entry in the rawinput process list */
</span>      struct list          kernel_object;   /* list of kernel object pointers */
      pe_image_info_t      image_info;      /* main exe image info */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                  esync_fd;        /* esync file descriptor (signaled on exit) */
</span> +    unsigned int         msync_idx;
  };
  
  /* process functions */
 diff --git a/server/protocol.def b/server/protocol.def
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 71705a5c75d..b1c960ac321 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5479ccb9e91..b320c7d4e34 100644
</span> --- a/server/protocol.def
 +++ b/server/protocol.def
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -4137,3 +4137,57 @@ enum esync_type
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Retrieve the fd to wait on for user APCs. */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- @REQ(get_esync_apc_fd)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4087,3 +4087,57 @@ typedef union
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @REPLY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int enable;                /* previous state of auto-repeat enable */
</span>  @END
 +
 +enum msync_type
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4318,62 +3861,56 @@ index 71705a5c75d..b1c960ac321 100644
</span> +    unsigned int shm_idx;
 +@END
 diff --git a/server/queue.c b/server/queue.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index c718f23488d..e3b71775303 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 6b3698c838f..972e61dabb6 100644
</span> --- a/server/queue.c
 +++ b/server/queue.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -45,6 +45,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -44,6 +44,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "process.h"
</span>  #include "request.h"
  #include "user.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
  #define WM_NCMOUSELAST  (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -137,6 +138,8 @@ struct msg_queue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -134,6 +135,8 @@ struct msg_queue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int                    keystate_lock;   /* owns an input keystate lock */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     const queue_shm_t     *shared;          /* queue in session shared memory */
</span>      unsigned int           ignore_post_msg; /* ignore post messages newer than this unique id */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                    esync_fd;        /* esync file descriptor (signalled on message) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                    esync_in_msgwait; /* our thread is currently waiting on us */
</span> +    unsigned int           msync_idx;
 +    int                    msync_in_msgwait; /* our thread is currently waiting on us */
  };
  
  struct hotkey
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -154,6 +157,7 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -150,6 +153,7 @@ static void msg_queue_dump( struct object *obj, int verbose );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
</span>  static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
  static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int msg_queue_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int msg_queue_get_msync_idx( struct object *obj, enum msync_type *type );
  static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry );
  static void msg_queue_destroy( struct object *obj );
  static void msg_queue_poll_event( struct fd *fd, int event );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -170,6 +174,7 @@ static const struct object_ops msg_queue_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_remove_queue,    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_get_esync_fd,    /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    msg_queue_get_msync_idx,   /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     msg_queue_satisfied,       /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -208,6 +213,7 @@ static const struct object_ops thread_input_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -322,6 +328,8 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -178,7 +182,8 @@ static const struct object_ops msg_queue_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,        /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    msg_queue_destroy          /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msg_queue_destroy,         /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    msg_queue_get_msync_idx    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops msg_queue_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -314,6 +319,8 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         queue->last_get_msg    = current_time;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         queue->keystate_lock   = 0;
</span>          queue->ignore_post_msg = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-         queue->esync_fd        = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         queue->esync_in_msgwait = 0;
</span> +        queue->msync_idx       = 0;
 +        queue->msync_in_msgwait = 0;
          list_init( &queue->send_result );
          list_init( &queue->callback_result );
          list_init( &queue->pending_timers );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -347,6 +355,9 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             queue->esync_fd = esync_create_fd( 0, 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -336,6 +343,9 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         SHARED_WRITE_END;
</span>  
 +        if (do_msync())
 +            queue->msync_idx = msync_alloc_shm( 0, 0 );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4381,28 +3918,19 @@ index c718f23488d..e3b71775303 100644
</span>          thread->queue = queue;
  
          if ((desktop = get_thread_desktop( thread, 0 )))
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -762,6 +773,9 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         queue->keystate_lock = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (do_msync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        msync_clear( &queue->obj );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( queue->esync_fd );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1253,6 +1267,9 @@ static int is_queue_hung( struct msg_queue *queue )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1238,6 +1248,10 @@ static int is_queue_hung( struct msg_queue *queue )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (get_wait_queue_thread(entry)->queue == queue)
</span>              return 0;  /* thread is waiting on queue -> not hung */
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync() && queue->msync_in_msgwait)
 +        return 0;   /* thread is waiting on queue in absentia -> not hung */
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && queue->esync_in_msgwait)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return 0;   /* thread is waiting on queue in absentia -> not hung */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1317,6 +1334,13 @@ static int msg_queue_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return queue->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1292,6 +1306,13 @@ static int msg_queue_signaled( struct object *obj, struct wait_queue_entry *entr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return ret || is_signaled( queue );
</span>  }
  
 +static unsigned int msg_queue_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4415,101 +3943,73 @@ index c718f23488d..e3b71775303 100644
</span>  static void msg_queue_satisfied( struct object *obj, struct wait_queue_entry *entry )
  {
      struct msg_queue *queue = (struct msg_queue *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1374,6 +1398,8 @@ static void msg_queue_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1348,6 +1369,8 @@ static void msg_queue_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (queue->hooks) release_object( queue->hooks );
</span>      if (queue->fd) release_object( queue->fd );
      if (queue->shared) free_shared_object( queue->shared );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync()) close( queue->esync_fd );
</span> +    if (do_msync())
 +        msync_destroy_semaphore( queue->msync_idx );
  }
  
  static void msg_queue_poll_event( struct fd *fd, int event )
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3161,6 +3187,9 @@ DECL_HANDLER(set_queue_mask)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3134,6 +3157,9 @@ DECL_HANDLER(set_queue_mask)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             }
</span>              else wake_up( &queue->obj, 0 );
          }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +        if (do_msync() && !is_signaled( queue ))
 +            msync_clear( &queue->obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_clear( queue->esync_fd );
</span>      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3184,6 +3213,9 @@ DECL_HANDLER(get_queue_status)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3154,6 +3180,9 @@ DECL_HANDLER(get_queue_status)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             shared->changed_bits &= ~req->clear_bits;
</span>          }
          SHARED_WRITE_END;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +        if (do_msync() && !is_signaled( queue ))
 +            msync_clear( &queue->obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_clear( queue->esync_fd );
</span>      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3455,6 +3487,9 @@ DECL_HANDLER(get_message)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     else reply->wake_bits = reply->changed_bits = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3422,6 +3451,10 @@ DECL_HANDLER(get_message)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SHARED_WRITE_END;
</span>  
      set_error( STATUS_PENDING );  /* FIXME */
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync() && !is_signaled( queue ))
 +        msync_clear( &queue->obj );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && !is_signaled( queue ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( queue->esync_fd );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return;
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -4257,6 +4292,23 @@ DECL_HANDLER(esync_msgwait)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         set_fd_events( queue->fd, req->in_msgwait ? POLLIN : 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ found_msg:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4222,3 +4255,18 @@ DECL_HANDLER(set_keyboard_repeat)
</span>  
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     release_object( desktop );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +DECL_HANDLER(msync_msgwait)
 +{
 +    struct msg_queue *queue = get_current_queue();
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    const queue_shm_t *queue_shm;
</span> +
 +    if (!queue) return;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    queue_shm = queue->shared;
</span> +    queue->msync_in_msgwait = req->in_msgwait;
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (current->process->idle_event && !(queue_shm->wake_mask & QS_SMRESULT))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (current->process->idle_event && !(queue->shared->wake_mask & QS_SMRESULT))
</span> +        set_event( current->process->idle_event );
 +
 +    /* and start/stop waiting on the driver */
 +    if (queue->fd)
 +        set_fd_events( queue->fd, req->in_msgwait ? POLLIN : 0 );
 +}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DECL_HANDLER(set_keyboard_repeat)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     struct desktop *desktop;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/registry.c b/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 2205d214ffb..3601e6e5c46 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/registry.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -181,6 +181,7 @@ static const struct object_ops key_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,               /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/request.c b/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 832a33917b4..2e76c45952c 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/request.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -91,6 +91,7 @@ static const struct object_ops master_socket_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                     /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span> diff --git a/server/request.h b/server/request.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 6d27205cac1..413d22e004c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 13957d051d8..e6d7a4e64bc 100644
</span> --- a/server/request.h
 +++ b/server/request.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -416,6 +416,11 @@ DECL_HANDLER(get_esync_fd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- DECL_HANDLER(esync_msgwait);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -411,6 +411,11 @@ DECL_HANDLER(suspend_process);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DECL_HANDLER(resume_process);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DECL_HANDLER(get_next_thread);
</span>  DECL_HANDLER(set_keyboard_repeat);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- DECL_HANDLER(get_esync_apc_fd);
</span> +DECL_HANDLER(create_msync);
 +DECL_HANDLER(open_msync);
 +DECL_HANDLER(get_msync_idx);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4518,10 +4018,10 @@ index 6d27205cac1..413d22e004c 100644
</span>  
  #ifdef WANT_REQUEST_HANDLERS
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -719,6 +724,11 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     (req_handler)req_esync_msgwait,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -709,6 +714,11 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     (req_handler)req_resume_process,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     (req_handler)req_get_next_thread,
</span>      (req_handler)req_set_keyboard_repeat,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     (req_handler)req_get_esync_apc_fd,
</span> +    (req_handler)req_create_msync,
 +    (req_handler)req_open_msync,
 +    (req_handler)req_get_msync_idx,
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4530,10 +4030,10 @@ index 6d27205cac1..413d22e004c 100644
</span>  };
  
  C_ASSERT( sizeof(abstime_t) == 8 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -2420,6 +2430,34 @@ C_ASSERT( sizeof(struct set_keyboard_repeat_request) == 24 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2384,6 +2394,34 @@ C_ASSERT( FIELD_OFFSET(struct set_keyboard_repeat_request, period) == 20 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ C_ASSERT( sizeof(struct set_keyboard_repeat_request) == 24 );
</span>  C_ASSERT( FIELD_OFFSET(struct set_keyboard_repeat_reply, enable) == 8 );
  C_ASSERT( sizeof(struct set_keyboard_repeat_reply) == 16 );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- C_ASSERT( sizeof(struct get_esync_apc_fd_request) == 16 );
</span> +C_ASSERT( FIELD_OFFSET(struct create_msync_request, access) == 12 );
 +C_ASSERT( FIELD_OFFSET(struct create_msync_request, low) == 16 );
 +C_ASSERT( FIELD_OFFSET(struct create_msync_request, high) == 20 );
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4565,136 +4065,46 @@ index 6d27205cac1..413d22e004c 100644
</span>  
  #endif  /* WANT_REQUEST_HANDLERS */
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/semaphore.c b/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e3889f24601..8d3c325c0b3 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/semaphore.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -71,6 +71,7 @@ static const struct object_ops semaphore_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                  /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                          /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                          /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     semaphore_signal,              /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                     /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/serial.c b/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0d49a996c2a..9c28c78cf28 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/serial.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -92,6 +92,7 @@ static const struct object_ops serial_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     serial_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/signal.c b/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 55cd6aa037e..e86ad49df8e 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/signal.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -63,6 +63,7 @@ static const struct object_ops handler_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/sock.c b/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 44a4e3b7b15..1d3071c3b90 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/sock.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -472,6 +472,7 @@ static const struct object_ops sock_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,                 /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     default_fd_signaled,          /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,                 /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     sock_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3601,6 +3602,7 @@ static const struct object_ops ifchange_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                    /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                    /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,            /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,               /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ifchange_get_fd,         /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -3823,6 +3825,7 @@ static const struct object_ops socket_device_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/symlink.c b/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c7f34412317..d40d060492b 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/symlink.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -72,6 +72,7 @@ static const struct object_ops symlink_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span> diff --git a/server/thread.c b/server/thread.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 74a586d7986..b2c3f49bbe2 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 506adfc0a6f..8f84a1de7aa 100644
</span> --- a/server/thread.c
 +++ b/server/thread.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -51,6 +51,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -50,6 +50,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "request.h"
</span>  #include "user.h"
  #include "security.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  
  /* thread queues */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -98,6 +99,7 @@ static const struct object_ops thread_apc_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_apc_signaled,        /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -141,6 +143,7 @@ static const struct object_ops context_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     context_signaled,           /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                       /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -178,6 +181,7 @@ struct type_descr thread_type =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -174,6 +175,7 @@ struct type_descr thread_type =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span>  static void dump_thread( struct object *obj, int verbose );
  static int thread_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int thread_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int thread_get_msync_idx( struct object *obj, enum msync_type *type );
  static unsigned int thread_map_access( struct object *obj, unsigned int access );
  static void thread_poll_event( struct fd *fd, int event );
  static struct list *thread_get_kernel_obj_list( struct object *obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -192,6 +196,7 @@ static const struct object_ops thread_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,               /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread_get_esync_fd,        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    thread_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_satisfied,               /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                  /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                  /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -233,6 +238,8 @@ static inline void init_thread_structure( struct thread *thread )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -200,7 +202,8 @@ static const struct object_ops thread_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,               /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     thread_get_kernel_obj_list, /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,            /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    destroy_thread              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    destroy_thread,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    thread_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const struct fd_ops thread_fd_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -226,6 +229,8 @@ static inline void init_thread_structure( struct thread *thread )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     thread->context         = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     thread->teb             = 0;
</span>      thread->entry_point     = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread->esync_fd        = -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     thread->esync_apc_fd    = -1;
</span> +    thread->msync_idx       = 0;
 +    thread->msync_apc_idx   = 0;
      thread->system_regs     = 0;
      thread->queue           = NULL;
      thread->wait            = NULL;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -381,6 +388,12 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -374,6 +379,12 @@ struct thread *create_thread( int fd, struct process *process, const struct secu
</span>          }
      }
  
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4704,13 +4114,13 @@ index 74a586d7986..b2c3f49bbe2 100644
</span> +        thread->msync_apc_idx = msync_alloc_shm( 0, 0 );
 +    }
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         thread->esync_fd = esync_create_fd( 0, 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -470,6 +483,12 @@ static void destroy_thread( struct object *obj )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         close( thread->esync_fd );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     set_fd_events( thread->request_fd, POLLIN );  /* start listening to events */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     add_process_thread( thread->process, thread );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return thread;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -454,6 +465,12 @@ static void destroy_thread( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (thread->exit_poll) remove_timeout_user( thread->exit_poll );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (thread->id) free_ptid( thread->id );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (thread->token) release_object( thread->token );
</span> +
 +    if (do_msync())
 +    {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4720,8 +4130,8 @@ index 74a586d7986..b2c3f49bbe2 100644
</span>  }
  
  /* dump a thread on stdout for debugging purposes */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -495,6 +514,13 @@ static int thread_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return thread->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -472,6 +489,13 @@ static int thread_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return mythread->state == TERMINATED && !mythread->exit_poll;
</span>  }
  
 +static unsigned int thread_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4734,122 +4144,120 @@ index 74a586d7986..b2c3f49bbe2 100644
</span>  static unsigned int thread_map_access( struct object *obj, unsigned int access )
  {
      access = default_map_access( obj, access );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -547,6 +573,7 @@ static struct thread_apc *create_apc( struct object *owner, const apc_call_t *ca
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         apc->result.type = APC_NONE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (owner) grab_object( owner );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return apc;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1093,6 +1120,9 @@ void wake_up( struct object *obj, int max )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1070,6 +1094,9 @@ void wake_up( struct object *obj, int max )
</span>      struct list *ptr;
      int ret;
  
 +    if (do_msync())
 +        msync_wake_up( obj );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_wake_up( obj );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1183,6 +1213,9 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     LIST_FOR_EACH( ptr, &obj->wait_queue )
</span>      {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+         struct wait_queue_entry *entry = LIST_ENTRY( ptr, struct wait_queue_entry, entry );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1154,8 +1181,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     grab_object( apc );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     list_add_tail( queue, &apc->entry );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (!list_prev( queue, &apc->entry ))  /* first one */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    {
</span>          wake_thread( thread );
  
 +        if (do_msync() && queue == &thread->user_apc)
 +            msync_signal_all( thread->msync_apc_idx );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync() && queue == &thread->user_apc)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_wake_fd( thread->esync_apc_fd );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1233,6 +1266,9 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1201,6 +1232,10 @@ static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         apc = LIST_ENTRY( ptr, struct thread_apc, entry );
</span>          list_remove( ptr );
      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +    if (do_msync() && list_empty( &thread->system_apc ) && list_empty( &thread->user_apc ))
 +        msync_clear_shm( thread->msync_apc_idx );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync() && list_empty( &thread->system_apc ) && list_empty( &thread->user_apc ))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_clear( thread->esync_apc_fd );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return apc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1351,6 +1387,8 @@ void kill_thread( struct thread *thread, int violent_death )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1316,6 +1351,8 @@ void kill_thread( struct thread *thread, int violent_death )
</span>      }
      kill_console_processes( thread, 0 );
      abandon_mutexes( thread );
 +    if (do_msync())
 +        msync_abandon_mutexes( thread );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         esync_abandon_mutexes( thread );
</span>      if (violent_death)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         send_thread_signal( thread, SIGQUIT );
</span> diff --git a/server/thread.h b/server/thread.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 16f3e79b540..43fbc318093 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index edf2a825451..885d5eb21c6 100644
</span> --- a/server/thread.h
 +++ b/server/thread.h
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -58,6 +58,8 @@ struct thread
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -56,6 +56,8 @@ struct thread
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct process        *process;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     thread_id_t            id;            /* thread id */
</span>      struct list            mutex_list;    /* list of currently owned mutexes */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                    esync_fd;      /* esync file descriptor (signalled on exit) */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                    esync_apc_fd;  /* esync apc fd (signalled when APCs are present) */
</span> +    unsigned int           msync_idx;
 +    unsigned int           msync_apc_idx;
      unsigned int           system_regs;   /* which system regs have been set */
      struct msg_queue      *queue;         /* message queue */
      struct thread_wait    *wait;          /* current wait condition if sleeping */
 diff --git a/server/timer.c b/server/timer.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 36645a2a8d2..d57a5536eb3 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 96dc9d00ca1..2b3880dbb31 100644
</span> --- a/server/timer.c
 +++ b/server/timer.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -36,6 +36,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -35,6 +35,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "file.h"
</span>  #include "handle.h"
  #include "request.h"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "esync.h"
</span> +#include "msync.h"
  
  static const WCHAR timer_name[] = {'T','i','m','e','r'};
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -63,11 +64,13 @@ struct timer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -61,10 +62,12 @@ struct timer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     struct thread       *thread;    /* thread that set the APC function */
</span>      client_ptr_t         callback;  /* callback APC function */
      client_ptr_t         arg;       /* callback argument */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     int                  esync_fd;  /* esync file descriptor */
</span> +    unsigned int         msync_idx; /* msync shm index */
  };
  
  static void timer_dump( struct object *obj, int verbose );
  static int timer_signaled( struct object *obj, struct wait_queue_entry *entry );
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static int timer_get_esync_fd( struct object *obj, enum esync_type *type );
</span> +static unsigned int timer_get_msync_idx( struct object *obj, enum msync_type *type );
  static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry );
  static void timer_destroy( struct object *obj );
  
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -80,6 +83,7 @@ static const struct object_ops timer_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     remove_queue,              /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     timer_signaled,            /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     timer_get_esync_fd,        /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    timer_get_msync_idx,       /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     timer_satisfied,           /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -116,6 +120,9 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             timer->thread   = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             timer->esync_fd = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -89,7 +92,8 @@ static const struct object_ops timer_ops =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_open_file,              /* open_file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_kernel_obj_list,        /* get_kernel_obj_list */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     no_close_handle,           /* close_handle */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    timer_destroy              /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    timer_destroy,             /* destroy */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    timer_get_msync_idx        /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span>  
<span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -110,6 +114,10 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             timer->period   = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             timer->timeout  = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             timer->thread   = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +            if (do_msync())
 +                timer->msync_idx = msync_alloc_shm( 0, 0 );
 +
<span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 timer->esync_fd = esync_create_fd( 0, 0 );
</span>          }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -190,6 +197,9 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -181,6 +189,9 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span>          period = 0;  /* period doesn't make any sense for a manual timer */
          timer->signaled = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span> +        if (do_msync())
 +            msync_clear( &timer->obj );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (do_esync())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             esync_clear( timer->esync_fd );
</span>      }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -226,6 +236,13 @@ static int timer_get_esync_fd( struct object *obj, enum esync_type *type )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return timer->esync_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     timer->when     = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     timer->period   = period;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -208,6 +219,13 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return timer->signaled;
</span>  }
  
 +static unsigned int timer_get_msync_idx( struct object *obj, enum msync_type *type )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4862,33 +4270,21 @@ index 36645a2a8d2..d57a5536eb3 100644
</span>  static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry )
  {
      struct timer *timer = (struct timer *)obj;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -241,6 +258,8 @@ static void timer_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -222,6 +240,8 @@ static void timer_destroy( struct object *obj )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span>      if (timer->timeout) remove_timeout_user( timer->timeout );
      if (timer->thread) release_object( timer->thread );
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (do_esync()) close( timer->esync_fd );
</span> +    if (do_msync())
 +        msync_destroy_semaphore( timer->msync_idx );
  }
  
  /* create a timer */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/token.c b/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 479596bdbfa..5a9187e79a3 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/token.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -146,6 +146,7 @@ static const struct object_ops token_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                      /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                      /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                 /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                 /* get_fd */
</span> diff --git a/server/trace.c b/server/trace.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-index 6d614b8b9c4..71d9fc82159 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5888470f996..23eb3ecaad9 100644
</span> --- a/server/trace.c
 +++ b/server/trace.c
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -4879,6 +4879,63 @@ static void dump_get_esync_apc_fd_request( const struct get_esync_apc_fd_request
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4827,6 +4827,63 @@ static void dump_set_keyboard_repeat_reply( const struct set_keyboard_repeat_rep
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     fprintf( stderr, " enable=%d", req->enable );
</span>  }
  
 +static void dump_create_msync_request( const struct create_msync_request *req )
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4951,10 +4347,10 @@ index 6d614b8b9c4..71d9fc82159 100644
</span>  static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
      (dump_func)dump_new_process_request,
      (dump_func)dump_get_new_process_info_request,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -5177,6 +5234,11 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     (dump_func)dump_esync_msgwait_request,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5120,6 +5177,11 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     (dump_func)dump_resume_process_request,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     (dump_func)dump_get_next_thread_request,
</span>      (dump_func)dump_set_keyboard_repeat_request,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     (dump_func)dump_get_esync_apc_fd_request,
</span> +    (dump_func)dump_create_msync_request,
 +    (dump_func)dump_open_msync_request,
 +    (dump_func)dump_get_msync_idx_request,
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4963,10 +4359,10 @@ index 6d614b8b9c4..71d9fc82159 100644
</span>  };
  
  static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -5477,6 +5539,11 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5415,6 +5477,11 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
</span>      NULL,
<span style='display:block; white-space:pre;background:#e0ffe0;'>+     (dump_func)dump_get_next_thread_reply,
</span>      (dump_func)dump_set_keyboard_repeat_reply,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,
</span> +    (dump_func)dump_create_msync_reply,
 +    (dump_func)dump_open_msync_reply,
 +    (dump_func)dump_get_msync_idx_reply,
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4975,10 +4371,10 @@ index 6d614b8b9c4..71d9fc82159 100644
</span>  };
  
  static const char * const req_names[REQ_NB_REQUESTS] = {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -5777,6 +5844,11 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     "esync_msgwait",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5710,6 +5777,11 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     "resume_process",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     "get_next_thread",
</span>      "set_keyboard_repeat",
<span style='display:block; white-space:pre;background:#ffe0e0;'>-     "get_esync_apc_fd",
</span> +    "create_msync",
 +    "open_msync",
 +    "get_msync_idx",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4987,35 +4383,3 @@ index 6d614b8b9c4..71d9fc82159 100644
</span>  };
  
  static const struct
<span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/window.c b/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 507a9acf94f..35cf194995c 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/window.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -108,6 +108,7 @@ static const struct object_ops window_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                     /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                     /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/server/winstation.c b/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e7884d42f40..a5b6e9ba148 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/server/winstation.c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -77,6 +77,7 @@ static const struct object_ops winstation_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -118,6 +119,7 @@ static const struct object_ops desktop_ops =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* remove_queue */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* signaled */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* get_esync_fd */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NULL,                         /* get_msync_idx */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     NULL,                         /* satisfied */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_signal,                    /* signal */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     no_get_fd,                    /* get_fd */
</span></pre><pre style='margin:0'>

</pre>