int main() { int i; struct nn_thread srv_thread; struct nn_thread cli_threads[THREAD_COUNT]; /* Stress the shutdown algorithm. */ nn_thread_init(&srv_thread, server, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init(&cli_threads[i], client, (void *)(intptr_t)i); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term(&cli_threads[i]); return 0; }
int main () { int rc; int sb; int i; int j; struct nn_thread threads [THREAD_COUNT]; /* Stress the shutdown algorithm. */ sb = nn_socket (AF_SP, NN_PUB); errno_assert (sb >= 0); rc = nn_bind (sb, SOCKET_ADDRESS); errno_assert (rc >= 0); for (j = 0; j != 10; ++j) { for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term (&threads [i]); } rc = nn_close (sb); errno_assert (rc == 0); return 0; }
int main () { #if !defined NN_HAVE_WINDOWS int sb; int i; int j; struct nn_thread threads [THREAD_COUNT]; /* Stress the shutdown algorithm. */ sb = test_socket (AF_SP, NN_PUB); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != 10; ++j) { for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term (&threads [i]); } test_close (sb); #endif return 0; }
int testterm() { int rc; int s; struct nn_thread thread; printf("test term\n"); /* Close the socket with no associated endpoints. */ s = test_socket (AF_SP, NN_PAIR); test_close (s); /* Test nn_term() before nn_close(). */ nn_thread_init (&thread, worker, NULL); nn_sleep (100); nn_term(); /* Check that it's not possible to create new sockets after nn_term(). */ rc = nn_socket (AF_SP, NN_PAIR); nn_assert (rc == -1); errno_assert (nn_errno () == ETERM); /* Wait till worker thread terminates. */ nn_thread_term(&thread); printf("nn_thread_term finished\n"); return 0; }
int nn_worker_init(struct nn_worker *self) { int32_t rc; //PostMessage("nn_worker_init %p\n",self); rc = nn_efd_init(&self->efd); //PostMessage("efd init: rc.%d\n",rc); if ( rc < 0 ) return rc; //PostMessage("nn_mutex_init\n"); nn_mutex_init(&self->sync); //PostMessage("nn_queue_init\n"); nn_queue_init(&self->tasks); //PostMessage("nn_queue_item_init\n"); nn_queue_item_init(&self->stop); //PostMessage("nn_poller_init\n"); nn_poller_init(&self->poller); //PostMessage("nn_poller_add\n"); nn_poller_add(&self->poller,nn_efd_getfd(&self->efd),&self->efd_hndl); //PostMessage("nn_poller_set_in\n"); nn_poller_set_in(&self->poller, &self->efd_hndl); //PostMessage("nn_timerset_init\n"); nn_timerset_init(&self->timerset); //PostMessage("nn_thread_init\n"); nn_thread_init(&self->thread,nn_worker_routine, self); //PostMessage("finished nn_worker_init\n"); return 0; }
int main () { int rc; char buf [3]; struct nn_thread thread; sb = nn_socket (AF_SP, NN_PAIR); errno_assert (sb != -1); rc = nn_bind (sb, SOCKET_ADDRESS); errno_assert (rc >= 0); sc = nn_socket (AF_SP, NN_PAIR); errno_assert (sc != -1); rc = nn_connect (sc, SOCKET_ADDRESS); errno_assert (rc >= 0); nn_thread_init (&thread, worker, NULL); rc = nn_recv (sb, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (sb, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); nn_thread_term (&thread); rc = nn_close (sc); errno_assert (rc == 0); rc = nn_close (sb); errno_assert (rc == 0); return 0; }
int main (int argc, const char *argv[]) { int end0; int end1; struct nn_thread thread5; struct nn_thread thread6; int port = get_test_port(argc, argv); test_addr_from(socket_address_h, "tcp", "127.0.0.1", port); test_addr_from(socket_address_i, "tcp", "127.0.0.1", port + 1); test_addr_from(socket_address_j, "tcp", "127.0.0.1", port + 2); /* Test the bi-directional device with REQ/REP (headers). */ /* Start the devices. */ nn_thread_init (&thread5, device5, NULL); nn_thread_init (&thread6, device6, NULL); /* Create two sockets to connect to the device. */ end0 = test_socket (AF_SP, NN_REQ); test_connect (end0, socket_address_h); end1 = test_socket (AF_SP, NN_REP); test_connect (end1, socket_address_j); /* Wait for TCP to establish. */ nn_sleep (100); /* Pass a message between endpoints. */ test_send (end0, "XYZ"); test_recv (end1, "XYZ"); /* Now send a reply. */ test_send (end1, "REPLYXYZ"); test_recv (end0, "REPLYXYZ"); /* Clean up. */ test_close (end0); test_close (end1); /* Shut down the devices. */ nn_term (); nn_thread_term (&thread5); nn_thread_term (&thread6); return 0; }
int testipc_shutdown() { int sb; int i; int j; struct nn_thread threads [THREAD_COUNT]; printf("test ipc shutdown\n"); /* Stress the shutdown algorithm. */ #if defined(SIGPIPE) && defined(SIG_IGN) signal (SIGPIPE, SIG_IGN); #endif sb = test_socket (AF_SP, NN_PUB); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term (&threads [i]); } test_close (sb); /* Test race condition of sending message while socket shutting down */ sb = test_socket (AF_SP, NN_PUSH); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine2, NULL); active = TEST2_THREAD_COUNT; while ( active ) { (void) nn_send (sb, "hello", 5, NN_DONTWAIT); } for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_term(&threads [i]); } test_close (sb); return 0; }
int ftw_socket_inbox_construct(struct ftw_socket_inbox **inst, LVUserEventRef *msg_to_lv_event, struct ftw_socket_inbox **sock, const LStrHandleArray **addresses, int linger, int max_recv_size) { char *addr; int rcb; int rcs; int rco; int i; /* Preconditions expected of LabVIEW. */ ftw_assert(inst && *inst && addresses && *addresses && msg_to_lv_event && sock); rcs = nn_socket(AF_SP_RAW, NN_REP); /* Socket creation failure? */ if (rcs < 0) { *sock = NULL; return rcs; } rco = nn_setsockopt(rcs, NN_SOL_SOCKET, NN_LINGER, &linger, sizeof(linger)); if (rco < 0) { *sock = NULL; return rco; } rco = nn_setsockopt(rcs, NN_SOL_SOCKET, NN_RCVMAXSIZE, &max_recv_size, sizeof(max_recv_size)); if (rco < 0) { *sock = NULL; return rco; } for (i = 0; i < (*addresses)->dimsize; i++) { addr = ftw_support_LStrHandle_to_CStr((*addresses)->element[i]); rcb = nn_bind(rcs, addr); ftw_free (addr); if (rcb < 0) { nn_close(rcs); *sock = NULL; return rcb; } } (*inst)->incoming_msg_notifier_event = *msg_to_lv_event; (*inst)->id = rcs; /* Launch thread and wait for it to initialize. */ nn_sem_init(&(*inst)->deinitialized); nn_sem_init(&(*inst)->initialized); nn_sem_init(&(*inst)->msg_acknowledged); nn_thread_init(&(*inst)->async_recv_thread, ftw_socket_inbox_async_recv_worker, *inst); nn_sem_wait(&(*inst)->initialized); *sock = *inst; return 0; }
void *portable_thread_create(void *funcp,void *argp) { //void nn_thread_term(struct nn_thread *self); void nn_thread_init(struct nn_thread *self,portable_thread_func *routine,void *arg); struct nn_thread *ptr; ptr = (struct nn_thread *)malloc(sizeof(*ptr)); nn_thread_init(ptr,(portable_thread_func *)funcp,argp); return(ptr); }
int main () { int sb; int i; int j; struct nn_thread threads [THREAD_COUNT]; /* Stress the shutdown algorithm. */ sb = test_socket (AF_SP, NN_PUB); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term (&threads [i]); } test_close (sb); /* Test race condition of sending message while socket shutting down */ sb = test_socket (AF_SP, NN_PUSH); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine2, NULL); nn_atomic_init(&active, TEST2_THREAD_COUNT); while (active.n) { (void) nn_send (sb, "hello", 5, NN_DONTWAIT); } for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_term (&threads [i]); nn_atomic_term(&active); } test_close (sb); return 0; }
int main (int argc, char *argv []) { int rc; int s; int i; char *buf; struct nn_thread thread; struct nn_stopwatch stopwatch; uint64_t elapsed; double latency; if (argc != 3) { printf ("usage: inproc_lat <message-size> <roundtrip-count>\n"); return 1; } message_size = atoi (argv [1]); roundtrip_count = atoi (argv [2]); s = nn_socket (AF_SP, NN_PAIR); assert (s != -1); rc = nn_bind (s, "inproc://inproc_lat"); assert (rc >= 0); buf = malloc (message_size); assert (buf); memset (buf, 111, message_size); /* Wait a bit till the worker thread blocks in nn_recv(). */ nn_thread_init (&thread, worker, NULL); nn_sleep (100); nn_stopwatch_init (&stopwatch); for (i = 0; i != roundtrip_count; i++) { rc = nn_send (s, buf, message_size, 0); assert (rc == (int)message_size); rc = nn_recv (s, buf, message_size, 0); assert (rc == (int)message_size); } elapsed = nn_stopwatch_term (&stopwatch); latency = (double) elapsed / (roundtrip_count * 2); printf ("message size: %d [B]\n", (int) message_size); printf ("roundtrip count: %d\n", (int) roundtrip_count); printf ("average latency: %.3f [us]\n", (double) latency); nn_thread_term (&thread); free (buf); rc = nn_close (s); assert (rc == 0); return 0; }
int main () { int end0; int end1; struct nn_thread thread5; struct nn_thread thread6; /* Test the bi-directional device with REQ/REP (headers). */ /* Start the devices. */ nn_thread_init (&thread5, device5, NULL); nn_thread_init (&thread6, device6, NULL); /* Create two sockets to connect to the device. */ end0 = test_socket (AF_SP, NN_REQ); test_connect (end0, SOCKET_ADDRESS_H); end1 = test_socket (AF_SP, NN_REP); test_connect (end1, SOCKET_ADDRESS_J); /* Wait for TCP to establish. */ nn_sleep (1000); /* Pass a message between endpoints. */ test_send (end0, "XYZ"); test_recv (end1, "XYZ"); /* Now send a reply. */ test_send (end1, "REPLYXYZ"); test_recv (end0, "REPLYXYZ"); /* Clean up. */ test_close (end0); test_close (end1); /* Shut down the devices. */ nn_term (); nn_thread_term (&thread5); nn_thread_term (&thread6); return 0; }
int nn_tcpmuxd (int port) { int rc; int tcp_listener; int ipc_listener; int opt; struct sockaddr_in tcp_addr; struct sockaddr_un ipc_addr; struct nn_tcpmuxd_ctx *ctx; /* Start listening on the specified TCP port. */ tcp_listener = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); errno_assert (tcp_listener >= 0); opt = 1; rc = setsockopt (tcp_listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); errno_assert (rc == 0); memset (&tcp_addr, 0, sizeof (tcp_addr)); tcp_addr.sin_family = AF_INET; tcp_addr.sin_port = htons (port); tcp_addr.sin_addr.s_addr = INADDR_ANY; rc = bind (tcp_listener, (struct sockaddr*) &tcp_addr, sizeof (tcp_addr)); errno_assert (rc == 0); rc = listen (tcp_listener, 100); errno_assert (rc == 0); /* Start listening for incoming IPC connections. */ ipc_addr.sun_family = AF_UNIX; snprintf (ipc_addr.sun_path, sizeof (ipc_addr.sun_path), "/tmp/tcpmux-%d.ipc", (int) port); unlink (ipc_addr.sun_path); ipc_listener = socket (AF_UNIX, SOCK_STREAM, 0); errno_assert (ipc_listener >= 0); rc = bind (ipc_listener, (struct sockaddr*) &ipc_addr, sizeof (ipc_addr)); errno_assert (rc == 0); rc = listen (ipc_listener, 100); errno_assert (rc == 0); /* Allocate a context for the daemon. */ ctx = nn_alloc (sizeof (struct nn_tcpmuxd_ctx), "tcpmuxd context"); alloc_assert (ctx); ctx->tcp_listener = tcp_listener; ctx->ipc_listener = ipc_listener; nn_list_init (&ctx->conns); /* Run the daemon in a dedicated thread. */ nn_thread_init (&ctx->thread, nn_tcpmuxd_routine, ctx); return 0; }
int nn_worker_init (struct nn_worker *self) { int rc; rc = nn_efd_init (&self->efd); if (rc < 0) return rc; nn_mutex_init (&self->sync); nn_queue_init (&self->tasks); nn_queue_item_init (&self->stop); nn_poller_init (&self->poller); nn_poller_add (&self->poller, nn_efd_getfd (&self->efd), &self->efd_hndl); nn_poller_set_in (&self->poller, &self->efd_hndl); nn_timerset_init (&self->timerset); nn_thread_init (&self->thread, nn_worker_routine, self); return 0; }
int main () { struct nn_thread thread; sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); nn_thread_init (&thread, worker, NULL); test_recv (sb, "ABC"); test_recv (sb, "ABC"); nn_thread_term (&thread); test_close (sc); test_close (sb); return 0; }
int main () { int enda; int endb; int endc; int endd; int ende1; int ende2; struct nn_thread thread1; struct nn_thread thread2; struct nn_thread thread3; int timeo; /* Test the bi-directional device. */ /* Start the device. */ nn_thread_init (&thread1, device1, NULL); /* Create two sockets to connect to the device. */ enda = test_socket (AF_SP, NN_PAIR); test_connect (enda, SOCKET_ADDRESS_A); endb = test_socket (AF_SP, NN_PAIR); test_connect (endb, SOCKET_ADDRESS_B); /* Pass a pair of messages between endpoints. */ test_send (enda, "ABC"); test_recv (endb, "ABC"); test_send (endb, "ABC"); test_recv (enda, "ABC"); /* Clean up. */ test_close (endb); test_close (enda); /* Test the uni-directional device. */ /* Start the device. */ nn_thread_init (&thread2, device2, NULL); /* Create two sockets to connect to the device. */ endc = test_socket (AF_SP, NN_PUSH); test_connect (endc, SOCKET_ADDRESS_C); endd = test_socket (AF_SP, NN_PULL); test_connect (endd, SOCKET_ADDRESS_D); /* Pass a message between endpoints. */ test_send (endc, "XYZ"); test_recv (endd, "XYZ"); /* Clean up. */ test_close (endd); test_close (endc); /* Test the loopback device. */ /* Start the device. */ nn_thread_init (&thread3, device3, NULL); /* Create two sockets to connect to the device. */ ende1 = test_socket (AF_SP, NN_BUS); test_connect (ende1, SOCKET_ADDRESS_E); ende2 = test_socket (AF_SP, NN_BUS); test_connect (ende2, SOCKET_ADDRESS_E); /* BUS is unreliable so wait a bit for connections to be established. */ nn_sleep (100); /* Pass a message to the bus. */ test_send (ende1, "KLM"); test_recv (ende2, "KLM"); /* Make sure that the message doesn't arrive at the socket it was originally sent to. */ timeo = 100; test_setsockopt (ende1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); test_drop (ende1, ETIMEDOUT); /* Clean up. */ test_close (ende2); test_close (ende1); /* Shut down the devices. */ nn_term (); nn_thread_term (&thread1); nn_thread_term (&thread2); nn_thread_term (&thread3); return 0; }
int main (int argc, char *argv []) { int rc; int s; int i; char *buf; struct nn_thread thread; struct nn_stopwatch stopwatch; uint64_t elapsed; unsigned long throughput; double megabits; if (argc != 3) { printf ("usage: thread_thr <message-size> <message-count>\n"); return 1; } message_size = atoi (argv [1]); message_count = atoi (argv [2]); s = nn_socket (AF_SP, NN_PAIR); assert (s != -1); rc = nn_bind (s, "inproc://inproc_thr"); assert (rc >= 0); buf = malloc (message_size); assert (buf); nn_thread_init (&thread, worker, NULL); /* First message is used to start the stopwatch. */ rc = nn_recv (s, buf, message_size, 0); assert (rc == 0); nn_stopwatch_init (&stopwatch); for (i = 0; i != message_count; i++) { rc = nn_recv (s, buf, message_size, 0); assert (rc == message_size); } elapsed = nn_stopwatch_term (&stopwatch); nn_thread_term (&thread); free (buf); rc = nn_close (s); assert (rc == 0); if (elapsed == 0) elapsed = 1; throughput = (unsigned long) ((double) message_count / (double) elapsed * 1000000); megabits = (double) (throughput * message_size * 8) / 1000000; printf ("message size: %d [B]\n", (int) message_size); printf ("message count: %d\n", (int) message_count); printf ("mean throughput: %d [msg/s]\n", (int) throughput); printf ("mean throughput: %.3f [Mb/s]\n", (double) megabits); return 0; }
int ftw_subscriber_construct(struct ftw_socket_callsite **callsite, LVUserEventRef *lv_event, const char *addr, int linger, int max_recv_size, struct ftw_socket **sock) { struct ftw_socket *inst; int rcc; int rcs; int rco; /* Preconditions expected of LabVIEW. */ ftw_assert(*callsite && addr); nn_mutex_lock(&(*callsite)->sync); rcs = nn_socket(AF_SP, NN_SUB); /* Socket creation failure? */ if (rcs < 0) { *sock = NULL; nn_mutex_unlock(&(*callsite)->sync); return rcs; } rco = nn_setsockopt(rcs, NN_SOL_SOCKET, NN_LINGER, &linger, sizeof(linger)); if (rco < 0) { *sock = NULL; nn_mutex_unlock(&(*callsite)->sync); return rco; } rco = nn_setsockopt(rcs, NN_SOL_SOCKET, NN_RCVMAXSIZE, &max_recv_size, sizeof(max_recv_size)); if (rco < 0) { *sock = NULL; nn_mutex_unlock(&(*callsite)->sync); return rco; } rcc = nn_connect(rcs, addr); /* Endpoint creation failure? */ if (rcc < 0) { nn_close(rcs); *sock = NULL; nn_mutex_unlock(&(*callsite)->sync); return rcc; } rco = nn_setsockopt (rcs, NN_SUB, NN_SUB_SUBSCRIBE, "", 0); if (rco < 0) { nn_close(rcs); *sock = NULL; nn_mutex_unlock(&(*callsite)->sync); return rco; } inst = ftw_malloc(sizeof(struct ftw_socket)); ftw_assert(inst); inst->incoming_msg_notifier_event = *lv_event; inst->id = rcs; inst->callsite = *callsite; nn_list_item_init(&inst->item); nn_list_insert(&(*callsite)->active_sockets, &inst->item, nn_list_end(&(*callsite)->active_sockets)); nn_sem_init(&inst->msg_acknowledged); /* Launch thread and wait for it to initialize. */ nn_sem_init(&inst->async_recv_ready); nn_thread_init(&inst->async_recv_thread, ftw_subscriber_async_recv_thread, inst); nn_sem_wait(&inst->async_recv_ready); *sock = inst; (*callsite)->lifetime_sockets++; nn_mutex_unlock(&(*callsite)->sync); return 0; }
int main () { int rc; int sb; char buf [3]; struct nn_thread thread; struct nn_pollfd pfd [2]; /* Test nn_poll() function. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); test_send (sc, "ABC"); nn_sleep (100); pfd [0].fd = sb; pfd [0].events = NN_POLLIN | NN_POLLOUT; pfd [1].fd = sc; pfd [1].events = NN_POLLIN | NN_POLLOUT; rc = nn_poll (pfd, 2, -1); errno_assert (rc >= 0); nn_assert (rc == 2); nn_assert (pfd [0].revents == (NN_POLLIN | NN_POLLOUT)); nn_assert (pfd [1].revents == NN_POLLOUT); test_close (sc); test_close (sb); /* Create a simple topology. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); /* Check the initial state of the socket. */ rc = getevents (sb, NN_IN | NN_OUT, 1000); nn_assert (rc == NN_OUT); /* Poll for IN when there's no message available. The call should time out. */ rc = getevents (sb, NN_IN, 10); nn_assert (rc == 0); /* Send a message and start polling. This time IN event should be signaled. */ test_send (sc, "ABC"); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); /* Receive the message and make sure that IN is no longer signaled. */ test_recv (sb, "ABC"); rc = getevents (sb, NN_IN, 10); nn_assert (rc == 0); /* Check signalling from a different thread. */ nn_thread_init (&thread, routine1, NULL); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); test_recv (sb, "ABC"); nn_thread_term (&thread); /* Check terminating the library from a different thread. */ nn_thread_init (&thread, routine2, NULL); rc = getevents (sb, NN_IN, 1000); nn_assert (rc == NN_IN); rc = nn_recv (sb, buf, sizeof (buf), 0); nn_assert (rc < 0 && nn_errno () == ETERM); nn_thread_term (&thread); /* Clean up. */ test_close (sc); test_close (sb); return 0; }