summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Williams <bill_williams@cable.comcast.com>2017-05-22 10:17:41 -0700
committerGarrett D'Amore <garrett@damore.org>2017-09-14 22:42:48 -0700
commit5eb73201f7e7d5e2cd9fe0f7927077d1bc0f0c53 (patch)
tree7203e26a85d0c4d7ce30e35287de03512b408875
parentb60b464dd83ac9ce2e8afba7a393807fad1b38c8 (diff)
downloadnanomsg-5eb73201f7e7d5e2cd9fe0f7927077d1bc0f0c53.tar.gz
clean fix of memory leak in btcp.c when nn_bind returns EADDRINUSE
-rw-r--r--src/aio/fsm.c10
-rw-r--r--src/aio/fsm.h4
-rw-r--r--src/transports/tcp/btcp.c15
3 files changed, 28 insertions, 1 deletions
diff --git a/src/aio/fsm.c b/src/aio/fsm.c
index 33250de..54ec60b 100644
--- a/src/aio/fsm.c
+++ b/src/aio/fsm.c
@@ -178,6 +178,16 @@ void nn_fsm_action (struct nn_fsm *self, int type)
nn_fsm_feed (self, NN_FSM_ACTION, type, NULL);
}
+void nn_fsm_raise_from_src (struct nn_fsm *self, struct nn_fsm_event *event,
+ int src, int type)
+{
+ event->fsm = self;
+ event->src = src;
+ event->srcptr = self->srcptr;
+ event->type = type;
+ nn_ctx_raise (self->ctx, event);
+}
+
void nn_fsm_raise (struct nn_fsm *self, struct nn_fsm_event *event, int type)
{
event->fsm = self->owner;
diff --git a/src/aio/fsm.h b/src/aio/fsm.h
index 19eca1a..5a41aef 100644
--- a/src/aio/fsm.h
+++ b/src/aio/fsm.h
@@ -97,6 +97,10 @@ struct nn_worker *nn_fsm_choose_worker (struct nn_fsm *self);
void nn_fsm_action (struct nn_fsm *self, int type);
/* Send event from the state machine to its owner. */
+void nn_fsm_raise_from_src (struct nn_fsm *self, struct nn_fsm_event *event,
+ int src, int type);
+
+/* Send event from the state machine to its owner. */
void nn_fsm_raise (struct nn_fsm *self, struct nn_fsm_event *event, int type);
diff --git a/src/transports/tcp/btcp.c b/src/transports/tcp/btcp.c
index 4fe8b58..1fdef03 100644
--- a/src/transports/tcp/btcp.c
+++ b/src/transports/tcp/btcp.c
@@ -59,11 +59,16 @@
#define NN_BTCP_SRC_USOCK 1
#define NN_BTCP_SRC_ATCP 2
+#define NN_BTCP_SRC_BTCP 3
+
+#define NN_BTCP_TYPE_LISTEN_ERR 1
+
struct nn_btcp {
/* The state machine. */
struct nn_fsm fsm;
+ struct nn_fsm_event listen_error;
int state;
struct nn_ep *ep;
@@ -143,6 +148,7 @@ int nn_btcp_create (struct nn_ep *ep)
/* Initialise the structure. */
nn_fsm_init_root (&self->fsm, nn_btcp_handler, nn_btcp_shutdown,
nn_ep_getctx (ep));
+ nn_fsm_event_init (&self->listen_error);
self->state = NN_BTCP_STATE_IDLE;
self->atcp = NULL;
nn_list_init (&self->atcps);
@@ -154,7 +160,8 @@ int nn_btcp_create (struct nn_ep *ep)
rc = nn_btcp_listen (self);
if (rc != 0) {
- // I suspect we might need to do nn_free here.
+ nn_fsm_raise_from_src (&self->fsm, &self->listen_error,
+ NN_BTCP_SRC_BTCP, NN_BTCP_TYPE_LISTEN_ERR);
return rc;
}
@@ -267,6 +274,12 @@ static void nn_btcp_handler (struct nn_fsm *self, int src, int type,
/* The execution is yielded to the atcp state machine in this state. */
/******************************************************************************/
case NN_BTCP_STATE_ACTIVE:
+ if (src == NN_BTCP_SRC_BTCP) {
+ nn_assert (type == NN_BTCP_TYPE_LISTEN_ERR);
+ nn_free (btcp);
+ return;
+ }
+
if (src == NN_BTCP_SRC_USOCK) {
/* usock object cleaning up */
nn_assert (type == NN_USOCK_SHUTDOWN || type == NN_USOCK_STOPPED);