/* * worker thread only processes one fake RPC. */ void *worker_thread(void *state) { int d = (int) state; char buf[4096]; int rv; int i; int ch; ch = imc_accept(d); write(2, "accepted\n", 9); rv = recv_imc_msg(ch, buf, sizeof buf, NULL); /* in case newlib version of stdio has thread safety issues */ write(2, "Got: ", 5); write(2, buf, rv); write(2, "\n", 1); /* echo it ... sdrawkcab! */ for (i = rv/2; --i >= 0; ) { char t = buf[rv - 1 - i]; buf[rv - 1 - i] = buf[i]; buf[i] = t; } send_imc_msg(ch, buf, -1); close(ch); close(d); return 0; }
int NaClSrpcAcceptClientOnThread(const struct NaClSrpcHandlerDesc* methods) { int sock_fd = -1; int result = 0; struct WorkerData *worker_data = NULL; pthread_t worker_tid; sock_fd = imc_accept(BOUND_SOCKET); if (sock_fd == -1) { goto done; } worker_data = (struct WorkerData*) malloc(sizeof *worker_data); if (worker_data == NULL) { goto done; } worker_data->sock_fd = sock_fd; worker_data->methods = methods; if (pthread_create(&worker_tid, NULL, Worker, (void *) worker_data) != 0) { goto done; } /* On successful thread start the worker takes ownership. */ worker_data = NULL; sock_fd = -1; result = 1; done: free(worker_data); if (sock_fd != -1) { close(sock_fd); } return result; }
void test_imc_accept_end_of_stream(void) { int bound_pair[2]; int rc; rc = imc_makeboundsock(bound_pair); assert(rc == 0); printf("Test imc_accept() when SocketAddress has been dropped...\n"); checked_close(bound_pair[1]); rc = imc_accept(bound_pair[0]); assert(rc == -1); assert(errno == EIO); checked_close(bound_pair[0]); }
int main(void) { int d; NaClSrpcModuleInit(); while ((d = imc_accept(3)) != -1) { pthread_t thr; if (0 != pthread_create(&thr, (pthread_attr_t *) NULL, RpcHandler, (void *) d)) { perror("pthread_create for RpcHandler"); abort(); } } NaClSrpcModuleFini(); return 0; }
/* * Acceptor loop: accept client connections, and for each, spawn a * worker thread that invokes the bad message loop. */ static void *acceptor(void *arg) { int d; while (-1 != (d = imc_accept(BOUND_SOCKET))) { struct worker_state *state = malloc(sizeof *state); pthread_t worker_tid; if (NULL == state) { fprintf(stderr, "No memory for accept\n"); exit(1); } state->d = d; /* worker thread is responsible for state and d. */ pthread_create(&worker_tid, NULL, worker, state); } return NULL; }
int NaClSrpcAcceptClientConnection(const struct NaClSrpcHandlerDesc *methods) { int sock_fd = -1; int result = 1; if (NaClSrpcIsStandalone()) { return NaClSrpcCommandLoopMain(methods); } sock_fd = imc_accept(BOUND_SOCKET); if (sock_fd == -1) { return 0; } if (!NaClSrpcServerLoop(sock_fd, methods, NULL)) { result = 0; } if (close(sock_fd) != 0) { result = 0; } return result; }
int NaClSrpcAcceptClientConnection(const struct NaClSrpcHandlerDesc *methods) { int sock_fd = -1; int result = 1; NaClSrpcLog(1, "NaClSrpcAcceptClientConnection(methods=%p)\n", (void*) methods); sock_fd = imc_accept(BOUND_SOCKET); if (sock_fd == -1) { NaClSrpcLog(NACL_SRPC_LOG_ERROR, "NaClSrpcAcceptClientConnection: imc_accept failed.\n"); return 0; } if (!NaClSrpcServerLoop(sock_fd, methods, NULL)) { NaClSrpcLog(1, "NaClSrpcAcceptClientConnection: NaClSrpcServerLoop exited.\n"); result = 0; } if (close(sock_fd) != 0) { NaClSrpcLog(NACL_SRPC_LOG_ERROR, "NaClSrpcAcceptClientConnection: close failed.\n"); result = 0; } return result; }
void *accept_thread(void *arg) { struct accept_thread_args *args = arg; args->result_fd = imc_accept(args->boundsock_fd); return NULL; }
int main(int ac, char **av) { int opt; char const *message = NULL; char const *message2 = NULL; int server = 0; int client_desc = -1; int channel; int sockaddrd; /* socket address descriptor */ int subchannel; int rv; char data_buffer[4096]; int desc_buffer[NACL_ABI_IMC_USER_DESC_MAX]; size_t i; unsigned long loop_iter = 1; unsigned int sleep_seconds = 0; while (EOF != (opt = getopt(ac, av, "c:l:m:M:sS:t:v"))) { switch (opt) { case 'c': client_desc = strtol(optarg, (char **) 0, 0); /* descriptor holds a connection capability for the server */ break; case 'l': loop_iter = strtoul(optarg, (char **) 0, 0); break; case 'm': message = optarg; break; case 'M': message2 = optarg; break; case 's': server = 1; break; case 'S': sleep_seconds = strtoul(optarg, (char **) 0, 0); break; default: fprintf(stderr, ("Usage: sel_ldr [sel_ldr_args] -- " /* no newline */ "nrd_xfer_test2.nexe [-c server-addr-desc] [-s]\n" " [-l loop_count] [-S server-sleep-sec]\n" "\n" "Typically, server is run using a command such as\n" "\n" " sel_ldr -X -1 -D 1 -f nrd_xfer_test2.nexe -- -s\n" "\n" "so the socket address is printed to standard output,\n" "and then the client is run with a command such as\n" "\n" " sel_ldr -X -1 -a 6:<addr-from-server> " /* no \n */ "-- nrd_xfer_test_nacl.nexe -c 6\n" "\n" "to have descriptor 6 be used to represent the socket\n" "address for connecting to the server\n")); return 1; } } for (i = 0; i < sizeof desc_buffer / sizeof desc_buffer[0]; ++i) { desc_buffer[i] = -1; } if (server) { message = (NULL != message) ? message : "\"Hello world!\", from server\n"; message2 = (NULL != message2) ? message2 : "SERVER MSG2"; } else { message = (NULL != message) ? message : "Client connect request\n"; message2 = (NULL != message2) ? message2 :"\"Goodbye cruel world!\", from client\n"; } if (server) { int pair[2]; pthread_t thr; int err; printf("Accepting a client connection...\n"); channel = imc_accept(3); printf("...got channel descriptor %d\n", channel); do { rv = recv_imc_msg(channel, data_buffer, sizeof data_buffer, NULL); printf("Receive returned %d\n", rv); if (-1 == rv) { fprintf(stderr, "imc_recvmsg failed\n"); return 1; } printf("Data bytes: %.*s\n", rv, data_buffer); /* send a reply */ if (-1 == imc_makeboundsock(pair)) { fprintf(stderr, "imc_socketpair failed, errno %d\n", errno); return 2; } /* * send pair[1], the addr, to peer as reply. */ send_imc_msg(channel, "sockaddr", pair[1]); err = pthread_create(&thr, NULL, worker_thread, (void *) pair[0]); if (0 != err) { fprintf(stderr, "pthread_create failed, returned %d\n", err); return 4; } pthread_detach(thr); if (-1 == close(pair[1])) { fprintf(stderr, "close of socketpair half failed\n"); } if (0 != sleep_seconds) { printf("sleeping for %d seconds...\n", sleep_seconds); sleep(sleep_seconds); } } while (--loop_iter > 0); if (-1 == close(channel)) { fprintf(stderr, "close of channel %d failed\n", channel); } } else { if (-1 == client_desc) { fprintf(stderr, "Client needs server socket address to which to connect\n"); return 100; } channel = imc_connect(client_desc); printf("Connect returned %d\n", channel); if (-1 == channel) { fprintf(stderr, "Client could not connect, errno %d\n", errno); return 101; } do { send_imc_msg(channel, message, -1); rv = recv_imc_msg(channel, data_buffer, sizeof data_buffer, &sockaddrd); printf("start RPC reply returned socket addr desc %d\n", sockaddrd); if (-1 == sockaddrd) { fprintf(stderr, "connect failed, errno %d\n", errno); return 106; } subchannel = imc_connect(sockaddrd); if (-1 == subchannel) { printf("Connect for client-specific socket failed: errno %d\n", errno); return 107; } if (-1 == close(sockaddrd)) { fprintf(stderr, "close of %d sockaddr failed, errno %d\n", sockaddrd, errno); } send_imc_msg(subchannel, message2, -1); if (-1 == (rv = recv_imc_msg(subchannel, data_buffer, sizeof data_buffer, NULL))) { fprintf(stderr, "receive from worker thread failed, errno %d\n", errno); return 108; } /* let's not trust server to NUL terminate */ data_buffer[sizeof data_buffer - 1] = '\0'; printf("reply: %s\n", data_buffer); if (-1 == close(subchannel)) { fprintf(stderr, "close of subchannel %d failed\n", subchannel); } } while (--loop_iter > 0); if (-1 == close(channel)) { fprintf(stderr, "close of %d (channel) failed\n", channel); } } return 0; }