server: Add a serial event mask change counter.

Dmitry Timoshkov dmitry at baikal.ru
Sun Sep 8 23:22:49 CDT 2013


This allows to detect a serial event mask change even if the new mask
is equal to an old one.
---
 dlls/kernel32/tests/comm.c |  6 ++----
 dlls/ntdll/serial.c        |  3 +++
 server/serial.c            | 10 +++++-----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/tests/comm.c b/dlls/kernel32/tests/comm.c
index e54be7a..7646766 100644
--- a/dlls/kernel32/tests/comm.c
+++ b/dlls/kernel32/tests/comm.c
@@ -860,8 +860,7 @@ todo_wine
     {
         /* unblock pending wait */
         trace("recovering after WAIT_TIMEOUT...\n");
-        /* FIXME: Wine fails to unblock with new mask being equal to the old one */
-        res = SetCommMask(hcom, 0);
+        res = SetCommMask(hcom, EV_TXEMPTY);
         ok(res, "SetCommMask error %d\n", GetLastError());
 
         res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
@@ -968,8 +967,7 @@ todo_wine
 
             /* unblock pending wait */
             trace("recovering after WAIT_TIMEOUT...\n");
-            /* FIXME: Wine fails to unblock with new mask being equal to the old one */
-            res = SetCommMask(hcom, 0);
+            res = SetCommMask(hcom, EV_TXEMPTY);
             ok(res, "SetCommMask error %d\n", GetLastError());
 
             res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c
index 07ba633..fc3df09 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -1160,7 +1160,10 @@ static inline NTSTATUS io_control(HANDLE hDevice,
         if (lpOutBuffer && nOutBufferSize == sizeof(DWORD))
         {
             if (!(status = get_wait_mask(hDevice, lpOutBuffer)))
+            {
+                *(DWORD *)lpOutBuffer &= 0xffff;
                 sz = sizeof(DWORD);
+            }
         }
         else
             status = STATUS_INVALID_PARAMETER;
diff --git a/server/serial.c b/server/serial.c
index aac20fa..fd8f574 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -76,6 +76,7 @@ struct serial
     unsigned int        writemult;
 
     unsigned int        eventmask;
+    unsigned short      generation; /* event mask change counter */
 
     struct termios      original;
 
@@ -135,6 +136,7 @@ struct object *create_serial( struct fd *fd )
     serial->writemult    = 0;
     serial->writeconst   = 0;
     serial->eventmask    = 0;
+    serial->generation   = 0;
     serial->fd = (struct fd *)grab_object( fd );
     set_fd_user( fd, &serial_fd_ops, &serial->obj );
     return &serial->obj;
@@ -209,7 +211,7 @@ DECL_HANDLER(get_serial_info)
         reply->writemult    = serial->writemult;
 
         /* event mask */
-        reply->eventmask    = serial->eventmask;
+        reply->eventmask    = serial->eventmask | (serial->generation << 16);
 
         release_object( serial );
     }
@@ -235,10 +237,8 @@ DECL_HANDLER(set_serial_info)
         if (req->flags & SERIALINFO_SET_MASK)
         {
             serial->eventmask = req->eventmask;
-            if (!serial->eventmask)
-            {
-                fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
-            }
+            if (++serial->generation >= 0xffff) serial->generation = 1;
+            fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
         }
 
         release_object( serial );
-- 
1.8.3.4




More information about the wine-patches mailing list