/* static */ int daemon::start(const char *cwd, const char *pidfile /* = NULL */, const char *logfile /* = NULL */) { int fdpid = -1; if (pidfile) { stored_pidfile = strdup(pidfile); if (NULL == stored_pidfile) LOGGER_ERROR_STR_EXIT(EXIT_FAILURE, "daemon::start, strdup"); if ((fdpid = create_pidfile(pidfile)) < 0) exit(EXIT_FAILURE); } pid_t pid = fork(); if (pid < 0) { logger::perror("daemon::start, fork"); exit(EXIT_FAILURE); } if (pid > 0) { logger::log("daemon started (pid=%d)", pid); exit(EXIT_SUCCESS); } umask(0); if (0 > setsid()) { logger::perror("setsid"); exit(EXIT_FAILURE); } if (NULL != cwd && 0 > chdir("/")) { logger::perror("chdir"); exit(EXIT_FAILURE); } reset_fds(); init_logfile(logfile); pid = getpid(); if (fdpid >= 0) { dprintf(fdpid, "%d", pid); ::close(fdpid); } logger::log("child process started (pid=%d)", pid); return 0; }
static void test_gpoll (void) { SOCKET sockets[NUM_POLLEES]; GPollFD fds[NUM_POLLFDS]; SOCKET opp_sockets[NUM_POLLEES]; gint i; gint activatable; gint64 times[REPEAT][2]; #define BUCKET_COUNT 25 gint64 bucket_limits[BUCKET_COUNT] = {3, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 120, 150, 180, 220, 280, 350, 450, 600, 800, 1000}; gint buckets[BUCKET_COUNT]; gint64 times_avg = 0, times_min = G_MAXINT64, times_max = 0; prepare_sockets (sockets, opp_sockets, fds, NUM_POLLEES); prepare_fds (sockets, fds, NUM_POLLEES); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); for (i = 0; i < REPEAT; i++) { gint r; gint64 diff; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 0); times[i][1] = g_get_monotonic_time (); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); activatable = 0; for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; MSG msg; gboolean found_app; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = send (opp_sockets[activatable], (const char *) &t, 1, 0); g_assert (PostMessage (NULL, WM_APP, 1, 2)); /* This is to ensure that all sockets catch up, otherwise some might not poll active */ g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); v = recv (sockets[activatable], (char *) &t, 1, 0); found_app = FALSE; while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) found_app = TRUE; g_assert (s == 1); g_assert (r == 2); g_assert (v == 1); g_assert (found_app); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; activatable = (activatable + 1) % NUM_POLLEES; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); activatable = 0; for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = send (opp_sockets[activatable], (const char *) &t, 1, 0); g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); v = recv (sockets[activatable], (char *) &t, 1, 0); g_assert (s == 1); g_assert (r == 1); g_assert (v == 1); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; activatable = (activatable + 1) % NUM_POLLEES; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; gint j; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = v = 0; for (j = 0; j < NUM_POLLEES / 2; j++) s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); for (j = 0; j < NUM_POLLEES / 2; j++) v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; g_assert (s == NUM_POLLEES / 2); g_assert (r == NUM_POLLEES / 2); g_assert (v == NUM_POLLEES / 2); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; gint j; MSG msg; gboolean found_app; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = v = 0; for (j = 0; j < NUM_POLLEES / 2; j++) s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; g_assert (PostMessage (NULL, WM_APP, 1, 2)); /* This is to ensure that all sockets catch up, otherwise some might not poll active */ g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); for (j = 0; j < NUM_POLLEES / 2; j++) v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; found_app = FALSE; while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) found_app = TRUE; g_assert (s == NUM_POLLEES / 2); g_assert (r == NUM_POLLEES / 2 + 1); g_assert (v == NUM_POLLEES / 2); g_assert (found_app); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; gint j; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = v = 0; for (j = 0; j < NUM_POLLEES; j++) s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); for (j = 0; j < NUM_POLLEES; j++) v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; g_assert (s == NUM_POLLEES); g_assert (r == NUM_POLLEES); g_assert (v == NUM_POLLEES); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); } times_avg /= NUM_POLLEES; g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); activatable = 0; times_avg = 0; times_min = G_MAXINT64; times_max = 0; memset (buckets, 0, sizeof (gint) * BUCKET_COUNT); for (i = 0; i < REPEAT; i++) { gint r, s, v, t; gint64 diff; gint j; MSG msg; gboolean found_app; reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); s = v = 0; for (j = 0; j < activatable; j++) s += send (opp_sockets[j], (const char *) &t, 1, 0) == 1 ? 1 : 0; g_assert (PostMessage (NULL, WM_APP, 1, 2)); g_usleep (G_USEC_PER_SEC / 1000); times[i][0] = g_get_monotonic_time (); r = g_poll (fds, NUM_POLLFDS, 1000); times[i][1] = g_get_monotonic_time (); check_fds (sockets, fds, NUM_POLLEES); for (j = 0; j < activatable; j++) v += recv (sockets[j], (char *) &t, 1, 0) == 1 ? 1 : 0; found_app = FALSE; while (!found_app && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) if (msg.message == WM_APP && msg.wParam == 1 && msg.lParam == 2) found_app = TRUE; g_assert (s == activatable); g_assert (r == activatable + 1); g_assert (v == activatable); g_assert (found_app); reset_fds (fds, NUM_POLLEES); reset_fds_msg (fds, NUM_POLLFDS); r = g_poll (fds, NUM_POLLFDS, 0); check_fds (sockets, fds, NUM_POLLEES); g_assert (r == 0); diff = times[i][1] - times[i][0]; if (times_min > diff) times_min = diff; if (times_max < diff) times_max = diff; times_avg += diff; bucketize (diff, buckets, bucket_limits, BUCKET_COUNT); activatable = (activatable + 1) % NUM_POLLEES; } times_avg /= NUM_POLLEES; g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); print_buckets (buckets, bucket_limits, BUCKET_COUNT); cleanup_sockets (sockets, opp_sockets, NUM_POLLEES); }