Dmitry Timoshkov : server: Add a serial event mask change counter.

Alexandre Julliard julliard at winehq.org
Tue Sep 10 14:49:56 CDT 2013


Module: wine
Branch: master
Commit: f031c676c1eb5c58810ef22c6c3da54fbe22d660
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f031c676c1eb5c58810ef22c6c3da54fbe22d660

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Sep 10 11:29:57 2013 +0900

server: Add a serial event mask change counter.

---

 dlls/kernel32/tests/comm.c     |    6 ++----
 dlls/ntdll/serial.c            |   18 +++++++++++-------
 include/wine/server_protocol.h |    4 +++-
 server/protocol.def            |    1 +
 server/request.h               |    3 ++-
 server/serial.c                |    9 +++++----
 server/trace.c                 |    1 +
 7 files changed, 25 insertions(+), 17 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..5e6eaf4 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -380,7 +380,7 @@ static NTSTATUS get_timeouts(HANDLE handle, SERIAL_TIMEOUTS* st)
     return status;
 }
 
-static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask)
+static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD *mask, DWORD *cookie)
 {
     NTSTATUS    status;
 
@@ -388,7 +388,10 @@ static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask)
     {
         req->handle = wine_server_obj_handle( hDevice );
         if (!(status = wine_server_call( req )))
+        {
             *mask = reply->eventmask;
+            if (cookie) *cookie = reply->cookie;
+        }
     }
     SERVER_END_REQ;
     return status;
@@ -794,6 +797,7 @@ typedef struct async_commio
     IO_STATUS_BLOCK*    iosb;
     HANDLE              hEvent;
     DWORD               evtmask;
+    DWORD               cookie;
     DWORD               mstat;
     serial_irq_info     irq_info;
 } async_commio;
@@ -906,9 +910,9 @@ static DWORD CALLBACK wait_for_event(LPVOID arg)
     if (!server_get_unix_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, &needs_close, NULL, NULL ))
     {
         serial_irq_info new_irq_info;
-        DWORD new_mstat, new_evtmask;
+        DWORD new_mstat, dummy, cookie;
         LARGE_INTEGER time;
-        
+
         TRACE("device=%p fd=0x%08x mask=0x%08x buffer=%p event=%p irq_info=%p\n", 
               commio->hDevice, fd, commio->evtmask, commio->events, commio->hEvent, &commio->irq_info);
 
@@ -934,8 +938,8 @@ static DWORD CALLBACK wait_for_event(LPVOID arg)
                                            &new_irq_info, &commio->irq_info,
                                            new_mstat, commio->mstat);
             if (*commio->events) break;
-            get_wait_mask(commio->hDevice, &new_evtmask);
-            if (commio->evtmask != new_evtmask)
+            get_wait_mask(commio->hDevice, &dummy, &cookie);
+            if (commio->cookie != cookie)
             {
                 *commio->events = 0;
                 break;
@@ -964,7 +968,7 @@ static NTSTATUS wait_on(HANDLE hDevice, int fd, HANDLE hEvent, PIO_STATUS_BLOCK
     commio->events  = events;
     commio->iosb    = piosb;
     commio->hEvent  = hEvent;
-    get_wait_mask(commio->hDevice, &commio->evtmask);
+    get_wait_mask(commio->hDevice, &commio->evtmask, &commio->cookie);
 
 /* We may never return, if some capabilities miss
  * Return error in that case
@@ -1159,7 +1163,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
     case IOCTL_SERIAL_GET_WAIT_MASK:
         if (lpOutBuffer && nOutBufferSize == sizeof(DWORD))
         {
-            if (!(status = get_wait_mask(hDevice, lpOutBuffer)))
+            if (!(status = get_wait_mask(hDevice, lpOutBuffer, NULL)))
                 sz = sizeof(DWORD);
         }
         else
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 4919579..b98e6d8 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3055,6 +3055,8 @@ struct get_serial_info_reply
     unsigned int writeconst;
     unsigned int writemult;
     unsigned int eventmask;
+    unsigned int cookie;
+    char __pad_36[4];
 };
 
 
@@ -5821,6 +5823,6 @@ union generic_reply
     struct set_suspend_context_reply set_suspend_context_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 448
+#define SERVER_PROTOCOL_VERSION 449
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 9164e3e..a7c5478 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2219,6 +2219,7 @@ enum message_type
     unsigned int writeconst;
     unsigned int writemult;
     unsigned int eventmask;
+    unsigned int cookie;
 @END
 
 
diff --git a/server/request.h b/server/request.h
index e6e2c40..12b609c 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1477,7 +1477,8 @@ C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, readmult) == 16 );
 C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, writeconst) == 20 );
 C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, writemult) == 24 );
 C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, eventmask) == 28 );
-C_ASSERT( sizeof(struct get_serial_info_reply) == 32 );
+C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, cookie) == 32 );
+C_ASSERT( sizeof(struct get_serial_info_reply) == 40 );
 C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, flags) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, readinterval) == 20 );
diff --git a/server/serial.c b/server/serial.c
index aac20fa..28f17f4 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -76,6 +76,7 @@ struct serial
     unsigned int        writemult;
 
     unsigned int        eventmask;
+    unsigned int        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;
@@ -210,6 +212,7 @@ DECL_HANDLER(get_serial_info)
 
         /* event mask */
         reply->eventmask    = serial->eventmask;
+        reply->cookie       = serial->generation;
 
         release_object( serial );
     }
@@ -235,10 +238,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 );
-            }
+            serial->generation++;
+            fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
         }
 
         release_object( serial );
diff --git a/server/trace.c b/server/trace.c
index 5b51e05..3f17b61 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2687,6 +2687,7 @@ static void dump_get_serial_info_reply( const struct get_serial_info_reply *req
     fprintf( stderr, ", writeconst=%08x", req->writeconst );
     fprintf( stderr, ", writemult=%08x", req->writemult );
     fprintf( stderr, ", eventmask=%08x", req->eventmask );
+    fprintf( stderr, ", cookie=%08x", req->cookie );
 }
 
 static void dump_set_serial_info_request( const struct set_serial_info_request *req )




More information about the wine-cvs mailing list