mirror of
https://github.com/libuv/libuv
synced 2025-03-28 21:13:16 +00:00
Add ol_close_cb stack test and fix it for Windows
This commit is contained in:
parent
56608452af
commit
4899328166
@ -22,6 +22,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="test\echo-server.c" />
|
||||
<ClCompile Include="test\test-callback-stack.c" />
|
||||
<ClCompile Include="test\test-fail-always.c" />
|
||||
<ClCompile Include="test\test-pass-always.c" />
|
||||
<ClCompile Include="test\test-ping-pong.c" />
|
||||
|
32
ol-win.c
32
ol-win.c
@ -285,7 +285,10 @@ ol_handle* ol_tcp_handle_new(ol_close_cb close_cb, void* data) {
|
||||
|
||||
|
||||
int ol_close_error(ol_handle* handle, ol_err e) {
|
||||
ol_req *req;
|
||||
|
||||
if (handle->_.flags & OL_HANDLE_CLOSING)
|
||||
|
||||
return 0;
|
||||
|
||||
handle->_.error = e;
|
||||
@ -293,17 +296,21 @@ int ol_close_error(ol_handle* handle, ol_err e) {
|
||||
switch (handle->type) {
|
||||
case OL_TCP:
|
||||
closesocket(handle->_.socket);
|
||||
if (handle->_.reqs_pending != 0) {
|
||||
/* Cannot free the handle right now because there are queued */
|
||||
/* operations. Close the socket, wait for for all packets to come */
|
||||
/* out, then have ol_poll call close_cb. */
|
||||
handle->_.flags |= OL_HANDLE_CLOSING;
|
||||
} else {
|
||||
/* There are no pending operations. Call the close callback now. */
|
||||
handle->_.flags |= OL_HANDLE_CLOSED;
|
||||
if (handle->close_cb)
|
||||
handle->close_cb(handle, e);
|
||||
if (handle->_.reqs_pending == 0) {
|
||||
/* If there are no operations queued for this socket, queue one */
|
||||
/* manually, so ol_poll will call close_cb. */
|
||||
req = (ol_req*)malloc(sizeof(*req));
|
||||
req->handle = handle;
|
||||
req->type = OL_CLOSE;
|
||||
req->_.flags = 0;
|
||||
if (!PostQueuedCompletionStatus(ol_iocp_, 0, (ULONG_PTR)handle, &req->_.overlapped))
|
||||
ol_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
|
||||
req->_.flags |= OL_REQ_PENDING;
|
||||
handle->_.reqs_pending++;
|
||||
}
|
||||
|
||||
/* After all packets to come out, ol_poll will call close_cb. */
|
||||
handle->_.flags |= OL_HANDLE_CLOSING;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@ -588,7 +595,6 @@ void ol_poll() {
|
||||
handle->_.flags |= OL_HANDLE_CLOSED;
|
||||
if (handle->close_cb)
|
||||
handle->close_cb(handle, handle->_.error);
|
||||
ol_refs_--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -649,6 +655,10 @@ void ol_poll() {
|
||||
free(req);
|
||||
}
|
||||
return;
|
||||
|
||||
case OL_CLOSE:
|
||||
/* Should never get here */
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
3
ol-win.h
3
ol-win.h
@ -28,5 +28,4 @@ typedef struct {
|
||||
unsigned int flags;
|
||||
unsigned int reqs_pending;
|
||||
ol_err error;
|
||||
} ol_handle_private;
|
||||
|
||||
} ol_handle_private;
|
3
ol.h
3
ol.h
@ -52,7 +52,8 @@ typedef enum {
|
||||
OL_ACCEPT,
|
||||
OL_READ,
|
||||
OL_WRITE,
|
||||
OL_SHUTDOWN
|
||||
OL_SHUTDOWN,
|
||||
OL_CLOSE
|
||||
} ol_req_type;
|
||||
|
||||
|
||||
|
32
test/test-callback-stack.c
Normal file
32
test/test-callback-stack.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "../ol.h"
|
||||
#include "test.h"
|
||||
|
||||
|
||||
int nested = 0;
|
||||
int close_cb_called = 0;
|
||||
|
||||
|
||||
void close_cb(ol_handle *handle, ol_err e) {
|
||||
assert("ol_close error" && e == 0);
|
||||
assert("ol_close_cb not called from a fresh stack" && nested == 0);
|
||||
close_cb_called++;
|
||||
ol_free(handle);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(close_cb_stack) {
|
||||
ol_handle *handle;
|
||||
|
||||
ol_init();
|
||||
handle = ol_tcp_handle_new(&close_cb, NULL);
|
||||
|
||||
nested++;
|
||||
ol_close(handle);
|
||||
nested--;
|
||||
|
||||
ol_run();
|
||||
|
||||
assert("ol_close_cb not called exactly once" && close_cb_called);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
TEST_DECLARE (echo_server)
|
||||
TEST_DECLARE (ping_pong)
|
||||
TEST_DECLARE (close_cb_stack);
|
||||
TEST_DECLARE (pass_always)
|
||||
TEST_DECLARE (fail_always)
|
||||
|
||||
@ -7,6 +8,8 @@ TEST_LIST_START
|
||||
TEST_ENTRY (ping_pong)
|
||||
TEST_HELPER (ping_pong, echo_server)
|
||||
|
||||
TEST_ENTRY (close_cb_stack)
|
||||
|
||||
TEST_ENTRY (fail_always)
|
||||
|
||||
TEST_ENTRY (pass_always)
|
||||
|
Loading…
x
Reference in New Issue
Block a user