aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/aio.c150
-rw-r--r--src/core/aio.h96
-rw-r--r--src/core/defs.h4
-rw-r--r--src/core/device.c8
-rw-r--r--src/core/endpt.c10
-rw-r--r--src/core/msgqueue.c6
-rw-r--r--src/core/msgqueue.h4
-rw-r--r--src/core/pipe.c12
-rw-r--r--src/core/pipe.h4
-rw-r--r--src/core/protocol.h4
-rw-r--r--src/core/socket.c20
-rw-r--r--src/core/socket.h6
-rw-r--r--src/core/transport.c1
-rw-r--r--src/core/url.c5
-rw-r--r--src/core/url.h1
15 files changed, 201 insertions, 130 deletions
diff --git a/src/core/aio.c b/src/core/aio.c
index a036a606..341b218e 100644
--- a/src/core/aio.c
+++ b/src/core/aio.c
@@ -54,6 +54,57 @@ static nni_list nni_aio_expire_aios;
// if it comes back nonzero (NNG_ESTATE) then it must simply discard the
// request and return.
+// An nni_aio is an async I/O handle.
+struct nng_aio {
+ int a_result; // Result code (nng_errno)
+ size_t a_count; // Bytes transferred (I/O only)
+ nni_time a_expire; // Absolute timeout
+ nni_duration a_timeout; // Relative timeout
+
+ // These fields are private to the aio framework.
+ nni_cv a_cv;
+ unsigned a_fini : 1; // shutting down (no new operations)
+ unsigned a_done : 1; // operation has completed
+ unsigned a_pend : 1; // completion routine pending
+ unsigned a_active : 1; // aio was started
+ unsigned a_expiring : 1; // expiration callback in progress
+ unsigned a_waiting : 1; // a thread is waiting for this to finish
+ unsigned a_synch : 1; // run completion synchronously
+ nni_task a_task;
+
+ // Read/write operations.
+ nni_iov *a_iov;
+ int a_niov;
+ nni_iov a_iovinl[4]; // inline IOVs - when the IOV list is short
+ nni_iov *a_iovalloc; // dynamically allocated IOVs
+ int a_niovalloc; // number of allocated IOVs
+
+ // Message operations.
+ nni_msg *a_msg;
+
+ // Connect/accept operations.
+ void *a_pipe; // opaque pipe handle
+
+ // User scratch data. Consumers may store values here, which
+ // must be preserved by providers and the framework.
+ void *a_user_data[4];
+
+ // Operation inputs & outputs. Up to 4 inputs and 4 outputs may be
+ // specified. The semantics of these will vary, and depend on the
+ // specific operation.
+ void *a_inputs[4];
+ void *a_outputs[4];
+
+ // Provider-use fields.
+ nni_aio_cancelfn a_prov_cancel;
+ void * a_prov_data;
+ nni_list_node a_prov_node;
+ void * a_prov_extra[4]; // Extra data used by provider
+
+ // Expire node.
+ nni_list_node a_expire_node;
+};
+
static void nni_aio_expire_add(nni_aio *);
int
@@ -88,7 +139,7 @@ nni_aio_fini(nni_aio *aio)
nni_cv_fini(&aio->a_cv);
if (aio->a_niovalloc > 0) {
- NNI_FREE_STRUCTS(aio->a_iov, aio->a_niovalloc);
+ NNI_FREE_STRUCTS(aio->a_iovalloc, aio->a_niovalloc);
}
NNI_FREE_STRUCT(aio);
@@ -96,21 +147,27 @@ nni_aio_fini(nni_aio *aio)
}
int
-nni_aio_set_iov(nni_aio *aio, int niov, nng_iov *iov)
+nni_aio_set_iov(nni_aio *aio, int niov, const nni_iov *iov)
{
- if ((niov > 4) && (niov > aio->a_niovalloc)) {
+ if ((niov > NNI_NUM_ELEMENTS(aio->a_iovinl)) &&
+ (niov > aio->a_niovalloc)) {
nni_iov *newiov = NNI_ALLOC_STRUCTS(newiov, niov);
if (newiov == NULL) {
return (NNG_ENOMEM);
}
if (aio->a_niovalloc > 0) {
- NNI_FREE_STRUCTS(aio->a_iov, aio->a_niovalloc);
+ NNI_FREE_STRUCTS(aio->a_iovalloc, aio->a_niovalloc);
}
aio->a_iov = newiov;
+ aio->a_iovalloc = newiov;
aio->a_niovalloc = niov;
}
-
- memcpy(aio->a_iov, iov, niov * sizeof(nng_iov));
+ if (niov <= NNI_NUM_ELEMENTS(aio->a_iovinl)) {
+ aio->a_iov = aio->a_iovinl;
+ } else {
+ aio->a_iov = aio->a_iovalloc;
+ }
+ memcpy(aio->a_iov, iov, niov * sizeof(nni_iov));
aio->a_niov = niov;
return (0);
}
@@ -136,7 +193,7 @@ nni_aio_stop(nni_aio *aio)
aio->a_fini = 1;
nni_mtx_unlock(&nni_aio_lk);
- nni_aio_cancel(aio, NNG_ECANCELED);
+ nni_aio_abort(aio, NNG_ECANCELED);
nni_aio_wait(aio);
}
@@ -293,10 +350,10 @@ nni_aio_start(nni_aio *aio, nni_aio_cancelfn cancelfn, void *data)
return (0);
}
-// nni_aio_cancel is called by a consumer which guarantees that the aio
+// nni_aio_abort is called by a consumer which guarantees that the aio
// is still valid.
void
-nni_aio_cancel(nni_aio *aio, int rv)
+nni_aio_abort(nni_aio *aio, int rv)
{
nni_aio_cancelfn cancelfn;
@@ -502,6 +559,81 @@ nni_aio_expire_loop(void *arg)
}
}
+void *
+nni_aio_get_prov_data(nni_aio *aio)
+{
+ return (aio->a_prov_data);
+}
+
+void
+nni_aio_set_prov_data(nni_aio *aio, void *data)
+{
+ aio->a_prov_data = data;
+}
+
+void *
+nni_aio_get_prov_extra(nni_aio *aio, unsigned index)
+{
+ return (aio->a_prov_extra[index]);
+}
+
+void
+nni_aio_set_prov_extra(nni_aio *aio, unsigned index, void *data)
+{
+ aio->a_prov_extra[index] = data;
+}
+
+void
+nni_aio_get_iov(nni_aio *aio, int *niovp, nni_iov **iovp)
+{
+ *niovp = aio->a_niov;
+ *iovp = aio->a_iov;
+}
+
+void
+nni_aio_normalize_timeout(nni_aio *aio, nng_duration dur)
+{
+ if (aio->a_timeout == NNG_DURATION_DEFAULT) {
+ aio->a_timeout = dur;
+ }
+}
+
+void
+nni_aio_bump_count(nni_aio *aio, size_t n)
+{
+ aio->a_count += n;
+}
+
+size_t
+nni_aio_iov_count(nni_aio *aio)
+{
+ size_t resid = 0;
+
+ for (int i = 0; i < aio->a_niov; i++) {
+ resid += aio->a_iov[i].iov_len;
+ }
+ return (resid);
+}
+
+size_t
+nni_aio_iov_advance(nni_aio *aio, size_t n)
+{
+ size_t resid = n;
+ while (n) {
+ NNI_ASSERT(aio->a_niov != 0);
+ if (aio->a_iov[0].iov_len > n) {
+ aio->a_iov[0].iov_len -= n;
+ NNI_INCPTR(aio->a_iov[0].iov_buf, n);
+ return (0); // we used all of "n"
+ }
+ resid -= aio->a_iov[0].iov_len;
+ n -= aio->a_iov[0].iov_len;
+ aio->a_iov = &aio->a_iov[1];
+ aio->a_niov--;
+ }
+ return (resid); // we might not have used all of n for this iov
+}
+
void
nni_aio_sys_fini(void)
{
diff --git a/src/core/aio.h b/src/core/aio.h
index 33fe07cb..34f4a56b 100644
--- a/src/core/aio.h
+++ b/src/core/aio.h
@@ -20,59 +20,6 @@ typedef struct nni_aio_ops nni_aio_ops;
typedef void (*nni_aio_cancelfn)(nni_aio *, int);
-// An nni_aio is an async I/O handle.
-struct nni_aio {
- int a_result; // Result code (nng_errno)
- size_t a_count; // Bytes transferred (I/O only)
- nni_time a_expire; // Absolute timeout
- nni_duration a_timeout; // Relative timeout
-
- // These fields are private to the aio framework.
- nni_cv a_cv;
- unsigned a_fini : 1; // shutting down (no new operations)
- unsigned a_done : 1; // operation has completed
- unsigned a_pend : 1; // completion routine pending
- unsigned a_active : 1; // aio was started
- unsigned a_expiring : 1; // expiration callback in progress
- unsigned a_waiting : 1; // a thread is waiting for this to finish
- unsigned a_synch : 1; // run completion synchronously
- nni_task a_task;
-
- // Read/write operations.
- nni_iov *a_iov;
- int a_niov;
- nni_iov a_iovinl[4]; // inline IOVs - when the IOV list is short
- int a_niovalloc; // number of allocated IOVs
-
- // Message operations.
- nni_msg *a_msg;
-
- // Connect/accept operations.
- void *a_pipe; // opaque pipe handle
-
- // Resolver operations.
- nni_sockaddr *a_addr;
-
- // User scratch data. Consumers may store values here, which
- // must be preserved by providers and the framework.
- void *a_user_data[4];
-
- // Operation inputs & outputs. Up to 4 inputs and 4 outputs may be
- // specified. The semantics of these will vary, and depend on the
- // specific operation.
- void *a_inputs[4];
- void *a_outputs[4];
-
- // Provider-use fields.
- nni_aio_cancelfn a_prov_cancel;
- void * a_prov_data;
- nni_list_node a_prov_node;
- void * a_prov_extra[4]; // Extra data used by provider
-
- // Expire node.
- nni_list_node a_expire_node;
-};
-
// nni_aio_init initializes an aio object. The callback is called with
// the supplied argument when the operation is complete. If NULL is
// supplied for the callback, then nni_aio_wake is used in its place,
@@ -128,11 +75,6 @@ extern void nni_aio_set_output(nni_aio *, int, void *);
// nni_get_output returns an output previously stored on the AIO.
extern void *nni_aio_get_output(nni_aio *, int);
-// nni_aio_set_iov sets an IOV (scatter/gather vector) on the AIO.
-// Up to 4 may be set without any possibility of failure, more than that
-// may require an allocation and hence fail due to NNG_ENOMEM.
-extern int nni_aio_set_iov(nni_aio *, int, nng_iov *);
-
// XXX: These should be refactored in terms of generic inputs and outputs.
extern void nni_aio_set_msg(nni_aio *, nni_msg *);
extern nni_msg *nni_aio_get_msg(nni_aio *);
@@ -152,11 +94,6 @@ extern void * nni_aio_get_pipe(nni_aio *);
// completion callback.
void nni_aio_set_synch(nni_aio *);
-// nni_aio_set_timeout sets the timeout (relative) when the AIO will
-// be canceled. The cancelation does not happen until after nni_aio_start
-// is called.
-extern void nni_aio_set_timeout(nni_aio *, nni_duration);
-
// nni_aio_result returns the result code (0 on success, or an NNG errno)
// for the operation. It is only valid to call this when the operation is
// complete (such as when the callback is executed or after nni_aio_wait
@@ -192,19 +129,30 @@ extern void nni_aio_finish_error(nni_aio *, int);
extern void nni_aio_finish_pipe(nni_aio *, void *);
extern void nni_aio_finish_msg(nni_aio *, nni_msg *);
-// nni_aio_cancel is used to cancel an operation. Any pending I/O or
+// nni_aio_abort is used to abort an operation. Any pending I/O or
// timeouts are canceled if possible, and the callback will be returned
// with the indicated result (NNG_ECLOSED or NNG_ECANCELED is recommended.)
-extern void nni_aio_cancel(nni_aio *, int rv);
-
-extern int nni_aio_start(nni_aio *, nni_aio_cancelfn, void *);
-
-// nni_aio_stop is used to abort all further operations on the AIO.
-// When this is executed, no further operations or callbacks will be
-// executed, and if callbacks or I/O is in progress this will block
-// until they are either canceled or aborted. (Question: why not just
-// nni_fini?)
-// extern void nni_aio_stop(nni_aio *);
+extern void nni_aio_abort(nni_aio *, int rv);
+
+extern int nni_aio_start(nni_aio *, nni_aio_cancelfn, void *);
+extern void *nni_aio_get_prov_data(nni_aio *);
+extern void nni_aio_set_prov_data(nni_aio *, void *);
+extern void *nni_aio_get_prov_extra(nni_aio *, unsigned);
+extern void nni_aio_set_prov_extra(nni_aio *, unsigned, void *);
+// nni_aio_advance_iov moves up the iov, reflecting that some I/O as
+// been performed. It returns the amount of data remaining in the argument;
+// i.e. if the count refers to more data than the iov can support, then
+// the result will be left over count.
+extern size_t nni_aio_iov_advance(nni_aio *, size_t);
+// nni_aio_iov_count returns the number of bytes referenced by the aio's iov.
+extern size_t nni_aio_iov_count(nni_aio *);
+
+extern int nni_aio_set_iov(nni_aio *, int, const nni_iov *);
+
+extern void nni_aio_set_timeout(nni_aio *, nng_duration);
+extern void nni_aio_get_iov(nni_aio *, int *, nni_iov **);
+extern void nni_aio_normalize_timeout(nni_aio *, nng_duration);
+extern void nni_aio_bump_count(nni_aio *, size_t);
extern int nni_aio_sys_init(void);
extern void nni_aio_sys_fini(void);
diff --git a/src/core/defs.h b/src/core/defs.h
index fbf074b4..dbbccf58 100644
--- a/src/core/defs.h
+++ b/src/core/defs.h
@@ -30,12 +30,14 @@
#define NNI_NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0]))
// These types are common but have names shared with user space.
+// Internal code should use these names when possible.
typedef struct nng_msg nni_msg;
typedef struct nng_sockaddr nni_sockaddr;
typedef struct nng_event nni_event;
typedef struct nng_notify nni_notify;
typedef struct nng_url nni_url;
typedef struct nng_iov nni_iov;
+typedef struct nng_aio nni_aio;
// These are our own names.
typedef struct nni_socket nni_sock;
@@ -62,8 +64,6 @@ typedef int nni_signal; // Wakeup channel.
typedef uint64_t nni_time; // Abs. time (ms).
typedef int32_t nni_duration; // Rel. time (ms).
-typedef struct nni_aio nni_aio;
-
typedef void (*nni_cb)(void *);
// Notify descriptor.
diff --git a/src/core/device.c b/src/core/device.c
index e6b75897..0eaec30e 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.com>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -38,7 +38,7 @@ typedef struct nni_device_pair nni_device_pair;
static void
nni_device_cancel(nni_aio *aio, int rv)
{
- nni_device_data *dd = aio->a_prov_data;
+ nni_device_data *dd = nni_aio_get_prov_data(aio);
// cancellation is the only path to shutting it down.
nni_mtx_lock(&dd->mtx);
@@ -63,7 +63,7 @@ nni_device_cb(void *arg)
if ((rv = nni_aio_result(aio)) != 0) {
p->state = NNI_DEVICE_STATE_FINI;
- nni_aio_cancel(p->user, rv);
+ nni_aio_abort(p->user, rv);
return;
}
diff --git a/src/core/endpt.c b/src/core/endpt.c
index cfabcc87..4a2c3097 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -249,10 +249,10 @@ nni_ep_shutdown(nni_ep *ep)
nni_mtx_unlock(&ep->ep_mtx);
// Abort any remaining in-flight operations.
- nni_aio_cancel(ep->ep_acc_aio, NNG_ECLOSED);
- nni_aio_cancel(ep->ep_con_aio, NNG_ECLOSED);
- nni_aio_cancel(ep->ep_con_syn, NNG_ECLOSED);
- nni_aio_cancel(ep->ep_tmo_aio, NNG_ECLOSED);
+ nni_aio_abort(ep->ep_acc_aio, NNG_ECLOSED);
+ nni_aio_abort(ep->ep_con_aio, NNG_ECLOSED);
+ nni_aio_abort(ep->ep_con_syn, NNG_ECLOSED);
+ nni_aio_abort(ep->ep_tmo_aio, NNG_ECLOSED);
// Stop the underlying transport.
ep->ep_ops.ep_close(ep->ep_data);
@@ -296,7 +296,7 @@ nni_ep_close(nni_ep *ep)
static void
nni_ep_tmo_cancel(nni_aio *aio, int rv)
{
- nni_ep *ep = aio->a_prov_data;
+ nni_ep *ep = nni_aio_get_prov_data(aio);
// The only way this ever gets "finished", is via cancellation.
if (ep != NULL) {
nni_mtx_lock(&ep->ep_mtx);
diff --git a/src/core/msgqueue.c b/src/core/msgqueue.c
index 10bffaa4..de4708fe 100644
--- a/src/core/msgqueue.c
+++ b/src/core/msgqueue.c
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -338,7 +338,7 @@ nni_msgq_set_cb(nni_msgq *mq, nni_msgq_cb fn, void *arg)
static void
nni_msgq_cancel(nni_aio *aio, int rv)
{
- nni_msgq *mq = aio->a_prov_data;
+ nni_msgq *mq = nni_aio_get_prov_data(aio);
nni_mtx_lock(&mq->mq_lock);
if (nni_aio_list_active(aio)) {
diff --git a/src/core/msgqueue.h b/src/core/msgqueue.h
index ececf372..9cc650e0 100644
--- a/src/core/msgqueue.h
+++ b/src/core/msgqueue.h
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
diff --git a/src/core/pipe.c b/src/core/pipe.c
index 66e7ae87..daee3834 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -201,7 +201,7 @@ nni_pipe_close(nni_pipe *p)
nni_mtx_unlock(&p->p_mtx);
// abort any pending negotiation/start process.
- nni_aio_cancel(p->p_start_aio, NNG_ECLOSED);
+ nni_aio_abort(p->p_start_aio, NNG_ECLOSED);
}
void
@@ -274,11 +274,11 @@ nni_pipe_create(nni_ep *ep, void *tdata)
nni_mtx_init(&p->p_mtx);
nni_cv_init(&p->p_cv, &nni_pipe_lk);
- nni_aio_init(&p->p_start_aio, nni_pipe_start_cb, p);
-
- nni_mtx_lock(&nni_pipe_lk);
- rv = nni_idhash_alloc(nni_pipes, &p->p_id, p);
- nni_mtx_unlock(&nni_pipe_lk);
+ if ((rv = nni_aio_init(&p->p_start_aio, nni_pipe_start_cb, p)) == 0) {
+ nni_mtx_lock(&nni_pipe_lk);
+ rv = nni_idhash_alloc(nni_pipes, &p->p_id, p);
+ nni_mtx_unlock(&nni_pipe_lk);
+ }
if ((rv != 0) || ((rv = nni_ep_pipe_add(ep, p)) != 0) ||
((rv = nni_sock_pipe_add(sock, p)) != 0)) {
diff --git a/src/core/pipe.h b/src/core/pipe.h
index 54629810..32871335 100644
--- a/src/core/pipe.h
+++ b/src/core/pipe.h
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
diff --git a/src/core/protocol.h b/src/core/protocol.h
index 39bde059..47ddfd3f 100644
--- a/src/core/protocol.h
+++ b/src/core/protocol.h
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
diff --git a/src/core/socket.c b/src/core/socket.c
index 409e4f66..bf97ef8d 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -126,7 +126,8 @@ nni_sock_getopt_fd(nni_sock *s, int flag, void *val, size_t *szp)
cb = nni_sock_can_recv_cb;
break;
default:
- nni_panic("default case!");
+ // This should never occur.
+ return (NNG_EINVAL);
}
// If we already inited this, just give back the same file descriptor.
@@ -772,25 +773,17 @@ nni_sock_closeall(void)
}
}
-static void
-nni_sock_normalize_expiration(nni_aio *aio, nni_duration def)
-{
- if (aio->a_timeout == (nni_duration) -2) {
- aio->a_timeout = def;
- }
-}
-
void
nni_sock_send(nni_sock *sock, nni_aio *aio)
{
- nni_sock_normalize_expiration(aio, sock->s_sndtimeo);
+ nni_aio_normalize_timeout(aio, sock->s_sndtimeo);
sock->s_sock_ops.sock_send(sock->s_data, aio);
}
void
nni_sock_recv(nni_sock *sock, nni_aio *aio)
{
- nni_sock_normalize_expiration(aio, sock->s_rcvtimeo);
+ nni_aio_normalize_timeout(aio, sock->s_rcvtimeo);
sock->s_sock_ops.sock_recv(sock->s_data, aio);
}
@@ -872,7 +865,6 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size)
{
int rv = NNG_ENOTSUP;
nni_ep * ep;
- int commits = 0;
nni_sockopt * optv;
nni_sockopt * oldv = NULL;
const nni_socket_option * sso;
diff --git a/src/core/socket.h b/src/core/socket.h
index 37c67436..30561d49 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -1,6 +1,6 @@
//
-// Copyright 2017 Garrett D'Amore <garrett@damore.org>
-// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -39,7 +39,7 @@ extern uint32_t nni_sock_id(nni_sock *);
// a pipe could wind up orphaned.
extern int nni_sock_pipe_add(nni_sock *, nni_pipe *);
extern void nni_sock_pipe_remove(nni_sock *, nni_pipe *);
-extern int nni_sock_pipe_start(nni_sock *, nni_pipe *p);
+extern int nni_sock_pipe_start(nni_sock *, nni_pipe *p);
extern int nni_sock_ep_add(nni_sock *, nni_ep *);
extern void nni_sock_ep_remove(nni_sock *, nni_ep *);
diff --git a/src/core/transport.c b/src/core/transport.c
index 38f88c4d..b48c7da6 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -38,7 +38,6 @@ nni_tran_register(const nni_tran *tran)
{
nni_transport *t;
int rv;
- size_t sz;
// Its entirely possible that we are called before any sockets
// are opened. Make sure we are initialized. This has to be
diff --git a/src/core/url.c b/src/core/url.c
index 3d8898bd..88a0cf0a 100644
--- a/src/core/url.c
+++ b/src/core/url.c
@@ -225,7 +225,7 @@ static struct {
// clang-format on
};
-static const char *
+const char *
nni_url_default_port(const char *scheme)
{
const char *s;
@@ -255,7 +255,6 @@ nni_url_parse(nni_url **urlp, const char *raw)
{
nni_url * url;
size_t len;
- int outlen;
const char *s;
char c;
int rv;
@@ -480,4 +479,4 @@ nni_url_clone(nni_url **dstp, const nni_url *src)
#undef URL_COPYSTR
*dstp = dst;
return (0);
-} \ No newline at end of file
+}
diff --git a/src/core/url.h b/src/core/url.h
index 27aec445..b3407277 100644
--- a/src/core/url.h
+++ b/src/core/url.h
@@ -27,5 +27,6 @@ struct nni_url {
extern int nni_url_parse(nni_url **, const char *path);
extern void nni_url_free(nni_url *);
extern int nni_url_clone(nni_url **, const nni_url *);
+extern const char *nni_url_default_port(const char *);
#endif // CORE_URL_H