int release_thread_ports( struct thread *tr ) { int count = 0; while ( tr->ports[0] != -1 ) { release_port( tr, tr->ports[0] ); count++; } return count; }
int rsem_wait(struct rsem_client *rcli, const char *name) { char err[512] = { 0 }; size_t err_len = sizeof(err); int ret, res, port, zfd = -1, zsock = -1; struct rsem_request req; struct json_object *jo; uint32_t ty, resp; struct sockaddr_in addr; port = wait_for_next_free_port(rcli); zsock = do_bind_and_listen(port, err, err_len); if (err[0]) { glitch_log("rsem_wait: do_bind_and_listen failed with " "error '%s'\n", err); ret = -EIO; zsock = -1; goto done; } zfd = do_socket(AF_INET, SOCK_STREAM, 0, WANT_O_CLOEXEC); if (zfd < 0) { glitch_log("rsem_wait: socket error: %d\n", zfd); ret = EIO; goto done; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(get_first_ipv4_addr(rcli->srv_host, err, err_len)); if (err[0]) { /* couldn't resolve hostname */ ret = EIO; goto done; } addr.sin_port = htons(rcli->srv_port); if (connect(zfd, &addr, sizeof(addr)) < 0) { ret = errno; glitch_log("rsem_wait: failed to connect to %s: error %d\n", rcli->srv_host, ret); goto done; } ty = htonl(RSEM_CLIENT_REQ_SEM); if (safe_write(zfd, &ty, sizeof(uint32_t))) { glitch_log("rsem_wait: short write of message type\n"); ret = -EIO; goto done; } memset(&req, 0, sizeof(req)); req.name = (char*)name; req.port = port; jo = JORM_TOJSON_rsem_request(&req); if (!jo) { ret = -ENOMEM; glitch_log("rsem_wait: out of memory\n"); goto done; } if (blocking_write_json_req("rsem_wait", zfd, jo)) { ret = -EIO; json_object_put(jo); goto done; } json_object_put(jo); if (safe_read(zfd, &resp, sizeof(uint32_t)) != sizeof(uint32_t)) { glitch_log("rsem_wait: short read of response\n"); ret = -EIO; goto done; } resp = ntohl(resp); RETRY_ON_EINTR(res, close(zfd)); zfd = -1; if (resp == RSEM_SERVER_GIVE_SEM) { ret = 0; } else if (resp == RSEM_SERVER_DELAY_SEM) { ret = rsem_wait_for_callback(name, zsock); } else { glitch_log("rsem_wait: unexpected server reply %d\n", resp); ret = -EIO; } done: if (zsock >= 0) RETRY_ON_EINTR(res, close(zsock)); if (zfd >= 0) RETRY_ON_EINTR(res, close(zfd)); release_port(rcli, port); return ret; }