summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/message.c168
-rw-r--r--src/core/message.h63
2 files changed, 48 insertions, 183 deletions
diff --git a/src/core/message.c b/src/core/message.c
index 49b6c453..a39ef4bb 100644
--- a/src/core/message.c
+++ b/src/core/message.c
@@ -24,22 +24,13 @@ typedef struct {
// Underlying message structure.
struct nng_msg {
- uint32_t m_header_buf[(NNI_MAX_MAX_TTL + 1)];
- size_t m_header_len;
- nni_chunk m_body;
- uint32_t m_pipe; // set on receive
- nni_atomic_int m_refcnt;
- struct nni_msg_opt *m_opts;
-};
-
-// Message options. For protocol use only.
-struct nni_msg_opt {
- struct nni_msg_opt *mo_next;
- const char * mo_name;
- void * mo_value;
- size_t mo_size;
- void (*mo_free)(void *, size_t); // called by nni_msg_free
- int (*mo_dup)(void **, void *, size_t); // called by nni_msg_dup
+ uint32_t m_header_buf[(NNI_MAX_MAX_TTL + 1)];
+ size_t m_header_len;
+ nni_chunk m_body;
+ nni_proto_msg_ops *m_proto_ops;
+ void * m_proto_data;
+ nni_atomic_int m_refcnt;
+ uint32_t m_pipe; // set on receive
};
#if 0
@@ -441,30 +432,15 @@ nni_msg_dup(nni_msg **dup, const nni_msg *src)
nni_atomic_init(&m->m_refcnt);
nni_atomic_set(&m->m_refcnt, 1);
- // clone message options -- we use the supplied cloner function
- // if one was provided.
- opp = &m->m_opts;
- for (os = src->m_opts; os != NULL; os = os->mo_next) {
- if ((od = NNI_ALLOC_STRUCT(od)) != NULL) {
+ // clone protocol data if a method was supplied.
+ if (src->m_proto_ops != NULL && src->m_proto_ops->msg_free != NULL) {
+ rv = src->m_proto_ops->msg_dup(
+ &m->m_proto_data, src->m_proto_data);
+ if (rv != 0) {
nni_msg_free(m);
return (NNG_ENOMEM);
}
- if ((os->mo_dup) != NULL) {
- rv = os->mo_dup(
- &od->mo_value, os->mo_value, os->mo_size);
- if (rv != 0) {
- nni_msg_free(m);
- return (rv);
- }
- od->mo_size = os->mo_size;
- od->mo_free = os->mo_free;
- od->mo_dup = os->mo_dup;
- } else {
- od->mo_value = os->mo_value;
- od->mo_size = os->mo_size;
- }
- *opp = od;
- opp = &od->mo_next;
+ m->m_proto_ops = src->m_proto_ops;
}
*dup = m;
@@ -478,12 +454,9 @@ nni_msg_free(nni_msg *m)
struct nni_msg_opt *mo;
nni_chunk_free(&m->m_body);
- while ((mo = m->m_opts) != NULL) {
- m->m_opts = mo->mo_next;
- if (mo->mo_free != NULL) {
- mo->mo_free(mo->mo_value, mo->mo_size);
- }
- NNI_FREE_STRUCT(mo);
+ if (m->m_proto_ops != NULL &&
+ m->m_proto_ops->msg_free != NULL) {
+ m->m_proto_ops->msg_free(m->m_proto_data);
}
NNI_FREE_STRUCT(m);
}
@@ -672,111 +645,18 @@ nni_msg_get_pipe(const nni_msg *m)
return (m->m_pipe);
}
-int
-nni_msg_set_opt(nng_msg *m, const char *name, void *val, size_t size,
- void (*free_func)(void *, size_t),
- int (*dup_func)(void **, void *, size_t))
-{
- struct nni_msg_opt **opp;
- struct nni_msg_opt * op;
-
- for (opp = &m->m_opts; (op = *opp) != NULL; opp = &op->mo_next) {
- if (strcmp(op->mo_name, name) == 0) {
- break;
- }
- }
- if (op == NULL) {
- if ((op = NNI_ALLOC_STRUCT(op)) == NULL) {
- return (NNG_ENOMEM);
- }
- if ((op->mo_name = nni_strdup(name)) == NULL) {
- NNI_FREE_STRUCT(op);
- return (NNG_ENOMEM);
- }
- *opp = op;
- }
- op->mo_value = val;
- op->mo_size = size;
- op->mo_free = free_func;
- op->mo_dup = dup_func;
- return (0);
-}
-
-int
-nni_msg_add_opt(nng_msg *m, const char *name, void *val, size_t size,
- void (*free_func)(void *, size_t),
- int (*dup_func)(void **, void *, size_t))
-{
- struct nni_msg_opt **opp;
- struct nni_msg_opt * op;
-
- opp = &m->m_opts;
- while ((op = *opp) != NULL) {
- opp = &op->mo_next;
- }
- if ((op = NNI_ALLOC_STRUCT(op)) == NULL) {
- return (NNG_ENOMEM);
- }
- if ((op->mo_name = nni_strdup(name)) == NULL) {
- NNI_FREE_STRUCT(op);
- return (NNG_ENOMEM);
- }
- *opp = op;
- op->mo_value = val;
- op->mo_size = size;
- op->mo_free = free_func;
- op->mo_dup = dup_func;
- return (0);
-}
-
-// nni_msg_rem_opt removes *all* options with the given name.
-int
-nni_msg_rem_opt(nng_msg *m, const char *name)
-{
- struct nni_msg_opt **opp;
- struct nni_msg_opt * op;
- int rv = NNG_ENOENT;
-
- opp = &m->m_opts;
- while ((op = *opp) != NULL) {
- if (strcmp(name, op->mo_name) == 0) {
- if (op->mo_free != NULL) {
- op->mo_free(op->mo_value, op->mo_size);
- }
- *opp = op->mo_next;
- NNI_FREE_STRUCT(op);
- rv = 0;
- } else {
- *opp = op->mo_next;
- }
- }
- return (rv);
-}
-
void
-nni_msg_walk_opt(
- nng_msg *m, void *arg, bool (*fn)(void *, const char *, void *, size_t))
+nni_msg_set_proto_data(nng_msg *m, nni_proto_msg_ops *ops, void *data)
{
- struct nni_msg_opt *op;
-
- for (op = m->m_opts; op != NULL; op = op->mo_next) {
- if (!fn(arg, op->mo_name, op->mo_value, op->mo_size)) {
- break;
- }
+ if (m->m_proto_ops != NULL && m->m_proto_ops->msg_free != NULL) {
+ m->m_proto_ops->msg_free(m->m_proto_data);
}
+ m->m_proto_ops = ops;
+ m->m_proto_data = data;
}
-int
-nni_msg_get_opt(nng_msg *m, const char *name, void **vp, size_t *szp)
+void *
+nni_msg_get_proto_data(nng_msg *m)
{
- struct nni_msg_opt *op;
-
- for (op = m->m_opts; op != NULL; op = op->mo_next) {
- if (strcmp(op->mo_name, name) == 0) {
- *vp = op->mo_value;
- *szp = op->mo_size;
- return 0;
- }
- }
- return (NNG_ENOENT);
+ return (m->m_proto_data);
}
diff --git a/src/core/message.h b/src/core/message.h
index fb03ca6b..95152853 100644
--- a/src/core/message.h
+++ b/src/core/message.h
@@ -60,48 +60,33 @@ extern bool nni_msg_shared(nni_msg *);
// original message in that case (same semantics as realloc).
extern nni_msg *nni_msg_pull_up(nni_msg *);
-// Message option handling. Message options are intended for protocol
-// specific use. For this reason, their API is not made public -- instead
-// protocols should provide protocol specific functions for accessing them.
-// Note that manipulation of message options must not be performed while the
-// message is shared. If a copy is made with nni_msg_unique(), then the
-// options will be cloned appropriately.
+// Message protocol private data. This is specific for protocol use,
+// and not exposed to library users.
-// nni_msg_set_opt sets a given option. This will replace another option
-// on the message set using the same name. The supplied functions are
-// used when freeing the message, or when duplicating the message.
-// If the value was created using nni_alloc, then nni_free and nni_mem_dup
-// can be supplied. Note that the message must not be shared when this
-// is called.
-//
-// NB: It is possible to use a non-NULL dup function, but have a NULL
-// free function. This is appropriate if the content of the buffer is
-// located in the message header, for example.
-extern int nni_msg_set_opt(nng_msg *, const char *, void *, size_t,
- void (*)(void *, size_t), int (*)(void **, void *, size_t));
-
-// nni_msg_add_opt adds a given option, regardless of whether another
-// instance of the option with the same name exists. In all other respects
-// it behaves like nng_msg_set_opt.
-extern int nni_msg_add_opt(nng_msg *, const char *, void *, size_t,
- void (*)(void *, size_t), int (*)(void **, void *, size_t));
+// nni_proto_msg_ops is used to handle the protocol private data
+// associated with a message.
+typedef struct nni_proto_msg_ops {
+ // This is used to free protocol specific data previously
+ // attached to the message, and is called when the message
+ // itself is freed, or when protocol private is replaced.
+ int (*msg_free)(void *);
-// nni_msg_rem_opt removes any (and all) instances of the named option
-// from the message. It returns zero if any instances are removed, or
-// NNG_ENOENT if no instance of the option was found on the message.
-// The message must not be shared.
-extern int nni_msg_rem_opt(nng_msg *, const char *);
+ // Duplicate protocol private data when duplicating a message,
+ // such as by nni_msg_dup() or calling nni_msg_unique() on a
+ // shared message.
+ int (*msg_dup)(void **, const void *);
+} nni_proto_msg_ops;
-// nni_msg_get_opt is used to get the first instance of a message option.
-// If the option cannot be found, then NNG_ENOENT is returned.
-extern int nni_msg_get_opt(nng_msg *, const char *, void **, size_t *);
+// nni_msg_set_proto_data is used to set protocol private data, and
+// callbacks for freeing and duplicating said data, on the message.
+// If other protocol private data exists on the message, it will be freed.
+// NULL can be used for the ops and the pointer to clear any previously
+// set data. The message must not be shared when this is called.
+extern void nni_msg_set_proto_data(nng_msg *, nni_proto_msg_ops *, void *);
-// nni_msg_walk_opt is used to iterate over all options with a function.
-// The called function should return true to keep iterating, or false
-// to stop the iteration. The argument is supplied as the first parameter
-// to the function.
-extern void
-nni_msg_walk_opt(
- nng_msg *, void *, bool (*)(void *, const char *, void *, size_t))
+// nni_msg_get_proto_data returns the data previously set on the message.
+// Note that the protocol is responsible for ensuring that the data on
+// the message is set by it alone.
+extern void *nni_msg_get_proto_data(nng_msg *);
#endif // CORE_SOCKET_H