Module: wine Branch: master Commit: f031c676c1eb5c58810ef22c6c3da54fbe22d660 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f031c676c1eb5c58810ef22c6c...
Author: Dmitry Timoshkov dmitry@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 )