static void setup_dbus_client(mrp_mainloop_t *ml) { DBusConnection *conn; int i, nmethod, nsignal; size_t size; ssize_t amount_read; nmethod = cfg.ndbus_method; nsignal = cfg.ndbus_signal; mrp_clear(&cfg); cfg.ndbus_method = nmethod; cfg.ndbus_signal = nsignal; mrp_mainloop_quit(ml, 0); #ifdef GLIB_ENABLED glib_pump_cleanup(); #endif mrp_mainloop_destroy(ml); for (i = 3; i < 1024; i++) if (i != dbus_test.pipe[0]) close(i); size = sizeof(dbus_test.address) - 1; amount_read = read(dbus_test.pipe[0], dbus_test.address, size); if (amount_read > 0) { dbus_test.address[amount_read] = '\0'; info("DBUS test: got address '%s'", dbus_test.address); } /*sleep(5);*/ if ((ml = dbus_test.ml = mrp_mainloop_create()) == NULL) fatal("failed to create mainloop"); cfg.ml = ml; if ((conn = dbus_test.conn = connect_to_dbus(NULL)) == NULL) fatal("failed to connect to DBUS"); if (!mrp_setup_dbus_connection(ml, conn)) fatal("failed to setup DBUS connection with mainloop"); if (mrp_add_timer(ml, 1000, client_send_msg, NULL) == NULL) fatal("failed to create DBUS message sending timer"); if (mrp_add_timer(ml, 1000, check_quit, NULL) == NULL) fatal("failed to create quit-check timer"); cfg.nrunning++; }
static void server_status_cb(mrp_dbus_t *dbus, const char *name, int up, const char *owner, void *user_data) { context_t *c = (context_t *)user_data; MRP_UNUSED(dbus); MRP_UNUSED(name); if (up) { mrp_log_info("%s came up (as %s)", name, owner); if (c->timer == NULL) { c->timer = mrp_add_timer(c->ml, 1000, send_cb, c); if (c->timer == NULL) { mrp_log_error("Failed to create D-BUS sending timer."); exit(1); } } } else { mrp_log_info("%s went down", name); if (c->timer != NULL) { mrp_del_timer(c->timer); c->timer = NULL; } } }
void setup_io(mrp_mainloop_t *ml) { test_io_t *w; mrp_io_event_t mask; int intervals[] = { IO_INTERVALS, 0 }, *iv = intervals; int msecs, i; if ((ios = mrp_allocz_array(test_io_t, cfg.nio)) != NULL) { mask = MRP_IO_EVENT_IN | MRP_IO_EVENT_HUP; for (i = 0, w = ios; i < cfg.nio; i++, w++) { w->id = i; msecs = *iv; while (cfg.runtime / msecs < 1 && msecs > 0) msecs /= 2; msecs *= 1000; if (!msecs) msecs = 500; w->target = 1000 * cfg.runtime / msecs; if (!w->target) continue; if (pipe(w->pipe) != 0) fatal("MRPH I/O #%d: could not create pipe", w->id); w->watch = mrp_add_io_watch(ml, w->pipe[0], mask, recv_io, w); w->timer = mrp_add_timer(ml, msecs, send_io, w); if (w->timer == NULL) fatal("MRPH I/O #%d: could not create I/O timer", w->id); if (w->watch == NULL) fatal("MRPH I/O #%d: could not create I/O watch", w->id); else info("MRPH I/O #%d: interval=%d, target=%d", w->id, *iv, w->target); cfg.nrunning++; iv++; if (!*iv) iv = intervals; } } else if (cfg.nio > 0) fatal("could not allocate %d I/O watches", cfg.nio); }
static void setup_signals(mrp_mainloop_t *ml) { test_signal_t *t; int intervals[] = { SIG_INTERVALS, 0 }, *iv = intervals; int signums[] = SIGNUMS, *s = signums; int msecs, i; if ((signals = mrp_allocz_array(test_signal_t, cfg.nsignal)) != NULL) { for (i = 0, t = signals; i < cfg.nsignal; i++, t++) { t->id = i; t->signum = *s; msecs = *iv; while (cfg.runtime / msecs < 1 && msecs > 0) msecs /= 2; msecs *= 1000; if (!msecs) msecs = 500; t->target = 1000 * cfg.runtime / msecs; if (!t->target) continue; t->watch = mrp_add_sighandler(ml, *s, recv_signal, t); t->timer = mrp_add_timer(ml, msecs, send_signal, t); if (t->timer == NULL) fatal("MRPH signal #%d: could not create timer", t->id); if (t->watch == NULL) fatal("MRPH signal #%d: could not create watch", t->id); else info("MRPH signal #%d: interval=%d, target=%d", t->id, *iv, t->target); cfg.nrunning++; iv++; if (!*iv) iv = intervals; s++; if (!*s) s = signums; } } else if (cfg.nsignal > 0) fatal("could not allocate %d signal watches", cfg.nsignal); }
static int timer_lua_create(lua_State *L) { mrp_context_t *ctx = mrp_lua_get_murphy_context(); char e[128] = ""; timer_lua_t *t; int narg; if (ctx == NULL) luaL_error(L, "failed to get murphy context"); narg = lua_gettop(L); t = (timer_lua_t *)mrp_lua_create_object(L, TIMER_LUA_CLASS, NULL, 0); t->L = L; t->ctx = ctx; t->callback = LUA_NOREF; t->data = LUA_NOREF; switch (narg) { case 1: break; case 2: if (mrp_lua_init_members(t, L, -2, e, sizeof(e)) != 1) return luaL_error(L, "failed to initialize timer members (%s)", e); break; default: return luaL_error(L, "expecting 0 or 1 constructor arguments, " "got %d", narg); } if (t->callback != LUA_NOREF && t->t == NULL) { t->t = mrp_add_timer(t->ctx->ml, t->msecs, timer_lua_cb, t); if (t->t == NULL) { mrp_lua_destroy_object(L, NULL, 0, t); return luaL_error(L, "failed to create Murphy timer"); } } mrp_lua_push_object(L, t); return 1; }
static void client_setup(context_t *c) { const char *dest; c->dbus = mrp_dbus_connect(c->ml, c->busaddr, NULL); if (c->dbus == NULL) { mrp_log_error("Failed to create D-BUS connection to '%s' bus.", c->busaddr); exit(1); } c->name = mrp_dbus_get_unique_name(c->dbus); mrp_log_info("Our address is %s on the bus...", c->name ? c->name : "unknown"); mrp_dbus_follow_name(c->dbus, SERVER_NAME, server_status_cb, c); if (c->all_pongs) { mrp_log_info("Subscribing for all pong signals..."); dest = NULL; } else { mrp_log_info("Subscribing only for pong signals to us..."); dest = c->name; } if (!mrp_dbus_subscribe_signal(c->dbus, pong_handler, c, dest, SERVER_PATH, SERVER_INTERFACE, PONG, NULL)) { mrp_log_error("Failed to subscribe for signal '%s/%s.%s'.", SERVER_PATH, SERVER_INTERFACE, PONG); exit(1); } c->timer = mrp_add_timer(c->ml, 1000, send_cb, c); if (c->timer == NULL) { mrp_log_error("Failed to create D-BUS sending timer."); exit(1); } }
static void setup_timers(mrp_mainloop_t *ml) { test_timer_t *t; int intervals[] = { TIMER_INTERVALS, 0 }, *iv = intervals; int msecs, i; if ((timers = mrp_allocz_array(test_timer_t, cfg.ntimer)) != NULL) { for (i = 0, t = timers; i < cfg.ntimer; i++, t++) { t->id = i; msecs = *iv; while (cfg.runtime / msecs < 1 && msecs > 0) msecs /= 2; msecs *= 1000; if (!msecs) msecs = 500; t->interval = msecs; t->target = 1000 * cfg.runtime / msecs; if (!t->target) continue; timeval_now(&t->prev); t->timer = mrp_add_timer(ml, t->interval, timer_cb, t); if (t->timer != NULL) info("MRPH timer #%d: interval=%d, target=%d", t->id, *iv, t->target); else fatal("MRPH timer #%d: failed to create", t->id); cfg.nrunning++; iv++; if (!*iv) iv = intervals; } } else if (cfg.ntimer > 0) fatal("could not allocate %d timers", cfg.ntimer); }
static void timer_lua_changed(void *data, lua_State *L, int member) { timer_lua_t *t = (timer_lua_t *)data; MRP_UNUSED(L); mrp_debug("timer member #%d (%s) changed", member, timer_lua_members[member].name); switch (member) { case TIMER_MEMBER_INTERVAL: if (t->t != NULL) mrp_mod_timer(t->t, t->msecs); else { enable: t->t = mrp_add_timer(t->ctx->ml, t->msecs, timer_lua_cb, t); if (t->t == NULL) luaL_error(L, "failed to create Murphy timer"); } break; case TIMER_MEMBER_CALLBACK: if (t->callback == LUA_NOREF) { mrp_del_timer(t->t); t->t = NULL; } else { if (t->t == NULL) goto enable; } break; default: break; } }
int main(int argc, char *argv[]) { mrp_mainloop_t *ml; mrp_clear(&cfg); parse_cmdline(&cfg, argc, argv); mrp_log_set_mask(cfg.log_mask); mrp_log_set_target(cfg.log_target); ml = mainloop_create(&cfg); if (ml == NULL) fatal("failed to create main loop."); dbus_test.ml = ml; setup_dbus_tests(ml); ml = dbus_test.ml; setup_timers(ml); setup_io(ml); setup_signals(ml); MRP_UNUSED(setup_deferred); /* XXX TODO: add deferred tests... */ #ifdef GLIB_ENABLED if (cfg.mainloop_type != MAINLOOP_GLIB && cfg.mainloop_type != MAINLOOP_QT) { if (cfg.ngio > 0 || cfg.ngtimer > 0) glib_pump_setup(ml); } setup_glib_io(); setup_glib_timers(); #endif if (mrp_add_timer(ml, 1000, check_quit, NULL) == NULL) fatal("failed to create quit-check timer"); setup_wakeup(ml); mainloop_run(&cfg); check_io(); check_timers(); check_signals(); #ifdef GLIB_ENABLED check_glib_io(); check_glib_timers(); #endif if (dbus_test.client != 0) close(dbus_test.pipe[1]); /* let the client continue */ check_dbus(); #ifdef GLIB_ENABLED if (cfg.mainloop_type != MAINLOOP_GLIB) { if (cfg.ngio > 0 || cfg.ngtimer > 0) glib_pump_cleanup(); } #endif cleanup_wakeup(); mainloop_cleanup(&cfg); }