diff options
| -rw-r--r-- | src/core/defs.h | 3 | ||||
| -rw-r--r-- | src/core/endpt.c | 11 | ||||
| -rw-r--r-- | src/core/endpt.h | 3 | ||||
| -rw-r--r-- | src/core/pipe.c | 19 | ||||
| -rw-r--r-- | src/core/pipe.h | 24 | ||||
| -rw-r--r-- | src/core/transport.h | 49 | ||||
| -rw-r--r-- | src/transport/inproc/inproc.c | 28 |
7 files changed, 70 insertions, 67 deletions
diff --git a/src/core/defs.h b/src/core/defs.h index d0d0df7b..eb561295 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -25,9 +25,6 @@ typedef struct nng_msg nni_msg; // REMOVE THESE typedef struct nng_endpt nni_endpt; -typedef struct nni_transport nni_transport; -typedef struct nni_endpt_ops nni_endpt_ops; -typedef struct nni_pipe_ops nni_pipe_ops; // These are our own names. typedef struct nni_tran nni_tran; diff --git a/src/core/endpt.c b/src/core/endpt.c index 63013652..e5f46978 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -36,6 +36,12 @@ nni_endpt_create(nni_endpt **epp, nni_sock *sock, const char *addr) ep->ep_close = 0; ep->ep_bound = 0; ep->ep_pipe = NULL; + ep->ep_tran = tran; + + // Make a copy of the endpoint operations. This allows us to + // modify them (to override NULLs for example), and avoids an extra + // dereference on hot paths. + ep->ep_ops = *tran->tran_ep; NNI_LIST_NODE_INIT(&ep->ep_node); if ((rv = nni_cv_init(&ep->ep_cv, &ep->ep_sock->s_mx)) != 0) { @@ -45,9 +51,8 @@ nni_endpt_create(nni_endpt **epp, nni_sock *sock, const char *addr) // Could safely use strcpy here, but this avoids discussion. (void) snprintf(ep->ep_addr, sizeof (ep->ep_addr), "%s", addr); - ep->ep_ops = *tran->tran_ep_ops; - rv = ep->ep_ops.ep_create(&ep->ep_data, addr, nni_sock_proto(sock)); + rv = ep->ep_ops.ep_init(&ep->ep_data, addr, nni_sock_proto(sock)); if (rv != 0) { nni_cv_fini(&ep->ep_cv); NNI_FREE_STRUCT(ep); @@ -88,7 +93,7 @@ nni_endpt_close(nni_endpt *ep) nni_thr_fini(&ep->ep_thr); } - ep->ep_ops.ep_destroy(ep->ep_data); + ep->ep_ops.ep_fini(ep->ep_data); nni_cv_fini(&ep->ep_cv); NNI_FREE_STRUCT(ep); diff --git a/src/core/endpt.h b/src/core/endpt.h index 695ef79a..92e3450a 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -16,7 +16,8 @@ // OUSIDE of the core is STRICTLY VERBOTEN. NO DIRECT ACCESS BY PROTOCOLS // OR TRANSPORTS. struct nng_endpt { - nni_endpt_ops ep_ops; + nni_tran_ep ep_ops; + nni_tran *ep_tran; void * ep_data; // Transport private nni_list_node ep_node; // Per socket list nni_sock * ep_sock; diff --git a/src/core/pipe.c b/src/core/pipe.c index d673f7c4..ce24e28e 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -25,14 +25,14 @@ nni_pipe_id(nni_pipe *p) int nni_pipe_send(nni_pipe *p, nng_msg *msg) { - return (p->p_tran_ops.p_send(p->p_tran_data, msg)); + return (p->p_tran_ops.pipe_send(p->p_tran_data, msg)); } int nni_pipe_recv(nni_pipe *p, nng_msg **msgp) { - return (p->p_tran_ops.p_recv(p->p_tran_data, msgp)); + return (p->p_tran_ops.pipe_recv(p->p_tran_data, msgp)); } @@ -45,7 +45,7 @@ nni_pipe_close(nni_pipe *p) nni_sock *sock = p->p_sock; if (p->p_tran_data != NULL) { - p->p_tran_ops.p_close(p->p_tran_data); + p->p_tran_ops.pipe_close(p->p_tran_data); } nni_mtx_lock(&sock->s_mx); @@ -63,7 +63,7 @@ nni_pipe_close(nni_pipe *p) uint16_t nni_pipe_peer(nni_pipe *p) { - return (p->p_tran_ops.p_peer(p->p_tran_data)); + return (p->p_tran_ops.pipe_peer(p->p_tran_data)); } @@ -74,7 +74,7 @@ nni_pipe_destroy(nni_pipe *p) nni_thr_fini(&p->p_recv_thr); if (p->p_tran_data != NULL) { - p->p_tran_ops.p_destroy(p->p_tran_data); + p->p_tran_ops.pipe_destroy(p->p_tran_data); } if (p->p_pdata != NULL) { nni_free(p->p_pdata, p->p_psize); @@ -95,12 +95,15 @@ nni_pipe_create(nni_pipe **pp, nni_endpt *ep) return (NNG_ENOMEM); } p->p_sock = sock; - p->p_tran_ops = *ep->ep_ops.ep_pipe_ops; p->p_tran_data = NULL; p->p_active = 0; p->p_psize = proto->proto_pipe_size; NNI_LIST_NODE_INIT(&p->p_node); + // Make a copy of the transport ops. We can override entry points + // and we avoid an extra dereference on hot code paths. + p->p_tran_ops = *ep->ep_tran->tran_pipe; + if ((p->p_pdata = nni_alloc(p->p_psize)) == NULL) { NNI_FREE_STRUCT(p); return (NNG_ENOMEM); @@ -132,10 +135,10 @@ int nni_pipe_getopt(nni_pipe *p, int opt, void *val, size_t *szp) { /* This should only be called with the mutex held... */ - if (p->p_tran_ops.p_getopt == NULL) { + if (p->p_tran_ops.pipe_getopt == NULL) { return (NNG_ENOTSUP); } - return (p->p_tran_ops.p_getopt(p->p_tran_data, opt, val, szp)); + return (p->p_tran_ops.pipe_getopt(p->p_tran_data, opt, val, szp)); } diff --git a/src/core/pipe.h b/src/core/pipe.h index 70dd01b1..d3669235 100644 --- a/src/core/pipe.h +++ b/src/core/pipe.h @@ -18,18 +18,18 @@ #include "core/transport.h" struct nng_pipe { - uint32_t p_id; - struct nni_pipe_ops p_tran_ops; - void * p_tran_data; - void * p_pdata; // protocol specific data - size_t p_psize; // size of protocol data - nni_list_node p_node; - nni_sock * p_sock; - nni_endpt * p_ep; - int p_reap; - int p_active; - nni_thr p_send_thr; - nni_thr p_recv_thr; + uint32_t p_id; + nni_tran_pipe p_tran_ops; + void * p_tran_data; + void * p_pdata; // protocol specific data + size_t p_psize; // size of protocol data + nni_list_node p_node; + nni_sock * p_sock; + nni_endpt * p_ep; + int p_reap; + int p_active; + nni_thr p_send_thr; + nni_thr p_recv_thr; }; // Pipe operations that protocols use. diff --git a/src/core/transport.h b/src/core/transport.h index c738929c..8544f097 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -17,8 +17,11 @@ struct nni_tran { // tran_scheme is the transport scheme, such as "tcp" or "inproc". const char * tran_scheme; - // tran_ep_ops links our endpoint operations. - const nni_endpt_ops * tran_ep_ops; + // tran_ep links our endpoint-specific operations. + const nni_tran_ep * tran_ep; + + // tran_pipe links our pipe-specific operations. + const nni_tran_pipe * tran_pipe; // tran_init, if not NULL, is called once during library // initialization. @@ -34,59 +37,53 @@ struct nni_tran { // fashion. The socket makes individual calls, which are expected to block // if appropriate (except for destroy). Endpoints are unable to call back // into the socket, to prevent recusive entry and deadlock. -struct nni_endpt_ops { - // ep_create creates a vanilla endpoint. The value created is +struct nni_tran_ep { + // ep_init creates a vanilla endpoint. The value created is // used for the first argument for all other endpoint functions. - int (*ep_create)(void **, const char *, - uint16_t); + int (*ep_init)(void **, const char *, uint16_t); - // ep_destroy frees the resources associated with the endpoint. + // ep_fini frees the resources associated with the endpoint. // The endpoint will already have been closed. - void (*ep_destroy)(void *); + void (*ep_fini)(void *); // ep_connect establishes a connection, and creates a new pipe, // which is returned in the final argument. It can return errors // NNG_EACCESS, NNG_ECONNREFUSED, NNG_EBADADDR, NNG_ECONNFAILED, // NNG_ETIMEDOUT, and NNG_EPROTO. - int (*ep_connect)(void *, void **); + int (*ep_connect)(void *, void **); // ep_bind just does the bind() and listen() work, // reserving the address but not creating any connections. // It should return NNG_EADDRINUSE if the address is already // taken. It can also return NNG_EBADADDR for an unsuitable // address, or NNG_EACCESS for permission problems. - int (*ep_bind)(void *); + int (*ep_bind)(void *); // ep_accept accepts an inbound connection, and creates // a transport pipe, which is returned in the final argument. - int (*ep_accept)(void *, void **); + int (*ep_accept)(void *, void **); // ep_close stops the endpoint from operating altogether. It does // not affect pipes that have already been created. - void (*ep_close)(void *); + void (*ep_close)(void *); // ep_setopt sets an endpoint (transport-specific) option. - int (*ep_setopt)(void *, int, const void *, - size_t); + int (*ep_setopt)(void *, int, const void *, size_t); // ep_getopt gets an endpoint (transport-specific) option. - int (*ep_getopt)(void *, int, void *, - size_t *); - - // ep_pipe_ops links our pipe operations. - const nni_pipe_ops * ep_pipe_ops; + int (*ep_getopt)(void *, int, void *, size_t *); }; // Pipe operations are entry points called by the socket. These may be called // with socket locks held, so it is forbidden for the transport to call // back into the socket at this point. (Which is one reason pointers back // to socket or even enclosing pipe state, are not provided.) -struct nni_pipe_ops { +struct nni_tran_pipe { // p_destroy destroys the pipe. This should clean up all local // resources, including closing files and freeing memory, used by // the pipe. After this call returns, the system will not make // further calls on the same pipe. - void (*p_destroy)(void *); + void (*pipe_destroy)(void *); // p_send sends the message. If the message cannot be received, then // the caller may try again with the same message (or free it). If @@ -94,7 +91,7 @@ struct nni_pipe_ops { // message, and the caller may not use it again. The transport will // have the responsibility to free the message (nng_msg_free()) when // it is finished with it. - int (*p_send)(void *, nni_msg *); + int (*pipe_send)(void *, nni_msg *); // p_recv recvs the message. This is a blocking operation, and a read // will be performed even for cases where no data is expected. This @@ -102,19 +99,19 @@ struct nni_pipe_ops { // NNG_ECLOSED. Note that the closed socket condition can arise as // either a result of a remote peer closing the connection, or a // synchronous call to p_close. - int (*p_recv)(void *, nng_msg **); + int (*pipe_recv)(void *, nng_msg **); // p_close closes the pipe. Further recv or send operations should // return back NNG_ECLOSED. - void (*p_close)(void *); + void (*pipe_close)(void *); // p_peer returns the peer protocol. This may arrive in whatever // transport specific manner is appropriate. - uint16_t (*p_peer)(void *); + uint16_t (*pipe_peer)(void *); // p_getopt gets an pipe (transport-specific) property. These values // may not be changed once the pipe is created. - int (*p_getopt)(void *, int, void *, size_t *); + int (*pipe_getopt)(void *, int, void *, size_t *); }; // These APIs are used by the framework internally, and not for use by diff --git a/src/transport/inproc/inproc.c b/src/transport/inproc/inproc.c index fe45e78e..ff0e9a2e 100644 --- a/src/transport/inproc/inproc.c +++ b/src/transport/inproc/inproc.c @@ -178,7 +178,7 @@ nni_inproc_pipe_getopt(void *arg, int option, void *buf, size_t *szp) static int -nni_inproc_ep_create(void **epp, const char *url, uint16_t proto) +nni_inproc_ep_init(void **epp, const char *url, uint16_t proto) { nni_inproc_ep *ep; int rv; @@ -207,7 +207,7 @@ nni_inproc_ep_create(void **epp, const char *url, uint16_t proto) static void -nni_inproc_ep_destroy(void *arg) +nni_inproc_ep_fini(void *arg) { nni_inproc_ep *ep = arg; @@ -391,23 +391,22 @@ nni_inproc_ep_accept(void *arg, void **pipep) } -static struct nni_pipe_ops nni_inproc_pipe_ops = { - .p_destroy = nni_inproc_pipe_destroy, - .p_send = nni_inproc_pipe_send, - .p_recv = nni_inproc_pipe_recv, - .p_close = nni_inproc_pipe_close, - .p_peer = nni_inproc_pipe_peer, - .p_getopt = nni_inproc_pipe_getopt, +static nni_tran_pipe nni_inproc_pipe_ops = { + .pipe_destroy = nni_inproc_pipe_destroy, + .pipe_send = nni_inproc_pipe_send, + .pipe_recv = nni_inproc_pipe_recv, + .pipe_close = nni_inproc_pipe_close, + .pipe_peer = nni_inproc_pipe_peer, + .pipe_getopt = nni_inproc_pipe_getopt, }; -static struct nni_endpt_ops nni_inproc_ep_ops = { - .ep_create = nni_inproc_ep_create, - .ep_destroy = nni_inproc_ep_destroy, +static nni_tran_ep nni_inproc_ep_ops = { + .ep_init = nni_inproc_ep_init, + .ep_fini = nni_inproc_ep_fini, .ep_connect = nni_inproc_ep_connect, .ep_bind = nni_inproc_ep_bind, .ep_accept = nni_inproc_ep_accept, .ep_close = nni_inproc_ep_close, - .ep_pipe_ops = &nni_inproc_pipe_ops, .ep_setopt = NULL, .ep_getopt = NULL, }; @@ -416,7 +415,8 @@ static struct nni_endpt_ops nni_inproc_ep_ops = { // symbol in this entire file. struct nni_tran nni_inproc_tran = { .tran_scheme = "inproc", - .tran_ep_ops = &nni_inproc_ep_ops, + .tran_ep = &nni_inproc_ep_ops, + .tran_pipe = &nni_inproc_pipe_ops, .tran_init = nni_inproc_init, .tran_fini = nni_inproc_fini, }; |
