aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows/win_tcpconn.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-02-25 14:56:24 -0800
committerGarrett D'Amore <garrett@damore.org>2024-02-25 14:56:24 -0800
commit8e62028a0db24364ea218007811e58ea11d0b64f (patch)
treeee2c71d2b7ead9514831a9084084b0e676fcb395 /src/platform/windows/win_tcpconn.c
parent08e55b929a64e5762561aa4a0ca5dd16fb14a157 (diff)
downloadnng-8e62028a0db24364ea218007811e58ea11d0b64f.tar.gz
nng-8e62028a0db24364ea218007811e58ea11d0b64f.tar.bz2
nng-8e62028a0db24364ea218007811e58ea11d0b64f.zip
fixes #1543 Deadlock in nng_close(socket)
This looks like a possible problem that may be windows specific involving the flow for IO completion ports. This simplifies the logic a little bit, and should ensure that canceled requests on pipes do not restart.
Diffstat (limited to 'src/platform/windows/win_tcpconn.c')
-rw-r--r--src/platform/windows/win_tcpconn.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/src/platform/windows/win_tcpconn.c b/src/platform/windows/win_tcpconn.c
index cc906803..fad7c495 100644
--- a/src/platform/windows/win_tcpconn.c
+++ b/src/platform/windows/win_tcpconn.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Devolutions <info@devolutions.net>
//
@@ -26,7 +26,7 @@ tcp_recv_start(nni_tcp_conn *c)
unsigned i;
unsigned naiov;
nni_iov *aiov;
- WSABUF * iov;
+ WSABUF *iov;
if (c->closed) {
while ((aio = nni_list_first(&c->recv_aios)) != NULL) {
@@ -68,7 +68,7 @@ again:
static void
tcp_recv_cb(nni_win_io *io, int rv, size_t num)
{
- nni_aio * aio;
+ nni_aio *aio;
nni_tcp_conn *c = io->ptr;
nni_mtx_lock(&c->mtx);
if ((aio = nni_list_first(&c->recv_aios)) == NULL) {
@@ -80,17 +80,18 @@ tcp_recv_cb(nni_win_io *io, int rv, size_t num)
rv = c->recv_rv;
c->recv_rv = 0;
}
+ if ((rv == 0) && (num == 0)) {
+ // A zero byte receive is a remote close from the peer.
+ rv = NNG_ECONNSHUT;
+ }
nni_aio_list_remove(aio);
- tcp_recv_start(c);
if (c->closed) {
nni_cv_wake(&c->cv);
+ } else {
+ tcp_recv_start(c);
}
nni_mtx_unlock(&c->mtx);
- if ((rv == 0) && (num == 0)) {
- // A zero byte receive is a remote close from the peer.
- rv = NNG_ECONNSHUT;
- }
nni_aio_finish_sync(aio, rv, num);
}
@@ -114,7 +115,7 @@ static void
tcp_recv(void *arg, nni_aio *aio)
{
nni_tcp_conn *c = arg;
- int rv;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
@@ -146,7 +147,7 @@ tcp_send_start(nni_tcp_conn *c)
unsigned i;
unsigned naiov;
nni_iov *aiov;
- WSABUF * iov;
+ WSABUF *iov;
if (c->closed) {
while ((aio = nni_list_first(&c->send_aios)) != NULL) {
@@ -204,7 +205,7 @@ tcp_send_cancel(nni_aio *aio, void *arg, int rv)
static void
tcp_send_cb(nni_win_io *io, int rv, size_t num)
{
- nni_aio * aio;
+ nni_aio *aio;
nni_tcp_conn *c = io->ptr;
nni_mtx_lock(&c->mtx);
if ((aio = nni_list_first(&c->send_aios)) == NULL) {
@@ -260,13 +261,8 @@ tcp_close(void *arg)
nni_mtx_lock(&c->mtx);
if (!c->closed) {
c->closed = true;
- if (!nni_list_empty(&c->recv_aios)) {
- CancelIoEx((HANDLE) c->s, &c->recv_io.olpd);
- }
- if (!nni_list_empty(&c->send_aios)) {
- CancelIoEx((HANDLE) c->s, &c->send_io.olpd);
- }
if (c->s != INVALID_SOCKET) {
+ CancelIoEx((HANDLE) c->s, NULL); // cancel everything
shutdown(c->s, SD_BOTH);
}
}