summaryrefslogtreecommitdiff
path: root/src/core/protocol.c
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/protocol.c
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/protocol.c')
-rw-r--r--src/core/protocol.c69
1 files changed, 69 insertions, 0 deletions
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