summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-23 18:30:51 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-23 21:14:49 -0700
commit68ff9c823d3cead2b11a003c40c8f5affc11dc71 (patch)
tree55673a26565a7ceef918f21e198e5c7698971f73 /src/core
parent2ec64a78da8df01ec534161475a87989ae527776 (diff)
downloadnng-68ff9c823d3cead2b11a003c40c8f5affc11dc71.tar.gz
nng-68ff9c823d3cead2b11a003c40c8f5affc11dc71.tar.bz2
nng-68ff9c823d3cead2b11a003c40c8f5affc11dc71.zip
Add init/fini to protocols to allow them to register options.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/init.c2
-rw-r--r--src/core/protocol.c69
-rw-r--r--src/core/protocol.h15
3 files changed, 85 insertions, 1 deletions
diff --git a/src/core/init.c b/src/core/init.c
index 54c72c5e..36f96d61 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -25,6 +25,7 @@ nni_init_helper(void)
((rv = nni_sock_sys_init()) != 0) ||
((rv = nni_ep_sys_init()) != 0) ||
((rv = nni_pipe_sys_init()) != 0) ||
+ ((rv = nni_proto_sys_init()) != 0) ||
((rv = nni_tran_sys_init()) != 0)) {
nni_fini();
}
@@ -41,6 +42,7 @@ void
nni_fini(void)
{
nni_tran_sys_fini();
+ nni_proto_sys_fini();
nni_pipe_sys_fini();
nni_ep_sys_fini();
nni_sock_sys_fini();
diff --git a/src/core/protocol.c b/src/core/protocol.c
index 7faf9068..e36bc31f 100644
--- a/src/core/protocol.c
+++ b/src/core/protocol.c
@@ -13,6 +13,44 @@
#include "core/nng_impl.h"
// Protocol related stuff - generically.
+typedef struct nni_protocol nni_protocol;
+struct nni_protocol {
+ const nni_proto *p_proto;
+ nni_list_node p_link;
+};
+
+static nni_mtx nni_proto_lk;
+static nni_list nni_proto_list;
+static int nni_proto_inited = 0;
+
+static int
+nni_proto_init(const nni_proto *proto)
+{
+ nni_protocol *p;
+ int rv;
+
+ nni_mtx_lock(&nni_proto_lk);
+ NNI_LIST_FOREACH (&nni_proto_list, p) {
+ if (p->p_proto == proto) {
+ nni_mtx_unlock(&nni_proto_lk);
+ return (0);
+ }
+ }
+ if ((p = NNI_ALLOC_STRUCT(p)) == NULL) {
+ nni_mtx_unlock(&nni_proto_lk);
+ return (NNG_ENOMEM);
+ }
+ NNI_LIST_NODE_INIT(&p->p_link);
+ p->p_proto = proto;
+ if ((proto->proto_init != NULL) && ((rv = proto->proto_init()) != 0)) {
+ NNI_FREE_STRUCT(p);
+ nni_mtx_unlock(&nni_proto_lk);
+ return (rv);
+ }
+ nni_list_append(&nni_proto_list, p);
+ nni_mtx_unlock(&nni_proto_lk);
+ return (0);
+}
int
nni_proto_open(nng_socket *sockidp, const nni_proto *proto)
@@ -20,8 +58,39 @@ nni_proto_open(nng_socket *sockidp, const nni_proto *proto)
int rv;
nni_sock *sock;
+ if (((rv = nni_init()) != 0) || ((rv = nni_proto_init(proto)) != 0)) {
+ return (rv);
+ }
if ((rv = nni_sock_open(&sock, proto)) == 0) {
*sockidp = nni_sock_id(sock); // Keep socket held open.
}
return (rv);
}
+
+int
+nni_proto_sys_init(void)
+{
+ NNI_LIST_INIT(&nni_proto_list, nni_protocol, p_link);
+ nni_mtx_init(&nni_proto_lk);
+ nni_proto_inited = 1;
+ return (0);
+}
+
+void
+nni_proto_sys_fini(void)
+{
+ if (nni_proto_inited) {
+ nni_protocol *p;
+ nni_mtx_lock(&nni_proto_lk);
+ while ((p = nni_list_first(&nni_proto_list)) != NULL) {
+ nni_list_remove(&nni_proto_list, p);
+ if (p->p_proto->proto_fini != NULL) {
+ p->p_proto->proto_fini();
+ }
+ NNI_FREE_STRUCT(p);
+ }
+ nni_mtx_unlock(&nni_proto_lk);
+ }
+ nni_proto_inited = 0;
+ nni_mtx_fini(&nni_proto_lk);
+} \ No newline at end of file
diff --git a/src/core/protocol.h b/src/core/protocol.h
index 14954b49..9416b2bf 100644
--- a/src/core/protocol.h
+++ b/src/core/protocol.h
@@ -95,6 +95,15 @@ struct nni_proto {
uint32_t proto_flags; // Protocol flags
const nni_proto_sock_ops *proto_sock_ops; // Per-socket opeations
const nni_proto_pipe_ops *proto_pipe_ops; // Per-pipe operations.
+
+ // proto_init, if not NULL, provides a function that initializes
+ // global values. The main purpose of this may be to initialize
+ // protocol option values.
+ int (*proto_init)(void);
+
+ // proto_fini, if not NULL, is called at shutdown, to release
+ // any resources allocated at proto_init time.
+ void (*proto_fini)(void);
};
// We quite intentionally use a signature where the upper word is nonzero,
@@ -118,7 +127,11 @@ struct nni_proto {
// nni_proto_open is called by the protocol to create a socket instance
// with its ops vector. The intent is that applications will only see
// the single protocol-specific constructure, like nng_pair_v0_open(),
-// which should just be a thin wrapper around this.
+// which should just be a thin wrapper around this. If the protocol has
+// not been initialized yet, this routine will do so.
extern int nni_proto_open(nng_socket *, const nni_proto *);
+extern int nni_proto_sys_init(void);
+extern void nni_proto_sys_fini(void);
+
#endif // CORE_PROTOCOL_H