Commit f031c676 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

server: Add a serial event mask change counter.

parent 4b772c2c
...@@ -860,8 +860,7 @@ todo_wine ...@@ -860,8 +860,7 @@ todo_wine
{ {
/* unblock pending wait */ /* unblock pending wait */
trace("recovering after WAIT_TIMEOUT...\n"); trace("recovering after WAIT_TIMEOUT...\n");
/* FIXME: Wine fails to unblock with new mask being equal to the old one */ res = SetCommMask(hcom, EV_TXEMPTY);
res = SetCommMask(hcom, 0);
ok(res, "SetCommMask error %d\n", GetLastError()); ok(res, "SetCommMask error %d\n", GetLastError());
res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
...@@ -968,8 +967,7 @@ todo_wine ...@@ -968,8 +967,7 @@ todo_wine
/* unblock pending wait */ /* unblock pending wait */
trace("recovering after WAIT_TIMEOUT...\n"); trace("recovering after WAIT_TIMEOUT...\n");
/* FIXME: Wine fails to unblock with new mask being equal to the old one */ res = SetCommMask(hcom, EV_TXEMPTY);
res = SetCommMask(hcom, 0);
ok(res, "SetCommMask error %d\n", GetLastError()); ok(res, "SetCommMask error %d\n", GetLastError());
res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT); res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
......
...@@ -380,7 +380,7 @@ static NTSTATUS get_timeouts(HANDLE handle, SERIAL_TIMEOUTS* st) ...@@ -380,7 +380,7 @@ static NTSTATUS get_timeouts(HANDLE handle, SERIAL_TIMEOUTS* st)
return status; return status;
} }
static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask) static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD *mask, DWORD *cookie)
{ {
NTSTATUS status; NTSTATUS status;
...@@ -388,7 +388,10 @@ static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask) ...@@ -388,7 +388,10 @@ static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask)
{ {
req->handle = wine_server_obj_handle( hDevice ); req->handle = wine_server_obj_handle( hDevice );
if (!(status = wine_server_call( req ))) if (!(status = wine_server_call( req )))
{
*mask = reply->eventmask; *mask = reply->eventmask;
if (cookie) *cookie = reply->cookie;
}
} }
SERVER_END_REQ; SERVER_END_REQ;
return status; return status;
...@@ -794,6 +797,7 @@ typedef struct async_commio ...@@ -794,6 +797,7 @@ typedef struct async_commio
IO_STATUS_BLOCK* iosb; IO_STATUS_BLOCK* iosb;
HANDLE hEvent; HANDLE hEvent;
DWORD evtmask; DWORD evtmask;
DWORD cookie;
DWORD mstat; DWORD mstat;
serial_irq_info irq_info; serial_irq_info irq_info;
} async_commio; } async_commio;
...@@ -906,9 +910,9 @@ static DWORD CALLBACK wait_for_event(LPVOID arg) ...@@ -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 )) if (!server_get_unix_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, &needs_close, NULL, NULL ))
{ {
serial_irq_info new_irq_info; serial_irq_info new_irq_info;
DWORD new_mstat, new_evtmask; DWORD new_mstat, dummy, cookie;
LARGE_INTEGER time; LARGE_INTEGER time;
TRACE("device=%p fd=0x%08x mask=0x%08x buffer=%p event=%p irq_info=%p\n", 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); commio->hDevice, fd, commio->evtmask, commio->events, commio->hEvent, &commio->irq_info);
...@@ -934,8 +938,8 @@ static DWORD CALLBACK wait_for_event(LPVOID arg) ...@@ -934,8 +938,8 @@ static DWORD CALLBACK wait_for_event(LPVOID arg)
&new_irq_info, &commio->irq_info, &new_irq_info, &commio->irq_info,
new_mstat, commio->mstat); new_mstat, commio->mstat);
if (*commio->events) break; if (*commio->events) break;
get_wait_mask(commio->hDevice, &new_evtmask); get_wait_mask(commio->hDevice, &dummy, &cookie);
if (commio->evtmask != new_evtmask) if (commio->cookie != cookie)
{ {
*commio->events = 0; *commio->events = 0;
break; break;
...@@ -964,7 +968,7 @@ static NTSTATUS wait_on(HANDLE hDevice, int fd, HANDLE hEvent, PIO_STATUS_BLOCK ...@@ -964,7 +968,7 @@ static NTSTATUS wait_on(HANDLE hDevice, int fd, HANDLE hEvent, PIO_STATUS_BLOCK
commio->events = events; commio->events = events;
commio->iosb = piosb; commio->iosb = piosb;
commio->hEvent = hEvent; 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 /* We may never return, if some capabilities miss
* Return error in that case * Return error in that case
...@@ -1159,7 +1163,7 @@ static inline NTSTATUS io_control(HANDLE hDevice, ...@@ -1159,7 +1163,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
case IOCTL_SERIAL_GET_WAIT_MASK: case IOCTL_SERIAL_GET_WAIT_MASK:
if (lpOutBuffer && nOutBufferSize == sizeof(DWORD)) if (lpOutBuffer && nOutBufferSize == sizeof(DWORD))
{ {
if (!(status = get_wait_mask(hDevice, lpOutBuffer))) if (!(status = get_wait_mask(hDevice, lpOutBuffer, NULL)))
sz = sizeof(DWORD); sz = sizeof(DWORD);
} }
else else
......
...@@ -3055,6 +3055,8 @@ struct get_serial_info_reply ...@@ -3055,6 +3055,8 @@ struct get_serial_info_reply
unsigned int writeconst; unsigned int writeconst;
unsigned int writemult; unsigned int writemult;
unsigned int eventmask; unsigned int eventmask;
unsigned int cookie;
char __pad_36[4];
}; };
...@@ -5821,6 +5823,6 @@ union generic_reply ...@@ -5821,6 +5823,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2219,6 +2219,7 @@ enum message_type ...@@ -2219,6 +2219,7 @@ enum message_type
unsigned int writeconst; unsigned int writeconst;
unsigned int writemult; unsigned int writemult;
unsigned int eventmask; unsigned int eventmask;
unsigned int cookie;
@END @END
......
...@@ -1477,7 +1477,8 @@ C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, readmult) == 16 ); ...@@ -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, writeconst) == 20 );
C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, writemult) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, writemult) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_serial_info_reply, eventmask) == 28 ); 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, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, flags) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, flags) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, readinterval) == 20 ); C_ASSERT( FIELD_OFFSET(struct set_serial_info_request, readinterval) == 20 );
......
...@@ -76,6 +76,7 @@ struct serial ...@@ -76,6 +76,7 @@ struct serial
unsigned int writemult; unsigned int writemult;
unsigned int eventmask; unsigned int eventmask;
unsigned int generation; /* event mask change counter */
struct termios original; struct termios original;
...@@ -135,6 +136,7 @@ struct object *create_serial( struct fd *fd ) ...@@ -135,6 +136,7 @@ struct object *create_serial( struct fd *fd )
serial->writemult = 0; serial->writemult = 0;
serial->writeconst = 0; serial->writeconst = 0;
serial->eventmask = 0; serial->eventmask = 0;
serial->generation = 0;
serial->fd = (struct fd *)grab_object( fd ); serial->fd = (struct fd *)grab_object( fd );
set_fd_user( fd, &serial_fd_ops, &serial->obj ); set_fd_user( fd, &serial_fd_ops, &serial->obj );
return &serial->obj; return &serial->obj;
...@@ -210,6 +212,7 @@ DECL_HANDLER(get_serial_info) ...@@ -210,6 +212,7 @@ DECL_HANDLER(get_serial_info)
/* event mask */ /* event mask */
reply->eventmask = serial->eventmask; reply->eventmask = serial->eventmask;
reply->cookie = serial->generation;
release_object( serial ); release_object( serial );
} }
...@@ -235,10 +238,8 @@ DECL_HANDLER(set_serial_info) ...@@ -235,10 +238,8 @@ DECL_HANDLER(set_serial_info)
if (req->flags & SERIALINFO_SET_MASK) if (req->flags & SERIALINFO_SET_MASK)
{ {
serial->eventmask = req->eventmask; serial->eventmask = req->eventmask;
if (!serial->eventmask) serial->generation++;
{ fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
}
} }
release_object( serial ); release_object( serial );
......
...@@ -2687,6 +2687,7 @@ static void dump_get_serial_info_reply( const struct get_serial_info_reply *req ...@@ -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, ", writeconst=%08x", req->writeconst );
fprintf( stderr, ", writemult=%08x", req->writemult ); fprintf( stderr, ", writemult=%08x", req->writemult );
fprintf( stderr, ", eventmask=%08x", req->eventmask ); 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 ) static void dump_set_serial_info_request( const struct set_serial_info_request *req )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment