int main (int argc, const char *argv[]) { int rc; int pair; int pull; int timeo; char socket_address_tcp[128]; test_addr_from(socket_address_tcp, "tcp", "127.0.0.1", get_test_port(argc, argv)); /* Inproc: Bind first, connect second. */ pair = test_socket (AF_SP, NN_PAIR); test_bind (pair, SOCKET_ADDRESS_INPROC); pull = test_socket (AF_SP, NN_PULL); test_connect (pull, SOCKET_ADDRESS_INPROC); timeo = 100; test_setsockopt (pair, NN_SOL_SOCKET, NN_SNDTIMEO, &timeo, sizeof (timeo)); rc = nn_send (pair, "ABC", 3, 0); errno_assert (rc < 0 && nn_errno () == ETIMEDOUT); test_close (pull); test_close (pair); /* Inproc: Connect first, bind second. */ pull = test_socket (AF_SP, NN_PULL); test_connect (pull, SOCKET_ADDRESS_INPROC); pair = test_socket (AF_SP, NN_PAIR); test_bind (pair, SOCKET_ADDRESS_INPROC); timeo = 100; test_setsockopt (pair, NN_SOL_SOCKET, NN_SNDTIMEO, &timeo, sizeof (timeo)); rc = nn_send (pair, "ABC", 3, 0); errno_assert (rc < 0 && nn_errno () == ETIMEDOUT); test_close (pull); test_close (pair); #if !defined NN_HAVE_WINDOWS /* IPC */ pair = test_socket (AF_SP, NN_PAIR); test_bind (pair, SOCKET_ADDRESS_IPC); pull = test_socket (AF_SP, NN_PULL); test_connect (pull, SOCKET_ADDRESS_IPC); timeo = 100; test_setsockopt (pair, NN_SOL_SOCKET, NN_SNDTIMEO, &timeo, sizeof (timeo)); rc = nn_send (pair, "ABC", 3, 0); errno_assert (rc < 0 && nn_errno () == ETIMEDOUT); test_close (pull); test_close (pair); #endif /* TCP */ pair = test_socket (AF_SP, NN_PAIR); test_bind (pair, socket_address_tcp); pull = test_socket (AF_SP, NN_PULL); test_connect (pull, socket_address_tcp); timeo = 100; test_setsockopt (pair, NN_SOL_SOCKET, NN_SNDTIMEO, &timeo, sizeof (timeo)); rc = nn_send (pair, "ABC", 3, 0); errno_assert (rc < 0 && nn_errno () == ETIMEDOUT); test_close (pull); test_close (pair); return 0; }
exception () : err (nn_errno ()) {}
int main () { int rc; int surveyor; int respondent1; int respondent2; int respondent3; int deadline; char buf [7]; /* Test a simple survey with three respondents. */ surveyor = test_socket (AF_SP, NN_SURVEYOR); deadline = 500; rc = nn_setsockopt (surveyor, NN_SURVEYOR, NN_SURVEYOR_DEADLINE, &deadline, sizeof (deadline)); errno_assert (rc == 0); test_bind (surveyor, SOCKET_ADDRESS); respondent1 = test_socket (AF_SP, NN_RESPONDENT); test_connect (respondent1, SOCKET_ADDRESS); respondent2 = test_socket (AF_SP, NN_RESPONDENT); test_connect (respondent2, SOCKET_ADDRESS); respondent3 = test_socket (AF_SP, NN_RESPONDENT); test_connect (respondent3, SOCKET_ADDRESS); /* Check that attempt to recv with no survey pending is EFSM. */ rc = nn_recv (surveyor, buf, sizeof (buf), 0); errno_assert (rc == -1 && nn_errno () == EFSM); /* Send the survey. */ test_send (surveyor, "ABC"); /* First respondent answers. */ test_recv (respondent1, "ABC"); test_send (respondent1, "DEF"); /* Second respondent answers. */ test_recv (respondent2, "ABC"); test_send (respondent2, "DEF"); /* Surveyor gets the responses. */ test_recv (surveyor, "DEF"); test_recv (surveyor, "DEF"); /* There are no more responses. Surveyor hits the deadline. */ rc = nn_recv (surveyor, buf, sizeof (buf), 0); errno_assert (rc == -1 && nn_errno () == ETIMEDOUT); /* Third respondent answers (it have already missed the deadline). */ test_recv (respondent3, "ABC"); test_send (respondent3, "GHI"); /* Surveyor initiates new survey. */ test_send (surveyor, "ABC"); /* Check that stale response from third respondent is not delivered. */ rc = nn_recv (surveyor, buf, sizeof (buf), 0); errno_assert (rc == -1 && nn_errno () == ETIMEDOUT); /* Check that subsequent attempt to recv with no survey pending is EFSM. */ rc = nn_recv (surveyor, buf, sizeof (buf), 0); errno_assert (rc == -1 && nn_errno () == EFSM); test_close (surveyor); test_close (respondent1); test_close (respondent2); test_close (respondent3); return 0; }
JNIEXPORT jint JNICALL Java_org_nanomsg_NanoLibrary_nn_1errno(JNIEnv* env, jobject obj) { return nn_errno(); }
int zmq_errno () { return nn_errno (); }
int outprocessControlThread(void *param) { OUTPROCESS_HANDLE_DATA * handleData = (OUTPROCESS_HANDLE_DATA*)param; if (handleData == NULL) { LogError("outprocessControlThread: parameter is NULL"); } else { int should_continue = 1; int needs_to_attach = 0; while (should_continue) { /*Codes_SRS_OUTPROCESS_MODULE_17_056: [ This thread shall ensure thread safety on the module data. ]*/ if (Lock(handleData->control_thread.thread_lock) != LOCK_OK) { LogError("unable to Lock"); should_continue = 0; break; } if (handleData->control_thread.thread_flag == THREAD_FLAG_STOP) { should_continue = 0; (void)Unlock(handleData->control_thread.thread_lock); break; } if (Unlock(handleData->control_thread.thread_lock) != LOCK_OK) { should_continue = 0; break; } if (needs_to_attach) { // our remote has detached. Attempt to reattach. /*Codes_SRS_OUTPROCESS_MODULE_17_059: [ If a Module Reply message has been received, and the status indicates the module has failed or has been terminated, this thread shall attempt to restart communications with module host process. ]*/ /*Codes_SRS_OUTPROCESS_MODULE_17_060: [ Once the control channel has been restarted, it shall follow the same process in Outprocess_Create to send a Create Message to the module host. ]*/ if (outprocessCreate(handleData) < 0) { LogError("attempting to reattach to remote failed"); } else { /*Codes_SRS_OUTPROCESS_MODULE_24_061: [ Once the control channel has been restarted and Create Message was sent, it shall send a Start Message to the module host. ]*/ send_start_message(handleData); needs_to_attach = 0; } } /*Codes_SRS_OUTPROCESS_MODULE_17_056: [ This thread shall ensure thread safety on the module data. ]*/ if (Lock(handleData->handle_lock) != LOCK_OK) { LogError("unable to Lock handle data"); should_continue = 0; break; } int nn_fd = handleData->control_socket; if (Unlock(handleData->handle_lock) != LOCK_OK) { should_continue = 0; break; } int nbytes; unsigned char *buf = NULL; errno = 0; /*Codes_SRS_OUTPROCESS_MODULE_17_057: [ This thread shall periodically attempt to receive a meesage from the module host process. ]*/ nbytes = nn_recv(nn_fd, (void *)&buf, NN_MSG, NN_DONTWAIT); if (nbytes < 0) { int receive_error = nn_errno(); if (receive_error != EAGAIN) should_continue = 0; } else { CONTROL_MESSAGE * msg = ControlMessage_CreateFromByteArray((const unsigned char*)buf, nbytes); nn_freemsg(buf); if (msg != NULL) { /*Codes_SRS_OUTPROCESS_MODULE_17_058: [ If a message has been received, it shall look for a Module Reply message. ]*/ if (msg->type == CONTROL_MESSAGE_TYPE_MODULE_REPLY) { CONTROL_MESSAGE_MODULE_REPLY * resp_msg = (CONTROL_MESSAGE_MODULE_REPLY*)msg; if (resp_msg->status != 0) { /*Codes_SRS_OUTPROCESS_MODULE_17_059: [ If a Module Reply message has been received, and the status indicates the module has failed or has been terminated, this thread shall attempt to restart communications with module host process. ]*/ needs_to_attach = 1; } } ControlMessage_Destroy(msg); } } ThreadAPI_Sleep(250); } } return 0; }
int main () { int rc; int push1; int push2; int pull1; int pull2; int sndprio; int rcvprio; /* Test send priorities. */ pull1 = test_socket (AF_SP, NN_PULL); test_bind (pull1, SOCKET_ADDRESS_A); pull2 = test_socket (AF_SP, NN_PULL); test_bind (pull2, SOCKET_ADDRESS_B); push1 = test_socket (AF_SP, NN_PUSH); sndprio = 1; rc = nn_setsockopt (push1, NN_SOL_SOCKET, NN_SNDPRIO, &sndprio, sizeof (sndprio)); errno_assert (rc == 0); test_connect (push1, SOCKET_ADDRESS_A); sndprio = 2; rc = nn_setsockopt (push1, NN_SOL_SOCKET, NN_SNDPRIO, &sndprio, sizeof (sndprio)); errno_assert (rc == 0); test_connect (push1, SOCKET_ADDRESS_B); test_send (push1, "ABC"); test_send (push1, "DEF"); test_recv (pull1, "ABC"); test_recv (pull1, "DEF"); test_close (pull1); test_close (push1); test_close (pull2); /* Test receive priorities. */ push1 = test_socket (AF_SP, NN_PUSH); test_bind (push1, SOCKET_ADDRESS_A); push2 = test_socket (AF_SP, NN_PUSH); test_bind (push2, SOCKET_ADDRESS_B); pull1 = test_socket (AF_SP, NN_PULL); rcvprio = 2; rc = nn_setsockopt (pull1, NN_SOL_SOCKET, NN_RCVPRIO, &rcvprio, sizeof (rcvprio)); errno_assert (rc == 0); test_connect (pull1, SOCKET_ADDRESS_A); rcvprio = 1; rc = nn_setsockopt (pull1, NN_SOL_SOCKET, NN_RCVPRIO, &rcvprio, sizeof (rcvprio)); errno_assert (rc == 0); test_connect (pull1, SOCKET_ADDRESS_B); test_send (push1, "ABC"); test_send (push2, "DEF"); nn_sleep (100); test_recv (pull1, "DEF"); test_recv (pull1, "ABC"); test_close (pull1); test_close (push2); test_close (push1); /* Test removing a pipe from the list. */ push1 = test_socket (AF_SP, NN_PUSH); test_bind (push1, SOCKET_ADDRESS_A); pull1 = test_socket (AF_SP, NN_PULL); test_connect (pull1, SOCKET_ADDRESS_A); test_send (push1, "ABC"); test_recv (pull1, "ABC"); test_close (pull1); rc = nn_send (push1, "ABC", 3, NN_DONTWAIT); nn_assert (rc == -1 && nn_errno() == EAGAIN); pull1 = test_socket (AF_SP, NN_PULL); test_connect (pull1, SOCKET_ADDRESS_A); test_send (push1, "ABC"); test_recv (pull1, "ABC"); test_close (pull1); test_close (push1); return 0; }
int main () { int rc; int rep1; int rep2; int req1; int req2; int resend_ivl; char buf [7]; int timeo; /* Test req/rep with full socket types. */ rep1 = nn_socket (AF_SP, NN_REP); errno_assert (rep1 != -1); rc = nn_bind (rep1, SOCKET_ADDRESS); errno_assert (rc >= 0); req1 = nn_socket (AF_SP, NN_REQ); errno_assert (req1 != -1); rc = nn_connect (req1, SOCKET_ADDRESS); errno_assert (rc >= 0); req2 = nn_socket (AF_SP, NN_REQ); errno_assert (req2 != -1); rc = nn_connect (req2, SOCKET_ADDRESS); errno_assert (rc >= 0); /* Check invalid sequence of sends and recvs. */ rc = nn_send (rep1, "ABC", 3, 0); nn_assert (rc == -1 && nn_errno () == EFSM); rc = nn_recv (req1, buf, sizeof (buf), 0); nn_assert (rc == -1 && nn_errno () == EFSM); /* Check fair queueing the requests. */ rc = nn_send (req2, "ABC", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (rep1, buf, 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (req2, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (req1, "ABC", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (rep1, buf, 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (req1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_close (rep1); errno_assert (rc == 0); rc = nn_close (req1); errno_assert (rc == 0); rc = nn_close (req2); errno_assert (rc == 0); /* Check load-balancing of requests. */ req1 = nn_socket (AF_SP, NN_REQ); errno_assert (req1 != -1); rc = nn_bind (req1, SOCKET_ADDRESS); errno_assert (rc >= 0); rep1 = nn_socket (AF_SP, NN_REP); errno_assert (rep1 != -1); rc = nn_connect (rep1, SOCKET_ADDRESS); errno_assert (rc >= 0); rep2 = nn_socket (AF_SP, NN_REP); errno_assert (rep2 != -1); rc = nn_connect (rep2, SOCKET_ADDRESS); errno_assert (rc >= 0); rc = nn_send (req1, "ABC", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (rep1, buf, 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (req1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (req1, "ABC", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep2, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_send (rep2, buf, 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (req1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_close (rep2); errno_assert (rc == 0); rc = nn_close (rep1); errno_assert (rc == 0); rc = nn_close (req1); errno_assert (rc == 0); /* Test re-sending of the request. */ rep1 = nn_socket (AF_SP, NN_REP); errno_assert (rep1 != -1); rc = nn_bind (rep1, SOCKET_ADDRESS); errno_assert (rc >= 0); req1 = nn_socket (AF_SP, NN_REQ); errno_assert (req1 != -1); rc = nn_connect (req1, SOCKET_ADDRESS); errno_assert (rc >= 0); resend_ivl = 100; rc = nn_setsockopt (req1, NN_REQ, NN_REQ_RESEND_IVL, &resend_ivl, sizeof (resend_ivl)); errno_assert (rc == 0); rc = nn_send (req1, "ABC", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_close (req1); errno_assert (rc == 0); rc = nn_close (rep1); errno_assert (rc == 0); /* Check sending a request when the peer is not available. (It should be sent immediatelly when the peer comes online rather than relying on the resend algorithm. */ req1 = nn_socket (AF_SP, NN_REQ); errno_assert (req1 != -1); rc = nn_connect (req1, SOCKET_ADDRESS); errno_assert (rc >= 0); rc = nn_send (req1, "ABC", 3, 0); errno_assert (rc >= 0); rep1 = nn_socket (AF_SP, NN_REP); errno_assert (rep1 != -1); rc = nn_bind (rep1, SOCKET_ADDRESS); errno_assert (rc >= 0); timeo = 100; rc = nn_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); errno_assert (rc == 0); rc = nn_recv (rep1, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_close (req1); errno_assert (rc == 0); rc = nn_close (rep1); errno_assert (rc == 0); return 0; }
bool pnet_internal_create_socket(pnet_socket *socket, pint16 type) { if (unlikely(!socket)) { plog_error("pnet_internal_create_socket() нет объекта socket"); return false; } int sock = nn_socket(AF_SP_RAW, type); if (unlikely(sock < 0)) { plog_error("pnet_internal_create_socket() не удалось создать сокет | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } socket->socket_fd = sock; int val = 1; if (unlikely(nn_setsockopt(socket->socket_fd, NN_TCP, NN_TCP_NODELAY, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_TCP_NODELAY | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } val = 0; if (unlikely(nn_setsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_LINGER, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_LINGER | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } val = 10000; if (unlikely(nn_setsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_RECONNECT_IVL_MAX | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } return true; }
int nn_device_entry (struct nn_device_recipe *device, int s1, int s2, NN_UNUSED int flags) { int rc; int op1; int op2; nn_fd s1rcv; nn_fd s1snd; nn_fd s2rcv; nn_fd s2snd; size_t opsz; /* At least one socket must be specified. */ if (device->required_checks & NN_CHECK_AT_LEAST_ONE_SOCKET) { if (s1 < 0 && s2 < 0) { errno = EBADF; return -1; } } /* Handle the case when there's only one socket in the device. */ if (device->required_checks & NN_CHECK_ALLOW_LOOPBACK) { if (s2 < 0) return nn_device_loopback (device,s1); if (s1 < 0) return nn_device_loopback (device,s2); } /* Check whether both sockets are "raw" sockets. */ if (device->required_checks & NN_CHECK_REQUIRE_RAW_SOCKETS) { opsz = sizeof (op1); rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_DOMAIN, &op1, &opsz); errno_assert (rc == 0); nn_assert (opsz == sizeof (op1)); opsz = sizeof (op2); rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_DOMAIN, &op2, &opsz); errno_assert (rc == 0); nn_assert (opsz == sizeof (op2)); if (op1 != AF_SP_RAW || op2 != AF_SP_RAW) { errno = EINVAL; return -1; } } /* Check whether both sockets are from the same protocol. */ if (device->required_checks & NN_CHECK_SAME_PROTOCOL_FAMILY) { opsz = sizeof (op1); rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_PROTOCOL, &op1, &opsz); errno_assert (rc == 0); nn_assert (opsz == sizeof (op1)); opsz = sizeof (op2); rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_PROTOCOL, &op2, &opsz); errno_assert (rc == 0); nn_assert (opsz == sizeof (op2)); if (op1 / 16 != op2 / 16) { errno = EINVAL; return -1; } } /* Get the file descriptors for polling. */ opsz = sizeof (s1rcv); rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_RCVFD, &s1rcv, &opsz); if (rc < 0 && nn_errno () == ENOPROTOOPT) s1rcv = -1; else { nn_assert (rc == 0); nn_assert (opsz == sizeof (s1rcv)); nn_assert (s1rcv >= 0); } opsz = sizeof (s1snd); rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_SNDFD, &s1snd, &opsz); if (rc < 0 && nn_errno () == ENOPROTOOPT) s1snd = -1; else { nn_assert (rc == 0); nn_assert (opsz == sizeof (s1snd)); nn_assert (s1snd >= 0); } opsz = sizeof (s2rcv); rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_RCVFD, &s2rcv, &opsz); if (rc < 0 && nn_errno () == ENOPROTOOPT) s2rcv = -1; else { nn_assert (rc == 0); nn_assert (opsz == sizeof (s2rcv)); nn_assert (s2rcv >= 0); } opsz = sizeof (s2snd); rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_SNDFD, &s2snd, &opsz); if (rc < 0 && nn_errno () == ENOPROTOOPT) s2snd = -1; else { nn_assert (rc == 0); nn_assert (opsz == sizeof (s2snd)); nn_assert (s2snd >= 0); } if (device->required_checks & NN_CHECK_SOCKET_DIRECTIONALITY) { /* Check the directionality of the sockets. */ if (s1rcv != -1 && s2snd == -1) { errno = EINVAL; return -1; } if (s1snd != -1 && s2rcv == -1) { errno = EINVAL; return -1; } if (s2rcv != -1 && s1snd == -1) { errno = EINVAL; return -1; } if (s2snd != -1 && s1rcv == -1) { errno = EINVAL; return -1; } } /* Two-directional device. */ if (device->required_checks & NN_CHECK_ALLOW_BIDIRECTIONAL) { if (s1rcv != -1 && s1snd != -1 && s2rcv != -1 && s2snd != -1) return nn_device_twoway (device, s1, s1rcv, s1snd, s2, s2rcv, s2snd); } if (device->required_checks & NN_CHECK_ALLOW_UNIDIRECTIONAL) { /* Single-directional device passing messages from s1 to s2. */ if (s1rcv != -1 && s1snd == -1 && s2rcv == -1 && s2snd != -1) return nn_device_oneway (device,s1, s1rcv, s2, s2snd); /* Single-directional device passing messages from s2 to s1. */ if (s1rcv == -1 && s1snd != -1 && s2rcv != -1 && s2snd == -1) return nn_device_oneway (device,s2, s2rcv, s1, s1snd); } /* This should never happen. */ nn_assert (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; }
int ss_nn_queue_create(json_object* items, nn_queue_t* nn_queue) { // int rv; int so_value; char* value = NULL; memset(nn_queue, 0, sizeof(nn_queue_t)); value = ss_json_string_get(items, "nm_url"); if (value == NULL) { fprintf(stderr, "nm_url is null\n"); goto error_out; } strlcpy(nn_queue->url, value, sizeof(nn_queue->url)); je_free(value); value = ss_json_string_get(items, "nm_type"); if (value == NULL) { fprintf(stderr, "nm_type is null\n"); goto error_out; } if (!strcasecmp(value, "BUS")) nn_queue->type = NN_BUS; else if (!strcasecmp(value, "PAIR")) nn_queue->type = NN_PAIR; else if (!strcasecmp(value, "PUSH")) nn_queue->type = NN_PUSH; else if (!strcasecmp(value, "PULL")) nn_queue->type = NN_PULL; else if (!strcasecmp(value, "PUB")) nn_queue->type = NN_PUB; else if (!strcasecmp(value, "SUB")) nn_queue->type = NN_SUB; else if (!strcasecmp(value, "REQ")) nn_queue->type = NN_REQ; else if (!strcasecmp(value, "REP")) nn_queue->type = NN_REP; else if (!strcasecmp(value, "SURVEYOR")) nn_queue->type = NN_SURVEYOR; else if (!strcasecmp(value, "RESPONDENT")) nn_queue->type = NN_RESPONDENT; else { fprintf(stderr, "unknown nm_type %s\n", value); goto error_out; } je_free(value); value = ss_json_string_get(items, "nm_format"); if (!strcasecmp(value, "metadata")) nn_queue->format = NN_FORMAT_METADATA; else if (!strcasecmp(value, "packet")) nn_queue->format = NN_FORMAT_PACKET; else { fprintf(stderr, "unknown nm_format %s\n", value); goto error_out; } je_free(value); nn_queue->conn = nn_socket(AF_SP, nn_queue->type); if (nn_queue->conn < 0) { fprintf(stderr, "could not allocate nm queue socket: %s\n", nn_strerror(nn_errno())); goto error_out; } so_value = 0; /* rv = nn_setsockopt(nn_queue->conn, NN_SOL_SOCKET, NN_IPV4ONLY, &so_value, sizeof(so_value)); if (rv != 0) { fprintf(stderr, "could not enable nm ipv6 support: %s\n", nn_strerror(nn_errno())); goto error_out; } */ nn_queue->remote_id = nn_connect(nn_queue->conn, nn_queue->url); if (nn_queue->remote_id < 0) { fprintf(stderr, "could not connect nm queue socket: %s\n", nn_strerror(nn_errno())); goto error_out; } fprintf(stderr, "created nm_queue type %s url %s\n", ss_nn_queue_type_dump(nn_queue->type), nn_queue->url); return 0; error_out: if (nn_queue) ss_nn_queue_destroy(nn_queue); if (value) je_free(value); return -1; }
int main () { int rc; int sb; int sc; int i; char buf [3]; int opt; size_t sz; /* Try closing bound but unconnected socket. */ #if 0 sb = nn_socket (AF_SP, NN_PAIR); errno_assert (sb >= 0); rc = nn_bind (sb, SOCKET_ADDRESS); errno_assert (rc > 0); rc = nn_close (sb); errno_assert (rc == 0); #endif /* Try closing a TCP socket while it not connected. At the same time test specifying the local address for connection. */ sc = nn_socket (AF_SP, NN_PAIR); errno_assert (sc != -1); rc = nn_connect (sc, "tcp://127.0.0.1;127.0.0.1:5555"); errno_assert (rc >= 0); rc = nn_close (sc); errno_assert (rc == 0); /* Open the socket anew. */ sc = nn_socket (AF_SP, NN_PAIR); errno_assert (sc != -1); /* Check NODELAY socket option. */ sz = sizeof (opt); rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz); errno_assert (rc == 0); nn_assert (sz == sizeof (opt)); nn_assert (opt == 0); opt = 2; rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt)); nn_assert (rc < 0 && nn_errno () == EINVAL); opt = 1; rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt)); errno_assert (rc == 0); sz = sizeof (opt); rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz); errno_assert (rc == 0); nn_assert (sz == sizeof (opt)); nn_assert (opt == 1); /* Try using invalid address strings. */ rc = nn_connect (sc, "tcp://*:"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "tcp://*:1000000"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "tcp://*:some_port"); nn_assert (rc < 0); rc = nn_connect (sc, "tcp://eth10000;127.0.0.1:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == ENODEV); rc = nn_bind (sc, "tcp://127.0.0.1:"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_bind (sc, "tcp://127.0.0.1:1000000"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_bind (sc, "tcp://eth10000:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == ENODEV); /* Connect correctly. Do so before binding the peer socket. */ rc = nn_connect (sc, SOCKET_ADDRESS); errno_assert (rc >= 0); /* Leave enough time for at least on re-connect attempt. */ nn_sleep (200); sb = nn_socket (AF_SP, NN_PAIR); errno_assert (sb != -1); rc = nn_bind (sb, SOCKET_ADDRESS); errno_assert (rc >= 0); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { rc = nn_send (sc, "ABC", 3, 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); rc = nn_send (sb, "DEF", 3, 0); errno_assert (rc >= 0); nn_assert (rc == 3); rc = nn_recv (sc, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 3); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { rc = nn_send (sc, "0123456789012345678901234567890123456789", 40, 0); errno_assert (rc >= 0); nn_assert (rc == 40); } for (i = 0; i != 100; ++i) { rc = nn_recv (sb, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 40); } rc = nn_close (sc); errno_assert (rc == 0); rc = nn_close (sb); errno_assert (rc == 0); return 0; }
int outprocessIncomingMessageThread(void *param) { /*Codes_SRS_OUTPROCESS_MODULE_17_037: [ This function shall receive the module handle data as the thread parameter. ]*/ OUTPROCESS_HANDLE_DATA * handleData = (OUTPROCESS_HANDLE_DATA*)param; if (handleData == NULL) { LogError("outprocess thread: parameter is NULL"); } else { int should_continue = 1; while (should_continue) { /*Codes_SRS_OUTPROCESS_MODULE_17_036: [ This function shall ensure thread safety on execution. ]*/ if (Lock(handleData->handle_lock) != LOCK_OK) { LogError("unable to Lock handle data"); should_continue = 0; break; } int nn_fd = handleData->message_socket; if (Unlock(handleData->handle_lock) != LOCK_OK) { should_continue = 0; break; } /*Codes_SRS_OUTPROCESS_MODULE_17_036: [ This function shall ensure thread safety on execution. ]*/ if (Lock(handleData->message_receive_thread.thread_lock) != LOCK_OK) { LogError("unable to Lock"); should_continue = 0; break; } if (handleData->message_receive_thread.thread_flag == THREAD_FLAG_STOP) { should_continue = 0; (void)Unlock(handleData->message_receive_thread.thread_lock); break; } if (Unlock(handleData->message_receive_thread.thread_lock) != LOCK_OK) { should_continue = 0; break; } int nbytes; unsigned char *buf = NULL; errno = 0; /*Codes_SRS_OUTPROCESS_MODULE_17_038: [ This function shall read from the message channel for gateway messages from the module host. ]*/ nbytes = nn_recv(nn_fd, (void *)&buf, NN_MSG, 0); if (nbytes < 0) { int receive_error = nn_errno(); if (receive_error != ETIMEDOUT && receive_error != EINTR) should_continue = 0; } else { /*Codes_SRS_OUTPROCESS_MODULE_17_039: [ Upon successful receiving a gateway message, this function shall deserialize the message. ]*/ const unsigned char*buf_bytes = (const unsigned char*)buf; MESSAGE_HANDLE msg = Message_CreateFromByteArray(buf_bytes, nbytes); if (msg != NULL) { /*Codes_SRS_OUTPROCESS_MODULE_17_040: [ This function shall publish any successfully created gateway message to the broker. ]*/ Broker_Publish(handleData->broker, (MODULE_HANDLE)handleData, msg); Message_Destroy(msg); } nn_freemsg(buf); } ThreadAPI_Sleep(1); } } return 0; }
int main (int argc, const char *argv[]) { int rc; int sb; int sc; int sb2; int opt; size_t sz; int i; char any_address[128]; test_addr_from (socket_address, "ws", "127.0.0.1", get_test_port (argc, argv)); test_addr_from (any_address, "ws", "*", get_test_port (argc, argv)); /* Try closing bound but unconnected socket. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, any_address); test_close (sb); /* Try closing a TCP socket while it not connected. At the same time test specifying the local address for the connection. */ sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, socket_address); test_close (sc); /* Open the socket anew. */ sc = test_socket (AF_SP, NN_PAIR); /* Check socket options. */ sz = sizeof (opt); rc = nn_getsockopt (sc, NN_WS, NN_WS_MSG_TYPE, &opt, &sz); errno_assert (rc == 0); nn_assert (sz == sizeof (opt)); nn_assert (opt == NN_WS_MSG_TYPE_BINARY); /* Default port 80 should be assumed if not explicitly declared. */ rc = nn_connect (sc, "ws://127.0.0.1"); errno_assert (rc >= 0); /* Try using invalid address strings. */ rc = nn_connect (sc, "ws://*:"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://*:1000000"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://*:some_port"); nn_assert (rc < 0); rc = nn_connect (sc, "ws://eth10000;127.0.0.1:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == ENODEV); rc = nn_bind (sc, "ws://127.0.0.1:"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_bind (sc, "ws://127.0.0.1:1000000"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_bind (sc, "ws://eth10000:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == ENODEV); rc = nn_connect (sc, "ws://:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://-hostname:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://abc.123.---.#:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://[::1]:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://abc.123.:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://abc...123:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); rc = nn_connect (sc, "ws://.123:5555"); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); test_close (sc); sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, socket_address); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, socket_address); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { test_send (sc, "ABC"); test_recv (sb, "ABC"); test_send (sb, "DEF"); test_recv (sc, "DEF"); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { test_send (sc, "0123456789012345678901234567890123456789"); } for (i = 0; i != 100; ++i) { test_recv (sb, "0123456789012345678901234567890123456789"); } test_close (sc); test_close (sb); /* Test two sockets binding to the same address. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, socket_address); sb2 = test_socket (AF_SP, NN_PAIR); rc = nn_bind (sb2, socket_address); nn_assert (rc < 0); errno_assert (nn_errno () == EADDRINUSE); test_close(sb); test_close(sb2); /* Test that NN_RCVMAXSIZE can be -1, but not lower */ sb = test_socket (AF_SP, NN_PAIR); opt = -1; rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt)); nn_assert (rc >= 0); opt = -2; rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt)); nn_assert (rc < 0); errno_assert (nn_errno () == EINVAL); test_close (sb); /* Test NN_RCVMAXSIZE limit */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, socket_address); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, socket_address); opt = 1000; test_setsockopt (sc, NN_SOL_SOCKET, NN_SNDTIMEO, &opt, sizeof (opt)); nn_assert (opt == 1000); opt = 1000; test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVTIMEO, &opt, sizeof (opt)); nn_assert (opt == 1000); opt = 4; test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt)); test_send (sc, "ABC"); test_recv (sb, "ABC"); test_send (sc, "ABCD"); test_recv (sb, "ABCD"); test_send (sc, "ABCDE"); test_drop (sb, ETIMEDOUT); /* Increase the size limit, reconnect, then try sending again. The reason a reconnect is necessary is because after a protocol violation, the connecting socket will not continue automatic reconnection attempts. */ opt = 5; test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt)); test_connect (sc, socket_address); test_send (sc, "ABCDE"); test_recv (sb, "ABCDE"); test_close (sb); test_close (sc); test_text (); /* Test closing a socket that is waiting to connect. */ sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, socket_address); nn_sleep (100); test_close (sc); return 0; }
bool pnet_internal_get_socketfd(pnet_socket *socket) { size_t sd_size = sizeof(int); if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_RCVFD, &socket->recv_fd, &sd_size))) { plog_error("pnet_server_start() не удалось получить NN_RCVFD | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_SNDFD, &socket->send_fd, &sd_size))) { plog_error("pnet_server_start() не удалось получить NN_SNDFD | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } return true; }
int main () { int rc; int sb; int sc; int s1, s2; int i; char buf [256]; int val; struct nn_msghdr hdr; struct nn_iovec iovec; unsigned char body [3]; void *control; struct nn_cmsghdr *cmsg; unsigned char *data; /* Create a simple topology. */ sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); /* Try a duplicate bind. It should fail. */ rc = nn_bind (sc, SOCKET_ADDRESS); nn_assert (rc < 0 && errno == EADDRINUSE); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { test_send (sc, "ABC"); test_recv (sb, "ABC"); test_send (sb, "DEFG"); test_recv (sc, "DEFG"); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { test_send (sc, "XYZ"); } for (i = 0; i != 100; ++i) { test_recv (sb, "XYZ"); } test_close (sc); test_close (sb); /* Test whether queue limits are observed. */ sb = test_socket (AF_SP, NN_PAIR); val = 200; rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVBUF, &val, sizeof (val)); errno_assert (rc == 0); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_PAIR); test_connect (sc, SOCKET_ADDRESS); val = 200; rc = nn_setsockopt (sc, NN_SOL_SOCKET, NN_SNDTIMEO, &val, sizeof (val)); errno_assert (rc == 0); i = 0; while (1) { rc = nn_send (sc, "0123456789", 10, 0); if (rc < 0 && nn_errno () == EAGAIN) break; errno_assert (rc >= 0); nn_assert (rc == 10); ++i; } nn_assert (i == 20); test_recv (sb, "0123456789"); test_send (sc, "0123456789"); rc = nn_send (sc, "0123456789", 10, 0); nn_assert (rc < 0 && nn_errno () == EAGAIN); for (i = 0; i != 20; ++i) { test_recv (sb, "0123456789"); } /* Make sure that even a message that doesn't fit into the buffers gets across. */ for (i = 0; i != sizeof (buf); ++i) buf [i] = 'A'; rc = nn_send (sc, buf, 256, 0); errno_assert (rc >= 0); nn_assert (rc == 256); rc = nn_recv (sb, buf, sizeof (buf), 0); errno_assert (rc >= 0); nn_assert (rc == 256); test_close (sc); test_close (sb); #if 0 /* Test whether connection rejection is handled decently. */ sb = test_socket (AF_SP, NN_PAIR); test_bind (sb, SOCKET_ADDRESS); s1 = test_socket (AF_SP, NN_PAIR); test_connect (s1, SOCKET_ADDRESS); s2 = test_socket (AF_SP, NN_PAIR); test_connect (s2, SOCKET_ADDRESS); nn_sleep (100); test_close (s2); test_close (s1); test_close (sb); #endif /* Check whether SP message header is transferred correctly. */ sb = test_socket (AF_SP_RAW, NN_REP); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_REQ); test_connect (sc, SOCKET_ADDRESS); test_send (sc, "ABC"); iovec.iov_base = body; iovec.iov_len = sizeof (body); hdr.msg_iov = &iovec; hdr.msg_iovlen = 1; hdr.msg_control = &control; hdr.msg_controllen = NN_MSG; rc = nn_recvmsg (sb, &hdr, 0); errno_assert (rc == 3); cmsg = NN_CMSG_FIRSTHDR (&hdr); while (1) { nn_assert (cmsg); if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) break; cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); } nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8)); data = NN_CMSG_DATA (cmsg); nn_assert (!(data[0] & 0x80)); nn_assert (data[4] & 0x80); nn_freemsg (control); test_close (sc); test_close (sb); /* Test binding a new socket after originally bound socket shuts down. */ sb = test_socket (AF_SP, NN_BUS); test_bind (sb, SOCKET_ADDRESS); sc = test_socket (AF_SP, NN_BUS); test_connect (sc, SOCKET_ADDRESS); s1 = test_socket (AF_SP, NN_BUS); test_connect (s1, SOCKET_ADDRESS); /* Close bound socket, leaving connected sockets connect. */ test_close (sb); nn_sleep (100); /* Rebind a new socket to the address to which our connected sockets are listening. */ s2 = test_socket (AF_SP, NN_BUS); test_bind (s2, SOCKET_ADDRESS); /* Ping-pong test. */ for (i = 0; i != 100; ++i) { test_send (sc, "ABC"); test_send (s1, "QRS"); test_recv (s2, "ABC"); test_recv (s2, "QRS"); test_send (s2, "DEFG"); test_recv (sc, "DEFG"); test_recv (s1, "DEFG"); } /* Batch transfer test. */ for (i = 0; i != 100; ++i) { test_send (sc, "XYZ"); } for (i = 0; i != 100; ++i) { test_recv (s2, "XYZ"); } for (i = 0; i != 100; ++i) { test_send (s1, "MNO"); } for (i = 0; i != 100; ++i) { test_recv (s2, "MNO"); } test_close (s1); test_close (sc); test_close (s2); return 0; }
static int outprocessCreate(void *param) { int thread_return; OUTPROCESS_HANDLE_DATA * handleData = (OUTPROCESS_HANDLE_DATA*)param; if (handleData == NULL) { LogError("async_create_receive_control thread: parameter is NULL"); thread_return = -1; } else { /*Codes_SRS_OUTPROCESS_MODULE_17_056: [ This thread shall ensure thread safety on the module data. ]*/ if (Lock(handleData->handle_lock) != LOCK_OK) { LogError("Unable to acquire handle data lock"); thread_return = -1; } else { int control_fd = handleData->control_socket; int remote_message_wait = (int)handleData->remote_message_wait; (void)Unlock(handleData->handle_lock); int should_continue = 1; do { int32_t creationMessageSize = 0; void * creationMessage = construct_create_message(handleData, &creationMessageSize); if (creationMessage == NULL) { /*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/ LogError("Unable to create create control message"); should_continue = 0; thread_return = -1; } else { /*Codes_SRS_OUTPROCESS_MODULE_17_013: [ This function shall send the Create Message on the control channel. ]*/ size_t default_wait_size = sizeof(remote_message_wait); if (nn_setsockopt(control_fd, NN_SOL_SOCKET, NN_RCVTIMEO, &remote_message_wait, default_wait_size) < 0) { LogError("Unable to set a receive timeout."); nn_freemsg(creationMessage); /* won't get to send that message we just created */ should_continue = 0; thread_return = -1; } else { int sendBytes = nn_send(control_fd, &creationMessage, NN_MSG, NN_DONTWAIT); if (sendBytes != creationMessageSize) { int send_err = nn_errno(); nn_freemsg(creationMessage); if (send_err != EAGAIN) { /*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/ LogError("unable to send create message [%p]", creationMessage); should_continue = 0; thread_return = -1; } else { ThreadAPI_Sleep((unsigned int)remote_message_wait); } } else { unsigned char *buf = NULL; /* This receive should time out if no one sends a response. */ int recvBytes = nn_recv(control_fd, (void *)&buf, NN_MSG, 0); if (recvBytes < 0) { int recv_error = nn_errno(); if (recv_error != EAGAIN && recv_error != ETIMEDOUT && recv_error != EINTR) { LogError("unexpected error on control channel receive: %d", recv_error); should_continue = 0; thread_return = -1; } } else { should_continue = 0; /* Only continue until we receive a message */ CONTROL_MESSAGE * msg = ControlMessage_CreateFromByteArray((const unsigned char*)buf, recvBytes); nn_freemsg(buf); if (msg == NULL) { thread_return = -1; } else { if (msg->type != CONTROL_MESSAGE_TYPE_MODULE_REPLY) { thread_return = -1; } else { CONTROL_MESSAGE_MODULE_REPLY * resp_msg = (CONTROL_MESSAGE_MODULE_REPLY*)msg; if (resp_msg->status != 0) { thread_return = -1; } else { /*Codes_SRS_OUTPROCESS_MODULE_17_015: [ This function shall expect a successful result from the Create Response to consider the module creation a success. ]*/ // complete success! thread_return = 1; } } ControlMessage_Destroy(msg); } } } } } } while (should_continue == 1); } } return thread_return; }