Module: wine
Branch: master
Commit: 29883e2db98b548e9c22b12e25b7f6d8360df220
URL: https://source.winehq.org/git/wine.git/?a=commit;h=29883e2db98b548e9c22b12e…
Author: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Date: Sun Mar 20 07:28:17 2022 +0900
ws2_32/tests: Continue sending remaining data on short write in test_write_events.
Today, we assert that a short write clears the FD_WRITE event bit;
however, short writes can never happen on Windows in the first place.
We're testing for a property of a socket behaviour that does not exist
on Windows, but currently happens to be exhibited by Wine.
Ignore short writes, and continue sending until it fails with
EWOULDBLOCK. This way, the test won't care whether or not a short write
clears FD_WRITE. This allows us some flexibility in implementation of
send().
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/ws2_32/tests/sock.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 6cb8ff0a7a8..cc74e301f60 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -5666,14 +5666,11 @@ static void test_write_events(struct event_test_ctx *ctx)
if (!broken(1))
{
- while ((ret = send(server, buffer, buffer_size, 0)) == buffer_size);
/* Windows will never send less than buffer_size bytes here, but Linux
* may do a short write. */
- todo_wine_if (ret > 0)
- {
- ok(ret == -1, "got %d\n", ret);
- ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
- }
+ while ((ret = send(server, buffer, buffer_size, 0)) > 0);
+ ok(ret == -1, "got %d\n", ret);
+ ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
while (recv(client, buffer, buffer_size, 0) > 0);
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
Module: wine
Branch: master
Commit: d162a3e2f19b152de1cb132f4b68835b60a63e14
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d162a3e2f19b152de1cb132f…
Author: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Date: Sun Mar 20 07:28:05 2022 +0900
server: Ensure initial status is set in async_set_result().
Shift the resposibility of setting initial status from
set_async_direct_result request handler to async_set_result().
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
server/async.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/server/async.c b/server/async.c
index 6d663a6a553..d49fb8b7c04 100644
--- a/server/async.c
+++ b/server/async.c
@@ -481,6 +481,8 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
assert( async->terminated ); /* it must have been woken up if we get a result */
+ if (async->unknown_status) async_set_initial_status( async, status );
+
if (async->alerted && status == STATUS_PENDING) /* restart it */
{
async->terminated = 0;
@@ -765,8 +767,6 @@ DECL_HANDLER(set_async_direct_result)
return;
}
- async_set_initial_status( async, status );
-
if (status == STATUS_PENDING)
{
async->direct_result = 0;
Module: wine
Branch: master
Commit: b632ddedcd37b28c42e20dc3c7b47df418ba64b8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b632ddedcd37b28c42e20dc3…
Author: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Date: Sun Mar 20 07:28:01 2022 +0900
server: Actually set initial status in set_async_direct_result handler.
Commit 15483b1a126 (server: Allow calling async_handoff() with status
code STATUS_ALERTED., 2022-02-10) introduced the set_async_direct_result
handler which calls async_set_initial_status().
However, the async_set_initial_status() call does nothing since
async->terminated is set, leaving the async in a confusing state
(unknown_status = 1 but pending/completed).
So far, this issue is unlikely to have been a problem in practice for
the following reasons:
1. async_set_initial_status() would have unset unknown_status, but it
remains set instead. This is usually not a problem, since
unknown_status is usually ever read by code paths effectively
unreachable for non-device (e.g. socket) asyncs.
It would still potentially allow set_async_direct_result to be called
multiple times, but it wouldn't actually happen in practice unless
something goes wrong.
2. async_set_initial_status() would have set initial_status; however,
it is left with the default value STATUS_PENDING. If the actual
status is something other than that, the handler closes the wait
handle and async_satisfied (the only real consumer of initial_status)
would never be called anyway.
For reasons above, this issue is not effectively observable or testable.
Nonetheless, the current code does leave the async object in an
inconsistent state.
Fix this by removing the !async->terminated check in
async_set_initial_status().
Also, remove assert( async->unknown_status ). The client can now
trigger the assert() by calling set_async_direct_result on a device
async, thereby causing async_set_initial_status() to be called twice.
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
server/async.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/server/async.c b/server/async.c
index 7d0ff10f7a4..6d663a6a553 100644
--- a/server/async.c
+++ b/server/async.c
@@ -302,12 +302,8 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
* the initial status may be STATUS_PENDING */
void async_set_initial_status( struct async *async, unsigned int status )
{
- assert( async->unknown_status );
- if (!async->terminated)
- {
- async->initial_status = status;
- async->unknown_status = 0;
- }
+ async->initial_status = status;
+ async->unknown_status = 0;
}
void set_async_pending( struct async *async )