aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/init.c2
-rw-r--r--src/core/options.c157
-rw-r--r--src/core/options.h7
3 files changed, 166 insertions, 0 deletions
diff --git a/src/core/init.c b/src/core/init.c
index 4025c0f4..54c72c5e 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -21,6 +21,7 @@ nni_init_helper(void)
((rv = nni_timer_sys_init()) != 0) ||
((rv = nni_aio_sys_init()) != 0) ||
((rv = nni_random_sys_init()) != 0) ||
+ ((rv = nni_option_sys_init()) != 0) ||
((rv = nni_sock_sys_init()) != 0) ||
((rv = nni_ep_sys_init()) != 0) ||
((rv = nni_pipe_sys_init()) != 0) ||
@@ -43,6 +44,7 @@ nni_fini(void)
nni_pipe_sys_fini();
nni_ep_sys_fini();
nni_sock_sys_fini();
+ nni_option_sys_fini();
nni_random_sys_fini();
nni_aio_sys_fini();
nni_timer_sys_fini();
diff --git a/src/core/options.c b/src/core/options.c
index ecfa437e..55797218 100644
--- a/src/core/options.c
+++ b/src/core/options.c
@@ -10,8 +10,22 @@
#include "core/nng_impl.h"
+#include <stdio.h>
#include <string.h>
+// Dynamic options.
+
+typedef struct nni_option nni_option;
+struct nni_option {
+ nni_list_node o_link;
+ char * o_name;
+ int o_id;
+};
+
+static nni_mtx nni_option_lk;
+static nni_list nni_options;
+static int nni_option_nextid;
+
int
nni_chkopt_usec(const void *v, size_t sz)
{
@@ -241,3 +255,146 @@ nni_getopt_fd(nni_sock *s, nni_notifyfd *fd, int mask, void *val, size_t *szp)
memcpy(val, &fd->sn_rfd, sizeof(int));
return (0);
}
+
+// nni_option_set_id sets the id for an option, if not already done so.
+// (Some options have hard coded values that end-user may depend upon.)
+// If the ID passed in is negative, then a new ID is allocated dynamically.
+static int
+nni_option_set_id(const char *name, int id)
+{
+ nni_option *opt;
+ int len;
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (strcmp(name, opt->o_name) == 0) {
+ nni_mtx_unlock(&nni_option_lk);
+ return (0);
+ }
+ }
+ if ((opt = NNI_ALLOC_STRUCT(opt)) == NULL) {
+ nni_mtx_unlock(&nni_option_lk);
+ return (NNG_ENOMEM);
+ }
+ len = strlen(name) + 1;
+ if ((opt->o_name = nni_alloc(len)) == NULL) {
+ nni_mtx_unlock(&nni_option_lk);
+ NNI_FREE_STRUCT(opt);
+ return (NNG_ENOMEM);
+ }
+ (void) snprintf(opt->o_name, len, "%s", name);
+ if (id < 0) {
+ id = nni_option_nextid++;
+ }
+ opt->o_id = id;
+ nni_list_append(&nni_options, opt);
+ nni_mtx_unlock(&nni_option_lk);
+ return (0);
+}
+
+int
+nni_option_lookup(const char *name)
+{
+ nni_option *opt;
+ int id = -1;
+
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (strcmp(name, opt->o_name) == 0) {
+ id = opt->o_id;
+ break;
+ }
+ }
+ nni_mtx_unlock(&nni_option_lk);
+ return (id);
+}
+
+const char *
+nni_option_name(int id)
+{
+ nni_option *opt;
+ const char *name = NULL;
+
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (id == opt->o_id) {
+ name = opt->o_name;
+ break;
+ }
+ }
+ nni_mtx_unlock(&nni_option_lk);
+ return (name);
+}
+
+int
+nni_option_register(const char *name, int *idp)
+{
+ int id;
+ int rv;
+
+ // Note that if the id was already in use, we will
+ // wind up leaving a gap in the ID space. That should
+ // be inconsequential.
+ if ((rv = nni_option_set_id(name, -1)) != 0) {
+ return (rv);
+ }
+ *idp = nni_option_lookup(name);
+ return (0);
+}
+
+int
+nni_option_sys_init(void)
+{
+ nni_mtx_init(&nni_option_lk);
+ NNI_LIST_INIT(&nni_options, nni_option, o_link);
+ nni_option_nextid = 0x10000;
+ int rv;
+
+ // Register our well-known options.
+ if (((rv = nni_option_set_id("raw", NNG_OPT_RAW)) != 0) ||
+ ((rv = nni_option_set_id("linger", NNG_OPT_LINGER)) != 0) ||
+ ((rv = nni_option_set_id("recv-buf", NNG_OPT_RCVBUF)) != 0) ||
+ ((rv = nni_option_set_id("send-buf", NNG_OPT_SNDBUF)) != 0) ||
+ ((rv = nni_option_set_id("recv-timeout", NNG_OPT_RCVTIMEO)) !=
+ 0) ||
+ ((rv = nni_option_set_id("send-timeout", NNG_OPT_SNDTIMEO)) !=
+ 0) ||
+ ((rv = nni_option_set_id("reconnect-time", NNG_OPT_RECONN_TIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id(
+ "reconnect-max-time", NNG_OPT_RECONN_MAXTIME)) != 0) ||
+ ((rv = nni_option_set_id("recv-max-size", NNG_OPT_RCVMAXSZ)) !=
+ 0) ||
+ ((rv = nni_option_set_id("max-ttl", NNG_OPT_MAXTTL)) != 0) ||
+ ((rv = nni_option_set_id("protocol", NNG_OPT_PROTOCOL)) != 0) ||
+ ((rv = nni_option_set_id("subscribe", NNG_OPT_SUBSCRIBE)) != 0) ||
+ ((rv = nni_option_set_id("unsubscribe", NNG_OPT_UNSUBSCRIBE)) !=
+ 0) ||
+ ((rv = nni_option_set_id("survey-time", NNG_OPT_SURVEYTIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id("resend-time", NNG_OPT_RESENDTIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id("transport", NNG_OPT_TRANSPORT)) != 0) ||
+ ((rv = nni_option_set_id("local-addr", NNG_OPT_LOCALADDR)) != 0) ||
+ ((rv = nni_option_set_id("remote-addr", NNG_OPT_REMOTEADDR)) !=
+ 0) ||
+ ((rv = nni_option_set_id("recv-fd", NNG_OPT_RCVFD)) != 0) ||
+ ((rv = nni_option_set_id("send-fd", NNG_OPT_SNDFD)) != 0)) {
+ nni_option_sys_fini();
+ return (rv);
+ }
+ return (0);
+}
+
+void
+nni_option_sys_fini(void)
+{
+ if (nni_option_nextid != 0) {
+ nni_option *opt;
+ while ((opt = nni_list_first(&nni_options)) != NULL) {
+ nni_list_remove(&nni_options, opt);
+ nni_free(opt->o_name, strlen(opt->o_name) + 1);
+ NNI_FREE_STRUCT(opt);
+ }
+ }
+ nni_option_nextid = 0;
+} \ No newline at end of file
diff --git a/src/core/options.h b/src/core/options.h
index 4b29c4b6..03a6e37e 100644
--- a/src/core/options.h
+++ b/src/core/options.h
@@ -56,4 +56,11 @@ extern int nni_chkopt_usec(const void *, size_t);
extern int nni_chkopt_int(const void *, size_t, int, int);
extern int nni_chkopt_size(const void *, size_t, size_t, size_t);
+extern int nni_option_register(const char *, int *);
+extern int nni_option_lookup(const char *);
+extern const char *nni_option_name(int);
+
+extern int nni_option_sys_init(void);
+extern void nni_option_sys_fini(void);
+
#endif // CORE_OPTIONS_H