New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gdamore/win io lock #1831
base: master
Are you sure you want to change the base?
Gdamore/win io lock #1831
Conversation
When closing pipes, we defer them to be reaped, but also leave them in the match list where they might be picked up by ep_match, or leak. It's best to reap these proactively and ensure that they are not allowed to life longer once they have errored during the negotiation phase.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1831 +/- ##
==========================================
+ Coverage 79.32% 79.50% +0.17%
==========================================
Files 95 95
Lines 21491 21484 -7
==========================================
+ Hits 17048 17081 +33
+ Misses 4443 4403 -40 ☔ View full report in Codecov by Sentry. |
src/platform/windows/win_io.c
Outdated
@@ -23,6 +23,8 @@ static int win_io_nthr = 0; | |||
static HANDLE win_io_h = NULL; | |||
static nni_thr *win_io_thrs; | |||
|
|||
static SRWLock win_io_lock = SRWLOCK_INIT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static SRWLock win_io_lock = SRWLOCK_INIT; | |
static SRWLOCK win_io_lock = SRWLOCK_INIT; |
src/platform/windows/win_io.c
Outdated
DWORD num; | ||
// Make absolutely sure there is no I/O running. | ||
if (io->f != INVALID_HANDLE) { | ||
CancelIoEx(io->f, &o->olpd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CancelIoEx(io->f, &o->olpd); | |
CancelIoEx(io->f, &io->olpd); |
src/platform/windows/win_io.c
Outdated
CloseHandle((HANDLE) io->olpd.hEvent); | ||
DWORD num; | ||
// Make absolutely sure there is no I/O running. | ||
if (io->f != INVALID_HANDLE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (io->f != INVALID_HANDLE) { | |
if (io->f != INVALID_HANDLE_VALUE) { |
src/platform/windows/win_ipclisten.c
Outdated
@@ -331,7 +331,8 @@ nni_ipc_listener_alloc(nng_stream_listener **lp, const nng_url *url) | |||
if ((l = NNI_ALLOC_STRUCT(l)) == NULL) { | |||
return (NNG_ENOMEM); | |||
} | |||
if ((rv = nni_win_io_init(&l->io, ipc_accept_cb, l)) != 0) { | |||
if ((rv = nni_win_io_init(&l->io, INVALID_HANDLE, ipc_accept_cb, l)) != |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((rv = nni_win_io_init(&l->io, INVALID_HANDLE, ipc_accept_cb, l)) != | |
if ((rv = nni_win_io_init(&l->io, INVALID_HANDLE_VALUE, ipc_accept_cb, l)) != |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code does compile after applying the suggestions - but the use-after-free is not solved
@@ -61,26 +69,44 @@ nni_win_io_register(HANDLE h) | |||
} | |||
|
|||
int | |||
nni_win_io_init(nni_win_io *io, nni_win_io_cb cb, void *ptr) | |||
nni_win_io_init(nni_win_io *io, HANDLE h, nni_win_io_cb cb, void *ptr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to update the header file as well
src/platform/windows/win_tcpconn.c
Outdated
if (((rv = nni_win_io_init(&c->recv_io, s, tcp_recv_cb, c)) != 0) || | ||
((rv = nni_win_io_init(&c->send_io, s, tcp_send_cb, c)) != 0) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (((rv = nni_win_io_init(&c->recv_io, s, tcp_recv_cb, c)) != 0) || | |
((rv = nni_win_io_init(&c->send_io, s, tcp_send_cb, c)) != 0) || | |
if (((rv = nni_win_io_init(&c->recv_io, (HANDLE) s, tcp_recv_cb, c)) != 0) || | |
((rv = nni_win_io_init(&c->send_io, (HANDLE) s, tcp_send_cb, c)) != 0) || |
src/platform/windows/win_tcpconn.c
Outdated
@@ -448,8 +448,8 @@ nni_win_tcp_init(nni_tcp_conn **connp, SOCKET s) | |||
c->ops.s_get = tcp_get; | |||
c->ops.s_set = tcp_set; | |||
|
|||
if (((rv = nni_win_io_init(&c->recv_io, tcp_recv_cb, c)) != 0) || | |||
((rv = nni_win_io_init(&c->send_io, tcp_send_cb, c)) != 0) || | |||
if (((rv = nni_win_io_init(&c->recv_io, s, tcp_recv_cb, c)) != 0) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remember to update the function declaration in win_impl.h:125
src/platform/windows/win_tcplisten.c
Outdated
@@ -322,7 +322,7 @@ nni_tcp_listener_accept(nni_tcp_listener *l, nni_aio *aio) | |||
c->listener = l; | |||
c->conn_aio = aio; | |||
nni_aio_set_prov_data(aio, c); | |||
if (((rv = nni_win_io_init(&c->conn_io, tcp_accept_cb, c)) != 0) || | |||
if (((rv = nni_win_io_init(&c->conn_io, s, tcp_accept_cb, c)) != 0) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (((rv = nni_win_io_init(&c->conn_io, s, tcp_accept_cb, c)) != 0) || | |
if (((rv = nni_win_io_init(&c->conn_io, (HANDLE) s, tcp_accept_cb, c)) != 0) || |
src/platform/windows/win_tcpdial.c
Outdated
@@ -208,7 +208,7 @@ nni_tcp_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) | |||
|
|||
c->peername = ss; | |||
|
|||
if ((rv = nni_win_io_init(&c->conn_io, tcp_dial_cb, c)) != 0) { | |||
if ((rv = nni_win_io_init(&c->conn_io, s, tcp_dial_cb, c)) != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((rv = nni_win_io_init(&c->conn_io, s, tcp_dial_cb, c)) != 0) { | |
if ((rv = nni_win_io_init(&c->conn_io, (HANDLE) s, tcp_dial_cb, c)) != 0) { |
src/platform/windows/win_udp.c
Outdated
@@ -67,7 +67,7 @@ nni_plat_udp_open(nni_plat_udp **udpp, nni_sockaddr *sa) | |||
(void) setsockopt( | |||
u->s, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &no, sizeof(no)); | |||
|
|||
if (((rv = nni_win_io_init(&u->rxio, udp_recv_cb, u)) != 0) || | |||
if (((rv = nni_win_io_init(&u->rxio, u->s, udp_recv_cb, u)) != 0) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (((rv = nni_win_io_init(&u->rxio, u->s, udp_recv_cb, u)) != 0) || | |
if (((rv = nni_win_io_init(&u->rxio, (HANDLE) u->s, udp_recv_cb, u)) != 0) || |
Hi @alzix - obviously I didn't get a chance to try building this on Windows myself (except via CI/CID) before I ran out of time. I'll fix these .. .but if you've already done so, can you tell me if the approach at least resolves the problems you've been observing? |
For the sake of completeness I want to mention that the reqrep code provided by @alzix also sometimes crashes in |
I also saw the crash in the |
HI @gdamore, I also tried this branch on a Windows machine and got the same crash: It seems that when calling It is very easy to reproduce as it happens almost immediately when running the modified reqrep demo. |
Hi @gdamore and all. I've been looking into this and it seems as if the pipe is being deallocated/freed (in Also worth mentioning that sometimes, not very often though there's no crash but a deadlock, where both client and server are waiting on signals. |
THanks -- I've been looking at this in spare cycles, but very few such cycles exist, which is why it's taking time. I'll try to get to it in a day or so. |
So the design is meant to ensure that all callbacks are done, and the pipe is totally unregistered before we freed it. I've missed something. I'm going to resolve this one way the other this weekend. |
This is a trial run, and it may or may not work.