// Process incoming messages in the background static void *rpc_server_func(void *arg) { rpc_connection_t *connection = (rpc_connection_t *)arg; int ret = rpc_listen_socket(connection); if (ret < 0) return NULL; connection->server_thread_active = 1; for (;;) { // XXX broken MacOS X doesn't implement cancellation points correctly pthread_testcancel(); // wait for data to arrive int ret = _rpc_wait_dispatch(connection, 50000); if (ret == 0) continue; if (ret < 0) break; rpc_dispatch(connection); } connection->server_thread_active = 0; return NULL; }
int main (int argc, char *argv[]) { if (rpc_test_get_connection_path) g_connection_path = rpc_test_get_connection_path (); else g_connection_path = NPW_CONNECTION_PATH "/Test.RPC"; #ifdef BUILD_CLIENT gchar **child_args; if (argc < 2) g_error ("no server program provided on command line"); signal (SIGSEGV, urgent_exit_sig); signal (SIGBUS, urgent_exit_sig); signal (SIGINT, urgent_exit_sig); signal (SIGABRT, urgent_exit_sig); if ((child_args = clone_args (argv)) == NULL) g_error ("could not create server program arguments\n"); g_free (child_args[0]); child_args[0] = g_strdup (argv[1]); if (!g_spawn_async (NULL, child_args, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &g_child_pid, NULL)) g_error ("could not start server program '%s'", child_args[0]); g_strfreev (child_args); if ((g_connection = rpc_init_client (g_connection_path)) == NULL) g_error ("failed to initialize RPC client connection"); #endif #ifdef BUILD_SERVER if ((g_connection = rpc_init_server (g_connection_path)) == NULL) g_error ("failed to initialize RPC server connection"); #endif int fd = -1; GSource *rpc_source = NULL; guint rpc_source_id = 0; GPollFD rpc_event_poll_fd; #ifdef BUILD_CLIENT fd = rpc_socket (g_connection); #endif #ifdef BUILD_SERVER fd = rpc_listen_socket (g_connection); #endif RPC_TEST_ENSURE (fd >= 0); if ((rpc_source = g_source_new (&rpc_event_funcs, sizeof (GSource))) == NULL) g_error ("failed to initialize RPC source"); rpc_source_id = g_source_attach (rpc_source, NULL); memset (&rpc_event_poll_fd, 0, sizeof (rpc_event_poll_fd)); rpc_event_poll_fd.fd = fd; rpc_event_poll_fd.events = G_IO_IN; rpc_event_poll_fd.revents = 0; g_source_add_poll (rpc_source, &rpc_event_poll_fd); static const rpc_method_descriptor_t vtable[] = { { RPC_TEST_METHOD_EXIT, handle_rpc_test_exit } }; if (rpc_connection_add_method_descriptor (g_connection, &vtable[0]) < 0) g_error ("could not add method descriptor for TEST_RPC_METHOD_EXIT"); g_main_loop = g_main_loop_new (NULL, TRUE); #ifdef BUILD_CLIENT g_child_watch_id = g_child_watch_add (g_child_pid, child_exited_cb, NULL); #endif rpc_test_init_invoke (argv); g_main_loop_run (g_main_loop); if (rpc_source_id) g_source_remove (rpc_source_id); if (g_connection) rpc_exit (g_connection); return g_exit_status; }