int client(int protocol_type, pid_t server_pid) { client_done = false; client_event_num = 0; // Sleep for 1ms to give the server time to start. usleep(1000); char address[256]; snprintf(address, 256, "%s://127.0.0.1:%d", protocol_type == msg_udp ? "udp" : "tcp", protocol_type == msg_udp ? udp_port : tcp_port); Context *ctx = malloc(sizeof(Context)); ctx->address = strdup(address); ctx->num_tries = 0; msg_connect(address, client_update, ctx); int timeout_in_ms = 10; while (!client_done) { msg_runloop(timeout_in_ms); // Check to see if the server process ended before we expected it to. int status; if (!client_done && waitpid(server_pid, &status, WNOHANG)) { test_failed("Client: Server process ended before client expected."); } } free(ctx->address); free(ctx); return test_success; }
/* * ptrace_attach() * Called by slave to first connect to master */ static void ptrace_attach(void) { struct proc *p = curthread->t_proc; port_t port; uint oflags; /* * Make sure we need to start up */ if ((p->p_dbg.pd_name == 0) || (p->p_dbg.pd_port != -1) || (p->p_dbg.pd_flags & PD_CONNECTING)) { v_sema(&p->p_sema); return; } /* * Try to connect. The PD_CONNECTING bit will keep other * threads from falling into this simultaneously. We need * to release p_sema because msg_connect() will acquire * it. */ oflags = p->p_dbg.pd_flags; p->p_dbg.pd_flags |= PD_CONNECTING; v_sema(&p->p_sema); port = msg_connect(p->p_dbg.pd_name, 0); /* * This might require taking the semaphore again, but I can't * think of a case where anybody else is allowed to fiddle * this while a connect is in progress. */ p->p_dbg.pd_flags = oflags; /* * If our connect bombs, junk this ptrace() request * and life just goes on. */ if (port < 0) { p->p_dbg.pd_name = 0; p->p_dbg.pd_flags = 0; return; } /* * Flag our port, and away we go */ p->p_dbg.pd_port = port; }
void client_update(msg_Conn *conn, msg_Event event, msg_Data data) { // We expect to hear events in this order: int expected_events[] = { msg_connection_ready, msg_connection_closed}; Context *ctx = (Context *)conn->conn_context; test_printf("Client: Received event %s\n", event_names[event]); if (event == msg_error) { char *err_str = msg_as_str(data); test_printf("Client: Error: %s\n", err_str); if (strcmp(err_str, "connect: Connection refused") == 0) { if (ctx->num_tries < max_tries) { test_printf("Client: Will wait briefly and try again at address %s.\n", ctx->address); sleep(5); ctx->num_tries++; msg_connect(ctx->address, client_update, ctx); return; // Don't count this as a server event. } else { test_printf("Client: max_tries reached; giving up connecting (at %s).\n", ctx->address); } } } if (event == msg_error) test_printf("Client: Error: %s\n", msg_as_str(data)); test_that(client_event_num < array_size(expected_events)); test_that(event == expected_events[client_event_num]); if (event == msg_connection_ready) { msg_Data data = msg_new_data("why hello"); msg_send(conn, data); msg_send(conn, data); msg_send(conn, data); msg_delete_data(data); client_done = true; } client_event_num++; }