static ucs_status_t test_poll_wait(ucp_worker_h ucp_worker) { int ret = -1; ucs_status_t status; int epoll_fd_local = 0, epoll_fd = 0; struct epoll_event ev; ev.data.u64 = 0; status = ucp_worker_get_efd(ucp_worker, &epoll_fd); if (status != UCS_OK) { goto err; } /* It is recommended to copy original fd */ epoll_fd_local = epoll_create(1); ev.data.fd = epoll_fd; ev.events = EPOLLIN; if (epoll_ctl(epoll_fd_local, EPOLL_CTL_ADD, epoll_fd, &ev) < 0) { fprintf(stderr, "Couldn't add original socket %d to the " "new epoll: %m\n", epoll_fd); goto err_fd; } /* Need to prepare ucp_worker before epoll_wait */ status = ucp_worker_arm(ucp_worker); if (status != UCS_OK) { goto err_fd; } do { ret = epoll_wait(epoll_fd_local, &ev, 1, -1); } while ((ret == -1) && (errno == EINTR)); ret = UCS_OK; err_fd: close(epoll_fd_local); err: return ret; }
int main(int argc, char **argv) { /* UCP temporary vars */ ucp_params_t ucp_params; ucp_worker_params_t worker_params; ucp_config_t *config; ucs_status_t status; /* UCP handler objects */ ucp_context_h ucp_context; /* OOB connection vars */ uint64_t addr_len = 0; char *server = NULL; int oob_sock = -1; int ret = -1; /* create the signalling pipe */ pipe(signal_pipe); /* Parse the command line */ if (parse_cmd(argc, argv, &server) != UCS_OK) { goto err; } /* UCP initialization */ status = ucp_config_read(NULL, NULL, &config); if (status != UCS_OK) { goto err; } ucp_params.features = UCP_FEATURE_TAG; if (ucp_test_mode == TEST_MODE_WAIT || ucp_test_mode == TEST_MODE_EVENTFD) { ucp_params.features |= UCP_FEATURE_WAKEUP; } ucp_params.request_size = sizeof(struct ucx_context); ucp_params.request_init = request_init; ucp_params.request_cleanup = NULL; status = ucp_init(&ucp_params, config, &ucp_context); ucp_config_print(config, stdout, NULL, UCS_CONFIG_PRINT_CONFIG); ucp_config_release(config); if (status != UCS_OK) { goto err; } worker_params.field_mask = UCP_WORKER_PARAM_FIELD_THREAD_MODE; worker_params.thread_mode = UCS_THREAD_MODE_SINGLE; status = ucp_worker_create(ucp_context, &worker_params, &ucp_worker); if (status != UCS_OK) { goto err_cleanup; } status = ucp_worker_get_address(ucp_worker, &local_addr, &local_addr_len); if (status != UCS_OK) { goto err_worker; } status = ucp_worker_get_efd(ucp_worker, &epoll_fd); if (status != UCS_OK) { goto err; } printf("[0x%x] local address length: %zu\n", (unsigned int)pthread_self(), local_addr_len); /* OOB connection establishment */ if (server) { peer_addr_len = local_addr_len; oob_sock = run_client(server); if (oob_sock < 0) { goto err_addr; } ret = recv(oob_sock, &addr_len, sizeof(addr_len), 0); if (ret < 0) { fprintf(stderr, "failed to receive address length\n"); goto err_addr; } peer_addr_len = addr_len; peer_addr = malloc(peer_addr_len); if (!peer_addr) { fprintf(stderr, "unable to allocate memory\n"); goto err_addr; } ret = recv(oob_sock, peer_addr, peer_addr_len, 0); if (ret < 0) { fprintf(stderr, "failed to receive address\n"); goto err_peer_addr; } } else { oob_sock = run_server(); if (oob_sock < 0) { goto err_peer_addr; } addr_len = local_addr_len; ret = send(oob_sock, &addr_len, sizeof(addr_len), 0); if (ret < 0 || ret != sizeof(addr_len)) { fprintf(stderr, "failed to send address length\n"); goto err_peer_addr; } ret = send(oob_sock, local_addr, local_addr_len, 0); if (ret < 0 || ret != local_addr_len) { fprintf(stderr, "failed to send address\n"); goto err_peer_addr; } } ret = run_test(NULL == server); /* Make sure remote is disconnected before destroying local worker */ barrier(oob_sock); close(oob_sock); err_peer_addr: free(peer_addr); err_addr: ucp_worker_release_address(ucp_worker, local_addr); err_worker: ucp_worker_destroy(ucp_worker); err_cleanup: ucp_cleanup(ucp_context); err: return ret; }