summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--perf/perf.c17
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/core/idhash.c87
-rw-r--r--src/core/idhash.h25
-rw-r--r--src/core/init.c26
-rw-r--r--src/core/init.h12
-rw-r--r--src/core/socket.c85
-rw-r--r--src/core/socket.h3
-rw-r--r--src/nng.c11
-rw-r--r--src/nng.h6
-rw-r--r--src/protocol/bus/bus.c1
-rw-r--r--src/protocol/reqrep/rep.c12
-rw-r--r--src/protocol/survey/respond.c12
-rw-r--r--tests/bus.c3
-rw-r--r--tests/event.c23
-rw-r--r--tests/idhash.c100
-rw-r--r--tests/inproc.c2
-rw-r--r--tests/ipc.c2
-rw-r--r--tests/sock.c11
-rw-r--r--tests/tcp.c4
20 files changed, 235 insertions, 209 deletions
diff --git a/perf/perf.c b/perf/perf.c
index 40b9c1f3..419d729f 100644
--- a/perf/perf.c
+++ b/perf/perf.c
@@ -20,17 +20,6 @@
// API, so don't be lazy like this! All nni_ symbols are subject to
// change without notice, and not part of the stable API or ABI.
#include "core/nng_impl.h"
-#include "core/thread.c"
-#include "core/clock.c"
-#include "platform/posix/posix_impl.h"
-#include "platform/posix/posix_alloc.c"
-#include "platform/posix/posix_clock.c"
-#include "platform/posix/posix_debug.c"
-#include "platform/posix/posix_thread.c"
-#include "platform/windows/win_impl.h"
-#include "platform/windows/win_clock.c"
-#include "platform/windows/win_debug.c"
-#include "platform/windows/win_thread.c"
static void latency_client(const char *, int, int);
static void latency_server(const char *, int, int);
@@ -107,12 +96,6 @@ nop(void)
return (0);
}
-int
-nni_init(void)
-{
- return (nni_plat_init(nop));
-}
-
static void
die(const char *fmt, ...)
{
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e70074c2..2df849ae 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,7 +32,9 @@ set (NNG_SOURCES
core/clock.c
core/clock.h
core/endpt.c
+ core/endpt.h
core/event.c
+ core/event.h
core/idhash.c
core/idhash.h
core/init.c
diff --git a/src/core/idhash.c b/src/core/idhash.c
index 0b680bc9..07368a65 100644
--- a/src/core/idhash.c
+++ b/src/core/idhash.c
@@ -11,54 +11,58 @@
#include <string.h>
-typedef struct {
+struct nni_idhash_entry {
uint32_t ihe_key;
uint32_t ihe_skips;
void * ihe_val;
-} nni_idhash_entry;
-
-struct nni_idhash {
- uint32_t ih_cap;
- uint32_t ih_count;
- uint32_t ih_load;
- uint32_t ih_minload; // considers placeholders
- uint32_t ih_maxload;
- uint32_t ih_walkers;
- uint32_t ih_minval;
- uint32_t ih_maxval;
- uint32_t ih_dynval;
- nni_idhash_entry * ih_entries;
};
+
int
-nni_idhash_create(nni_idhash **hp)
+nni_idhash_init(nni_idhash *h)
{
- nni_idhash *h;
-
- if ((h = NNI_ALLOC_STRUCT(h)) == NULL) {
- return (NNG_ENOMEM);
- }
- h->ih_entries = nni_alloc(8 * sizeof (nni_idhash_entry));
- if (h->ih_entries == NULL) {
- NNI_FREE_STRUCT(h);
- return (NNG_ENOMEM);
- }
- (void) memset(h->ih_entries, 0, (8 * sizeof (nni_idhash_entry)));
+ h->ih_entries = NULL;
h->ih_count = 0;
h->ih_load = 0;
- h->ih_cap = 8;
- h->ih_maxload = 5;
+ h->ih_cap = 0;
+ h->ih_maxload = 0;
h->ih_minload = 0; // never shrink below this
h->ih_walkers = 0;
h->ih_minval = 0;
h->ih_maxval = 0xffffffff;
h->ih_dynval = 0;
- *hp = h;
return (0);
}
void
+nni_idhash_fini(nni_idhash *h)
+{
+ NNI_ASSERT(h->ih_walkers == 0);
+ if (h->ih_entries != NULL) {
+ nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry));
+ h->ih_entries = NULL;
+ h->ih_cap = h->ih_count = 0;
+ h->ih_load = h->ih_minload = h->ih_maxload = 0;
+ }
+}
+
+
+void
+nni_idhash_reclaim(nni_idhash *h)
+{
+ // Reclaim the buffer if we want, but preserve the limits.
+ if ((h->ih_count == 0) && (h->ih_cap != 0) && (h->ih_walkers == 0)) {
+ nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry));
+ h->ih_cap = 0;
+ h->ih_entries = NULL;
+ h->ih_minload = 0;
+ h->ih_maxload = 0;
+ }
+}
+
+
+void
nni_idhash_set_limits(nni_idhash *h, uint32_t minval, uint32_t maxval,
uint32_t start)
{
@@ -71,16 +75,6 @@ nni_idhash_set_limits(nni_idhash *h, uint32_t minval, uint32_t maxval,
}
-void
-nni_idhash_destroy(nni_idhash *h)
-{
- if (h != NULL) {
- nni_free(h->ih_entries, h->ih_cap * sizeof (nni_idhash_entry));
- NNI_FREE_STRUCT(h);
- }
-}
-
-
// Inspired by Python dict implementation. This probe will visit every
// cell. We always hash consecutively assigned IDs.
#define NNI_IDHASH_NEXTPROBE(h, j) \
@@ -91,6 +85,10 @@ nni_idhash_find(nni_idhash *h, uint32_t id, void **valp)
{
uint32_t index = id & (h->ih_cap - 1);
+ if (h->ih_count == 0) {
+ return (NNG_ENOENT);
+ }
+
for (;;) {
if ((h->ih_entries[index].ihe_val == NULL) &&
(h->ih_entries[index].ihe_skips == 0)) {
@@ -165,7 +163,9 @@ nni_hash_resize(nni_idhash *h)
index = NNI_IDHASH_NEXTPROBE(h, index);
}
}
- nni_free(oldents, sizeof (nni_idhash_entry) * oldsize);
+ if (oldsize != 0) {
+ nni_free(oldents, sizeof (nni_idhash_entry) * oldsize);
+ }
return (0);
}
@@ -286,11 +286,10 @@ nni_idhash_alloc(nni_idhash *h, uint32_t *idp, void *val)
}
-int
-nni_idhash_count(nni_idhash *h, uint32_t *countp)
+size_t
+nni_idhash_count(nni_idhash *h)
{
- *countp = h->ih_count;
- return (0);
+ return (h->ih_count);
}
diff --git a/src/core/idhash.h b/src/core/idhash.h
index e8876ad5..4616ccde 100644
--- a/src/core/idhash.h
+++ b/src/core/idhash.h
@@ -22,7 +22,23 @@
// use table sizes that are powers of two. Note that hash items
// must be non-NULL. The table is locked.
-typedef struct nni_idhash nni_idhash;
+typedef struct nni_idhash nni_idhash;
+typedef struct nni_idhash_entry nni_idhash_entry;
+
+// The details of the nni_idhash are "private". But they let us inline
+// this into structures.
+struct nni_idhash {
+ size_t ih_cap;
+ size_t ih_count;
+ size_t ih_load;
+ size_t ih_minload; // considers placeholders
+ size_t ih_maxload;
+ uint32_t ih_walkers;
+ uint32_t ih_minval;
+ uint32_t ih_maxval;
+ uint32_t ih_dynval;
+ nni_idhash_entry * ih_entries;
+};
// nni_idhash_walkfn is called when walking a hash table. If the
// return value is non-zero, then nni_idhash_walk will terminate further
@@ -32,14 +48,17 @@ typedef struct nni_idhash nni_idhash;
// Note that the walkfn must not attempt to change the hash table.
// The user must provide any locking needed.
typedef int (*nni_idhash_walkfn)(void *, uint32_t, void *);
-extern int nni_idhash_create(nni_idhash **);
+extern int nni_idhash_init(nni_idhash *);
+extern void nni_idhash_fini(nni_idhash *);
+extern void nni_idhash_reclaim(nni_idhash *);
extern void nni_idhash_set_limits(nni_idhash *, uint32_t, uint32_t, uint32_t);
+extern int nni_idhash_create(nni_idhash **);
extern void nni_idhash_destroy(nni_idhash *);
extern int nni_idhash_find(nni_idhash *, uint32_t, void **);
extern int nni_idhash_remove(nni_idhash *, uint32_t);
extern int nni_idhash_insert(nni_idhash *, uint32_t, void *);
extern int nni_idhash_alloc(nni_idhash *, uint32_t *, void *);
-extern int nni_idhash_count(nni_idhash *, uint32_t *);
+extern size_t nni_idhash_count(nni_idhash *);
extern int nni_idhash_walk(nni_idhash *, nni_idhash_walkfn, void *);
#endif // CORE_IDHASH_H
diff --git a/src/core/init.c b/src/core/init.c
index 48a5096c..8ada0247 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -15,6 +15,10 @@ nni_idhash *nni_endpoints;
nni_idhash *nni_pipes;
nni_idhash *nni_sockets;
nni_mtx *nni_idlock;
+
+static nni_idhash nni_endpoints_x;
+static nni_idhash nni_pipes_x;
+static nni_idhash nni_sockets_x;
static nni_mtx nni_idlock_x;
static int
@@ -28,17 +32,23 @@ nni_init_helper(void)
if ((rv = nni_mtx_init(&nni_idlock_x)) != 0) {
return (rv);
}
- if (((rv = nni_idhash_create(&nni_endpoints)) != 0) ||
- ((rv = nni_idhash_create(&nni_pipes)) != 0) ||
- ((rv = nni_idhash_create(&nni_sockets)) != 0)) {
+ if (((rv = nni_idhash_init(&nni_endpoints_x)) != 0) ||
+ ((rv = nni_idhash_init(&nni_pipes_x)) != 0) ||
+ ((rv = nni_idhash_init(&nni_sockets_x)) != 0)) {
nni_mtx_fini(&nni_idlock_x);
nni_random_fini();
return (rv);
}
- nni_idhash_set_limits(nni_pipes, 1, 0x7fffffff,
+ nni_idhash_set_limits(&nni_pipes_x, 1, 0x7fffffff,
nni_random() & 0x7fffffff);
- nni_idhash_set_limits(nni_sockets, 1, 0xffffffff, 1);
+ nni_idhash_set_limits(&nni_sockets_x, 1, 0x7fffffff, 1);
+ nni_idhash_set_limits(&nni_endpoints_x, 1, 0xffffffff, 1);
+
nni_idlock = &nni_idlock_x;
+ nni_pipes = &nni_pipes_x;
+ nni_endpoints = &nni_endpoints_x;
+ nni_sockets = &nni_sockets_x;
+
nni_tran_init();
return (0);
}
@@ -54,9 +64,9 @@ nni_init(void)
void
nni_fini(void)
{
- nni_idhash_destroy(nni_endpoints);
- nni_idhash_destroy(nni_pipes);
- nni_idhash_destroy(nni_sockets);
+ nni_idhash_fini(&nni_endpoints_x);
+ nni_idhash_fini(&nni_pipes_x);
+ nni_idhash_fini(&nni_sockets_x);
nni_mtx_fini(&nni_idlock_x);
nni_tran_fini();
nni_random_fini();
diff --git a/src/core/init.h b/src/core/init.h
index bae78fc3..e48b6705 100644
--- a/src/core/init.h
+++ b/src/core/init.h
@@ -15,17 +15,17 @@
// nni_init is called each time the user enters the library. It ensures that
// the library is initlialized properly, and also deals with checks such as
// whether the process has forked since last initialization.
-extern int nni_init(void);
+int nni_init(void);
// nni_fini tears everything down. In the future it may be used to ensure
// that all resources used by the library are released back to the system.
-extern void nni_fini(void);
+void nni_fini(void);
// Private hash tables matching IDs to values. Consumers need to use the
// nni_idlock to protect access to these.
-nni_idhash *nni_endpoints;
-nni_idhash *nni_pipes;
-nni_idhash *nni_sockets;
-nni_mtx *nni_idlock;
+extern nni_mtx *nni_idlock;
+extern nni_idhash *nni_endpoints;
+extern nni_idhash *nni_pipes;
+extern nni_idhash *nni_sockets;
#endif // CORE_INIT_H
diff --git a/src/core/socket.c b/src/core/socket.c
index b1f8f2c4..52df70a2 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -47,34 +47,58 @@ nni_sock_hold(nni_sock **sockp, uint32_t id)
}
nni_mtx_lock(nni_idlock);
rv = nni_idhash_find(nni_sockets, id, (void **) &sock);
+ if ((rv != 0) || (sock->s_closed)) {
+ nni_mtx_unlock(nni_idlock);
+ return (NNG_ECLOSED);
+ }
+ sock->s_refcnt++;
nni_mtx_unlock(nni_idlock);
+ *sockp = sock;
- if (rv == 0) {
- if (sock->s_closing) {
- rv = NNG_ECLOSED;
- } else {
- nni_mtx_lock(&sock->s_mx);
- sock->s_refcnt++;
- nni_mtx_unlock(&sock->s_mx);
- *sockp = sock;
- }
- }
- if (rv == NNG_ENOENT) {
- rv = NNG_ECLOSED;
- }
- return (rv);
+ return (0);
}
void
nni_sock_rele(nni_sock *sock)
{
- nni_mtx_lock(&sock->s_mx);
+ nni_mtx_lock(nni_idlock);
sock->s_refcnt--;
- if (sock->s_closing) {
- nni_cv_wake(&sock->s_cv);
+ if ((sock->s_closed) && (sock->s_refcnt == 1)) {
+ nni_cv_wake(&sock->s_refcv);
}
- nni_mtx_unlock(&sock->s_mx);
+ nni_mtx_unlock(nni_idlock);
+}
+
+
+// nni_sock_hold_close is a special hold acquired by the nng_close
+// function. This waits until it has exclusive access, and then marks
+// the socket unusuable by anything else.
+int
+nni_sock_hold_close(nni_sock **sockp, uint32_t id)
+{
+ int rv;
+ nni_sock *sock;
+
+ if ((rv = nni_init()) != 0) {
+ return (rv);
+ }
+
+ nni_mtx_lock(nni_idlock);
+ rv = nni_idhash_find(nni_sockets, id, (void **) &sock);
+ if (rv != 0) {
+ nni_mtx_unlock(nni_idlock);
+ return (NNG_ECLOSED);
+ }
+ sock->s_closed = 1;
+ sock->s_refcnt++;
+ while (sock->s_refcnt != 1) {
+ nni_cv_wait(&sock->s_refcv);
+ }
+ nni_mtx_unlock(nni_idlock);
+ *sockp = sock;
+
+ return (0);
}
@@ -290,6 +314,10 @@ nni_sock_open(nni_sock **sockp, uint16_t pnum)
goto fail;
}
+ if ((rv = nni_cv_init(&sock->s_refcv, nni_idlock)) != 0) {
+ goto fail;
+ }
+
rv = nni_ev_init(&sock->s_recv_ev, NNG_EV_CAN_RECV, sock);
if (rv != 0) {
goto fail;
@@ -355,6 +383,11 @@ fail:
if (sock->s_id != 0) {
nni_mtx_lock(nni_idlock);
nni_idhash_remove(nni_sockets, sock->s_id);
+ if (nni_idhash_count(nni_sockets) == 0) {
+ nni_idhash_reclaim(nni_pipes);
+ nni_idhash_reclaim(nni_endpoints);
+ nni_idhash_reclaim(nni_sockets);
+ }
nni_mtx_unlock(nni_idlock);
}
nni_thr_fini(&sock->s_notifier);
@@ -363,6 +396,7 @@ fail:
nni_ev_fini(&sock->s_recv_ev);
nni_msgq_fini(sock->s_urq);
nni_msgq_fini(sock->s_uwq);
+ nni_cv_fini(&sock->s_refcv);
nni_cv_fini(&sock->s_notify_cv);
nni_cv_fini(&sock->s_cv);
nni_mtx_fini(&sock->s_notify_mx);
@@ -472,7 +506,8 @@ nni_sock_shutdown(nni_sock *sock)
// nni_sock_close shuts down the socket, then releases any resources
// associated with it. It is a programmer error to reference the socket
// after this function is called, as the pointer may reference invalid
-// memory or other objects.
+// memory or other objects. The socket should have been acquired with
+// nni_sock_hold_close().
void
nni_sock_close(nni_sock *sock)
{
@@ -482,11 +517,6 @@ nni_sock_close(nni_sock *sock)
// Shutdown everything if not already done. This operation
// is idempotent.
nni_sock_shutdown(sock);
- nni_mtx_lock(&sock->s_mx);
- while (sock->s_refcnt > 1) {
- nni_cv_wait(&sock->s_cv);
- }
- nni_mtx_unlock(&sock->s_mx);
// At this point nothing else should be referencing us.
// As with UNIX close, it is a gross error for the caller
@@ -497,6 +527,12 @@ nni_sock_close(nni_sock *sock)
nni_mtx_lock(nni_idlock);
nni_idhash_remove(nni_sockets, sock->s_id);
+ if (nni_idhash_count(nni_sockets) == 0) {
+ nni_idhash_reclaim(nni_pipes);
+ nni_idhash_reclaim(nni_endpoints);
+ nni_idhash_reclaim(nni_sockets);
+ }
+
nni_mtx_unlock(nni_idlock);
// The protocol needs to clean up its state.
@@ -516,6 +552,7 @@ nni_sock_close(nni_sock *sock)
nni_msgq_fini(sock->s_uwq);
nni_ev_fini(&sock->s_send_ev);
nni_ev_fini(&sock->s_recv_ev);
+ nni_cv_fini(&sock->s_refcv);
nni_cv_fini(&sock->s_notify_cv);
nni_cv_fini(&sock->s_cv);
nni_mtx_fini(&sock->s_notify_mx);
diff --git a/src/core/socket.h b/src/core/socket.h
index 2a30fae5..2f34a038 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -19,6 +19,7 @@ struct nni_socket {
uint32_t s_id;
uint32_t s_refcnt;
+ nni_cv s_refcv;
nni_msgq * s_uwq; // Upper write queue
nni_msgq * s_urq; // Upper read queue
@@ -52,6 +53,7 @@ struct nni_socket {
int s_ep_pend; // EP dial/listen in progress
int s_closing; // Socket is closing
+ int s_closed; // Socket closed
int s_reapexit; // Shutdown the reaper
int s_besteffort; // Best effort mode delivery
int s_senderr; // Protocol state machine use
@@ -64,6 +66,7 @@ struct nni_socket {
};
extern int nni_sock_hold(nni_sock **, uint32_t);
+extern int nni_sock_hold_close(nni_sock **, uint32_t);
extern void nni_sock_rele(nni_sock *);
extern int nni_sock_open(nni_sock **, uint16_t);
extern void nni_sock_close(nni_sock *);
diff --git a/src/nng.c b/src/nng.c
index a8b145f9..c6dfb7f4 100644
--- a/src/nng.c
+++ b/src/nng.c
@@ -56,7 +56,9 @@ nng_close(nng_socket sid)
int rv;
nni_sock *sock;
- if ((rv = nni_sock_hold(&sock, sid)) != 0) {
+ // Close is special, because we still want to be able to get
+ // a hold on the socket even if shutdown was called.
+ if ((rv = nni_sock_hold_close(&sock, sid)) != 0) {
return (rv);
}
// No release -- close releases it.
@@ -607,3 +609,10 @@ nng_device(nng_socket sock1, nng_socket sock2)
// Device TBD.
return (NNG_ENOTSUP);
}
+
+
+void
+nng_usleep(uint64_t usec)
+{
+ nni_usleep(usec);
+}
diff --git a/src/nng.h b/src/nng.h
index c6d733d1..8dc3fedd 100644
--- a/src/nng.h
+++ b/src/nng.h
@@ -372,6 +372,12 @@ NNG_DECL int64_t nng_stat_value(nng_stat *);
// which means that messages from one side are forwarded to the other.
NNG_DECL int nng_device(nng_socket, nng_socket);
+// Sleep for the specified usecs. This is intended for use by test
+// programs (to avoid needing to expose the rest of the private details).
+// Applications are discouraged from using this -- use your platform
+// time services instead.
+NNG_DECL void nng_usleep(uint64_t);
+
// Pollset functionality. TBD. (Note that I'd rather avoid this
// altogether, because I believe that the notification mechanism I've
// created offers a superior way to handle this. I don't think many
diff --git a/src/protocol/bus/bus.c b/src/protocol/bus/bus.c
index 986d8ed7..02467ffe 100644
--- a/src/protocol/bus/bus.c
+++ b/src/protocol/bus/bus.c
@@ -94,6 +94,7 @@ nni_bus_pipe_fini(void *arg)
nni_bus_pipe *ppipe = arg;
if (ppipe != NULL) {
+ nni_msgq_fini(ppipe->sendq);
NNI_FREE_STRUCT(ppipe);
}
}
diff --git a/src/protocol/reqrep/rep.c b/src/protocol/reqrep/rep.c
index 6410e6db..a34f6eea 100644
--- a/src/protocol/reqrep/rep.c
+++ b/src/protocol/reqrep/rep.c
@@ -26,7 +26,7 @@ struct nni_rep_sock {
nni_msgq * urq;
int raw;
int ttl;
- nni_idhash * pipes;
+ nni_idhash pipes;
char * btrace;
size_t btrace_len;
};
@@ -53,7 +53,7 @@ nni_rep_sock_init(void **repp, nni_sock *sock)
rep->raw = 0;
rep->btrace = NULL;
rep->btrace_len = 0;
- if ((rv = nni_idhash_create(&rep->pipes)) != 0) {
+ if ((rv = nni_idhash_init(&rep->pipes)) != 0) {
NNI_FREE_STRUCT(rep);
return (rv);
}
@@ -73,7 +73,7 @@ nni_rep_sock_fini(void *arg)
nni_rep_sock *rep = arg;
if (rep != NULL) {
- nni_idhash_destroy(rep->pipes);
+ nni_idhash_fini(&rep->pipes);
if (rep->btrace != NULL) {
nni_free(rep->btrace, rep->btrace_len);
}
@@ -121,7 +121,7 @@ nni_rep_pipe_add(void *arg)
nni_rep_pipe *rp = arg;
nni_rep_sock *rep = rp->rep;
- return (nni_idhash_insert(rep->pipes, nni_pipe_id(rp->pipe), rp));
+ return (nni_idhash_insert(&rep->pipes, nni_pipe_id(rp->pipe), rp));
}
@@ -131,7 +131,7 @@ nni_rep_pipe_rem(void *arg)
nni_rep_pipe *rp = arg;
nni_rep_sock *rep = rp->rep;
- nni_idhash_remove(rep->pipes, nni_pipe_id(rp->pipe));
+ nni_idhash_remove(&rep->pipes, nni_pipe_id(rp->pipe));
}
@@ -166,7 +166,7 @@ nni_rep_sock_send(void *arg)
nni_msg_trim_header(msg, 4);
nni_mtx_lock(mx);
- if (nni_idhash_find(rep->pipes, id, (void **) &rp) != 0) {
+ if (nni_idhash_find(&rep->pipes, id, (void **) &rp) != 0) {
nni_mtx_unlock(mx);
nni_msg_free(msg);
continue;
diff --git a/src/protocol/survey/respond.c b/src/protocol/survey/respond.c
index 5603b675..263e023a 100644
--- a/src/protocol/survey/respond.c
+++ b/src/protocol/survey/respond.c
@@ -24,7 +24,7 @@ struct nni_resp_sock {
nni_sock * nsock;
int raw;
int ttl;
- nni_idhash * pipes;
+ nni_idhash pipes;
char * btrace;
size_t btrace_len;
};
@@ -51,7 +51,7 @@ nni_resp_sock_init(void **pp, nni_sock *nsock)
psock->raw = 0;
psock->btrace = NULL;
psock->btrace_len = 0;
- if ((rv = nni_idhash_create(&psock->pipes)) != 0) {
+ if ((rv = nni_idhash_init(&psock->pipes)) != 0) {
NNI_FREE_STRUCT(psock);
return (rv);
}
@@ -68,7 +68,7 @@ nni_resp_sock_fini(void *arg)
nni_resp_sock *psock = arg;
if (psock != NULL) {
- nni_idhash_destroy(psock->pipes);
+ nni_idhash_fini(&psock->pipes);
if (psock->btrace != NULL) {
nni_free(psock->btrace, psock->btrace_len);
}
@@ -117,7 +117,7 @@ nni_resp_pipe_add(void *arg)
nni_resp_sock *psock = ppipe->psock;
int rv;
- rv = nni_idhash_insert(psock->pipes, nni_pipe_id(ppipe->npipe), ppipe);
+ rv = nni_idhash_insert(&psock->pipes, nni_pipe_id(ppipe->npipe), ppipe);
return (rv);
}
@@ -128,7 +128,7 @@ nni_resp_pipe_rem(void *arg)
nni_resp_pipe *ppipe = arg;
nni_resp_sock *psock = ppipe->psock;
- nni_idhash_remove(psock->pipes, nni_pipe_id(ppipe->npipe));
+ nni_idhash_remove(&psock->pipes, nni_pipe_id(ppipe->npipe));
}
@@ -163,7 +163,7 @@ nni_resp_sock_send(void *arg)
nni_msg_trim_header(msg, 4);
nni_mtx_lock(mx);
- if (nni_idhash_find(psock->pipes, id, (void **) &ppipe) != 0) {
+ if (nni_idhash_find(&psock->pipes, id, (void **) &ppipe) != 0) {
nni_mtx_unlock(mx);
nni_msg_free(msg);
continue;
diff --git a/tests/bus.c b/tests/bus.c
index 6703fa0e..f0c84406 100644
--- a/tests/bus.c
+++ b/tests/bus.c
@@ -19,7 +19,6 @@
Main({
const char *addr = "inproc://test";
- nni_init();
Test("BUS pattern", {
Convey("We can create a BUS socket", {
@@ -96,6 +95,4 @@ Main({
})
})
})
-
- nni_fini();
})
diff --git a/tests/event.c b/tests/event.c
index 30e8f438..554f990f 100644
--- a/tests/event.c
+++ b/tests/event.c
@@ -9,8 +9,8 @@
#include "convey.h"
#include "nng.h"
-#include "core/nng_impl.h"
#include <string.h>
+#include <assert.h>
#define APPENDSTR(m, s) nng_msg_append(m, s, strlen(s))
#define CHECKSTR(m, s) So(nng_msg_len(m) == strlen(s));\
@@ -31,10 +31,7 @@ bump(nng_event *ev, void *arg)
{
struct evcnt *cnt = arg;
- if (nng_event_socket(ev) != cnt->sock) {
- nni_panic("Incorrect socket! %p != %p",
- nng_event_socket(ev), cnt->sock);
- }
+ assert(nng_event_socket(ev) == cnt->sock);
switch (nng_event_type(ev)) {
case NNG_EV_CAN_SEND:
cnt->writeable++;
@@ -61,7 +58,7 @@ bump(nng_event *ev, void *arg)
break;
default:
- nni_panic("Invalid event type %d", nng_event_type(ev));
+ assert(0);
break;
}
}
@@ -69,8 +66,6 @@ bump(nng_event *ev, void *arg)
Main({
const char *addr = "inproc://test";
- nni_init();
-
Test("Event Handling", {
Convey("Given a connected pair of pair sockets", {
nng_socket sock1;
@@ -97,26 +92,26 @@ Main({
So(nng_dial(sock2, addr, NULL, NNG_FLAG_SYNCH) == 0);
// Let everything connect.
- nni_usleep(100000);
+ nng_usleep(100000);
Convey("We can register callbacks", {
So((notify1 = nng_setnotify(sock1, NNG_EV_CAN_SEND, bump, &evcnt1)) != NULL);
So((notify2 = nng_setnotify(sock2, NNG_EV_CAN_RECV, bump, &evcnt2)) != NULL);
Convey("They are called", {
- nni_msg *msg;
+ nng_msg *msg;
- So(nni_msg_alloc(&msg, 0) == 0);
+ So(nng_msg_alloc(&msg, 0) == 0);
APPENDSTR(msg, "abc");
So(nng_sendmsg(sock1, msg, 0) == 0);
So(nng_recvmsg(sock2, &msg, 0) == 0);
CHECKSTR(msg, "abc");
- nni_msg_free(msg);
+ nng_msg_free(msg);
// The notify runs async...
- nni_usleep(100000);
+ nng_usleep(100000);
So(evcnt1.writeable == 1);
So(evcnt2.readable == 1);
@@ -131,6 +126,4 @@ Main({
})
})
})
-
- nni_fini();
})
diff --git a/tests/idhash.c b/tests/idhash.c
index 600b17ae..50a8d976 100644
--- a/tests/idhash.c
+++ b/tests/idhash.c
@@ -8,86 +8,69 @@
//
#include "convey.h"
-#include "core/nng_impl.h"
#include "core/idhash.c"
Main({
- nni_init();
-
Test("General ID Hash", {
int rv;
Convey("Given an id hash", {
- nni_idhash *h;
+ nni_idhash h;
- rv = nni_idhash_create(&h);
- So(rv == 0);
- So(h->ih_cap == 8);
- So(h->ih_entries != NULL);
- So(h->ih_count == 0);
+ So(nni_idhash_init(&h) == 0);
+ So(nni_idhash_count(&h) == 0);
Reset({
- nni_idhash_destroy(h);
+ nni_idhash_fini(&h);
})
Convey("We can insert an element", {
char *five = "five";
char *four = "four";
- rv = nni_idhash_insert(h, 5, five);
+ rv = nni_idhash_insert(&h, 5, five);
+ So(nni_idhash_count(&h) == 1);
So(rv == 0);
- So(h->ih_load == 1);
- So(h->ih_count == 1);
Convey("And we can find it", {
void *ptr;
- rv = nni_idhash_find(h, 5, &ptr);
+ rv = nni_idhash_find(&h, 5, &ptr);
So(rv == 0);
So(ptr == five);
})
Convey("We can delete it", {
void *ptr;
- rv = nni_idhash_remove(h, 5);
+ rv = nni_idhash_remove(&h, 5);
So(rv == 0);
- rv = nni_idhash_find(h, 5, &ptr);
+ rv = nni_idhash_find(&h, 5, &ptr);
So(rv == NNG_ENOENT);
})
Convey("We can change the value", {
void *ptr;
- rv = nni_idhash_insert(h, 5, four);
- So(rv == 0);
- So(h->ih_count == 1);
- rv = nni_idhash_find(h, 5, &ptr);
- So(rv == 0);
+ So(nni_idhash_insert(&h, 5, four) == 0);
+ So(nni_idhash_count(&h) == 1);
+ So(nni_idhash_find(&h, 5, &ptr) == 0);
So(ptr == four);
})
Convey("We can insert a hash collision", {
void *ptr;
- rv = nni_idhash_insert(h, 13, four);
- So(rv == 0);
- So(h->ih_load == 2);
- So(h->ih_count == 2);
- rv = nni_idhash_find(h, 5, &ptr);
- So(rv == 0);
+ So(nni_idhash_insert(&h, 13, four) == 0);
+ So(nni_idhash_count(&h) == 2);
+ So(nni_idhash_find(&h, 5, &ptr) == 0);
So(ptr == five);
- rv = nni_idhash_find(h, 13, &ptr);
- So(rv == 0);
+ So(nni_idhash_find(&h, 13, &ptr) == 0);
So(ptr == four);
- So(h->ih_entries[5].ihe_skips == 1);
Convey("And delete the intermediate", {
- rv = nni_idhash_remove(h, 5);
- So(rv == 0);
+ So(nni_idhash_remove(&h, 5) == 0);
ptr = NULL;
- rv = nni_idhash_find(h, 13, &ptr);
- So(rv == 0);
+ So(nni_idhash_find(&h, 13, &ptr) == 0);
So(ptr == four);
- So(h->ih_load == 2);
})
})
})
Convey("We cannot find bogus values", {
void *ptr = NULL;
- rv = nni_idhash_find(h, 42, &ptr);
+ rv = nni_idhash_find(&h, 42, &ptr);
So(rv == NNG_ENOENT);
So(ptr == NULL);
})
@@ -103,34 +86,27 @@ Main({
expect[i] = i;
}
Convey("Given an id hash", {
- nni_idhash *h;
+ nni_idhash h;
- rv = nni_idhash_create(&h);
- So(rv == 0);
- So(h->ih_cap == 8);
- So(h->ih_entries != NULL);
- So(h->ih_count == 0);
+ So(nni_idhash_init(&h) == 0);
+ So(nni_idhash_count(&h) == 0);
Reset({
- nni_idhash_destroy(h);
+ nni_idhash_fini(&h);
})
Convey("We can insert 1024 items", {
uint32_t count;
for (i = 0; i < 1024; i++) {
- nni_idhash_insert(h, i, &expect[i]);
+ nni_idhash_insert(&h, i, &expect[i]);
}
- So(nni_idhash_count(h, &count) == 0);
- So(count == 1024);
- So(h->ih_cap = 2048);
- So(h->ih_count == 1024);
+ So(nni_idhash_count(&h) == 1024);
Convey("We can remove them", {
for (i = 0; i < 1024; i++) {
- nni_idhash_remove(h, i);
+ nni_idhash_remove(&h, i);
}
- So(h->ih_count == 0);
- So(h->ih_cap == 8);
+ So(nni_idhash_count(&h) == 0);
})
})
})
@@ -138,36 +114,34 @@ Main({
Test("Dynamic ID generation", {
Convey("Given a small ID hash", {
- nni_idhash *h;
+ nni_idhash h;
int expect[5];
uint32_t id;
int i;
- So(nni_idhash_create(&h) == 0);
+ So(nni_idhash_init(&h) == 0);
Reset({
- nni_idhash_destroy(h);
+ nni_idhash_fini(&h);
})
- nni_idhash_set_limits(h, 10, 13, 10);
+ nni_idhash_set_limits(&h, 10, 13, 10);
So(1);
Convey("We can fill the table", {
for (i = 0; i < 4; i++) {
- So(nni_idhash_alloc(h, &id, &expect[i]) == 0);
+ So(nni_idhash_alloc(&h, &id, &expect[i]) == 0);
So(id == (i + 10));
}
Convey("Adding another fails", {
- So(nni_idhash_alloc(h, &id, &expect[5]) == NNG_ENOMEM);
+ So(nni_idhash_alloc(&h, &id, &expect[5]) == NNG_ENOMEM);
})
Convey("Deleting one lets us reinsert", {
- nni_idhash_remove(h, 11);
- So(nni_idhash_alloc(h, &id, &expect[5]) == 0);
+ nni_idhash_remove(&h, 11);
+ So(nni_idhash_alloc(&h, &id, &expect[5]) == 0);
So(id == 11);
})
})
Convey("We cannot insert bogus values", {
- So(nni_idhash_insert(h, 1, &expect[0]) == NNG_EINVAL);
- So(nni_idhash_insert(h, 100, &expect[0]) == NNG_EINVAL);
+ So(nni_idhash_insert(&h, 1, &expect[0]) == NNG_EINVAL);
+ So(nni_idhash_insert(&h, 100, &expect[0]) == NNG_EINVAL);
})
})
})
-
- nni_fini();
})
diff --git a/tests/inproc.c b/tests/inproc.c
index cfbf3153..0375320f 100644
--- a/tests/inproc.c
+++ b/tests/inproc.c
@@ -15,7 +15,5 @@
// Inproc tests.
TestMain("Inproc Transport", {
- nni_init();
trantest_test_all("inproc://TEST");
- nni_fini();
})
diff --git a/tests/ipc.c b/tests/ipc.c
index 7e9221f3..69fe36d0 100644
--- a/tests/ipc.c
+++ b/tests/ipc.c
@@ -14,7 +14,5 @@
// Inproc tests.
TestMain("IPC Transport", {
- nni_init();
trantest_test_all("ipc:///tmp/nng_ipc_test");
- nni_fini();
})
diff --git a/tests/sock.c b/tests/sock.c
index ec923e4a..c43b6fc1 100644
--- a/tests/sock.c
+++ b/tests/sock.c
@@ -14,8 +14,6 @@
#include <string.h>
Main({
- nni_init();
-
Test("Socket Operations", {
Convey("We are able to open a PAIR socket", {
@@ -137,6 +135,9 @@ Main({
Convey("We can connect to it", {
nng_socket sock2;
So(nng_open(&sock2, NNG_PROTO_PAIR) == 0);
+ Reset({
+ nng_close(sock2);
+ })
rv = nng_dial(sock2, "inproc://here", NULL, NNG_FLAG_SYNCH);
So(rv == 0);
nng_close(sock2);
@@ -151,6 +152,9 @@ Main({
char *buf;
So(nng_open(&sock2, NNG_PROTO_PAIR) == 0);
+ Reset({
+ nng_close(sock2);
+ })
So(nng_setopt(sock, NNG_OPT_RCVBUF, &len, sizeof (len)) == 0);
So(nng_setopt(sock, NNG_OPT_SNDBUF, &len, sizeof (len)) == 0);
@@ -172,10 +176,7 @@ Main({
So(sz == 4);
So(memcmp(buf, "abc", 4) == 0);
nng_free(buf, sz);
- nng_close(sock2);
})
})
})
-
- nni_fini();
})
diff --git a/tests/tcp.c b/tests/tcp.c
index 0ec69121..73039e64 100644
--- a/tests/tcp.c
+++ b/tests/tcp.c
@@ -16,7 +16,6 @@
TestMain("TCP Transport", {
int rv;
- nni_init();
trantest_test_all("tcp://127.0.0.1:4450");
@@ -43,7 +42,4 @@ TestMain("TCP Transport", {
So(nng_dial(s2, "tcp://127.0.0.1:5771", NULL, NNG_FLAG_SYNCH) == 0);
fflush(stdout);
})
- nni_fini();
-
-
})