aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-01-23 11:00:34 -0800
committerGarrett D'Amore <garrett@damore.org>2017-01-23 11:00:34 -0800
commit5f34e9b1ed7df2102ad8cd3ebbef202a4d8c37cb (patch)
tree8af71e89b3120e5fa825684500d88a4e1854547f /src
parent9b373f8dc63a5a400df4c95ef3daf27b44181119 (diff)
downloadnng-5f34e9b1ed7df2102ad8cd3ebbef202a4d8c37cb.tar.gz
nng-5f34e9b1ed7df2102ad8cd3ebbef202a4d8c37cb.tar.bz2
nng-5f34e9b1ed7df2102ad8cd3ebbef202a4d8c37cb.zip
Use nng_msg underneath (less copying!)
Diffstat (limited to 'src')
-rw-r--r--src/nng_compat.c146
1 files changed, 136 insertions, 10 deletions
diff --git a/src/nng_compat.c b/src/nng_compat.c
index 7c0f6871..bed171ac 100644
--- a/src/nng_compat.c
+++ b/src/nng_compat.c
@@ -173,6 +173,75 @@ nn_shutdown(int s, int ep)
}
+void *
+nn_allocmsg(size_t size, int type)
+{
+ uintptr_t *ch;
+ nng_msg *msg;
+ int rv;
+
+ // Validate type and non-zero size. This also checks for overflow.
+ if ((type != 0) || (size < 1) || ((size + sizeof (msg) < size))) {
+ nn_seterror(NNG_EINVAL);
+ return (NULL);
+ }
+
+ // So our "messages" from nn are really going to be nng messages
+ // but to make this work, we use a bit of headroom in the message
+ // to stash the message header.
+ if ((rv = nng_msg_alloc(&msg, size + (sizeof (msg)))) != 0) {
+ nn_seterror(rv);
+ return (NULL);
+ }
+
+ memcpy(nng_msg_body(msg), &msg, sizeof (msg));
+
+ // We are counting on the implementation of nn_msg_trim to not
+ // reallocate the message but just to leave the prefix inplace.
+ (void) nng_msg_trim(msg, sizeof (msg));
+
+ return (nng_msg_body(msg));
+}
+
+
+void
+nni_freemsg(void *ptr)
+{
+ nng_msg *msg;
+
+ memcpy(&msg, ((char *) ptr) - sizeof (msg), sizeof (msg));
+ nng_msg_free(msg);
+}
+
+
+void *
+nni_reallocmsg(void *ptr, size_t len)
+{
+ nng_msg *msg;
+ int rv;
+
+ if ((len + sizeof (msg)) < len) {
+ // overflowed!
+ nn_seterror(NNG_EINVAL);
+ return (NULL);
+ }
+
+ memcpy(&msg, ((char *) ptr) - sizeof (msg), sizeof (msg));
+
+ // We need to realloc the requested len, plus size for our header.
+ if ((rv = nng_msg_realloc(msg, len + sizeof (msg))) != 0) {
+ // We don't free the old message. Code is free to cope
+ // as it sees fit.
+ nn_seterror(rv);
+ return (NULL);
+ }
+ // Stash the msg header pointer
+ memcpy(nng_msg_body(msg), &msg, sizeof (msg));
+ nng_msg_trim(msg, sizeof (msg));
+ return (nng_msg_body(msg));
+}
+
+
int
nn_send(int s, const void *buf, size_t len, int flags)
{
@@ -189,16 +258,18 @@ nn_send(int s, const void *buf, size_t len, int flags)
return (-1);
}
if (len == NN_MSG) {
- // FIX ME -- this is a message allocated another way...
- nn_seterror(NNG_ENOTSUP);
- return (-1);
+ nng_msg *msg;
+ memcpy(&msg, ((char *) buf) - sizeof (msg), sizeof (msg));
+ len = nng_msg_len(msg);
+ rv = nng_sendmsg((nng_socket) s, msg, flags);
+ } else {
+ rv = nng_send((nng_socket) s, (void *) buf, len, flags);
}
- rv = nng_send((nng_socket) s, (void *)buf, len, flags);
if (rv != 0) {
nn_seterror(rv);
return (-1);
}
- return ((int)len);
+ return ((int) len);
}
@@ -206,7 +277,7 @@ int
nn_recv(int s, void *buf, size_t len, int flags)
{
int rv;
-
+
switch (flags) {
case NN_DONTWAIT:
flags = NNG_FLAG_NONBLOCK;
@@ -218,13 +289,68 @@ nn_recv(int s, void *buf, size_t len, int flags)
return (-1);
}
if (len == NN_MSG) {
- nn_seterror(NNG_ENOTSUP);
- return (-1);
+ nng_msg *msg;
+ rv = nng_recvmsg((nng_socket) s, &msg, flags);
+ if (rv == 0) {
+ void *body;
+ // prepend our header to the body...
+ // Note that this *can* alter the message,
+ // although for performance reasons it ought not.
+ // (There should be sufficient headroom.)
+ nng_msg_prepend(msg, &msg, sizeof (msg));
+ // then trim it off :-)
+ nng_msg_trim(msg, sizeof (msg));
+ // store the pointer to the revised body
+ body = nng_msg_body(msg);
+
+ // arguably we could do this with a pointer store,
+ // but memcpy gives us extra paranoia in case the
+ // the receiver is misaligned.
+ memcpy(buf, &body, sizeof (body));
+ len = nng_msg_len(msg);
+ }
+ } else {
+ rv = nng_recv((nng_socket) s, buf, &len, flags);
}
- rv = nng_recv((nng_socket) s, buf, &len, flags);
if (rv != 0) {
nn_seterror(rv);
return (-1);
}
- return ((int)len);
+ return ((int) len);
}
+
+
+#if 0
+int
+nn_sendmsg(int s, const struct nn_msghdr *mh, int flags)
+{
+ void *chunk;
+
+ switch (flags) {
+ case NN_DONTWAIT:
+ flags = NN_FLAG_NONBLOCK;
+ break;
+ case 0:
+ break;
+ default:
+ nn_seterror(NNG_EINVAL);
+ return (-1);
+ }
+
+ // Iterate over the iovecs. The first iov may be NN_MSG,
+ // in which case it must be the only iovec.
+
+ if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) {
+ // Chunk is stored at the offset...
+ chunk = *(void **) mh->msg_iov[0].iov_base;
+ // Chunk must be aligned
+ if ((chuink & (sizeof (void *) - 1)) != 0) {
+ nn_seterror(NNG_EINVAL);
+ return (-1);
+ }
+ size = (size_t) (*(uintptr_t *) (((void **) chunk) - 1));
+ }
+}
+
+
+#endif