/** Timer fibril. * * @param arg Timer */ static int fibril_timer_func(void *arg) { fibril_timer_t *timer = (fibril_timer_t *) arg; int rc; fibril_mutex_lock(&timer->lock); while (true) { while (timer->state != fts_active && timer->state != fts_cleanup) { if (timer->state == fts_cleanup) break; fibril_condvar_wait(&timer->cv, &timer->lock); } if (timer->state == fts_cleanup) break; rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock, timer->delay); if (rc == ETIMEOUT) { timer->state = fts_fired; fibril_mutex_unlock(&timer->lock); timer->fun(timer->arg); fibril_mutex_lock(&timer->lock); } } fibril_mutex_unlock(&timer->lock); return 0; }
void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) { int rc; rc = fibril_condvar_wait_timeout(fcv, fm, 0); assert(rc == EOK); }
/** Fibril for each accepted socket. * * @param arg Corresponding @c telnet_user_t structure. */ static int network_user_fibril(void *arg) { telnet_user_t *user = arg; int rc = loc_service_register(user->service_name, &user->service_id); if (rc != EOK) { telnet_user_error(user, "Unable to register %s with loc: %s.", user->service_name, str_error(rc)); return EOK; } telnet_user_log(user, "Service %s registerd with id %" PRIun ".", user->service_name, user->service_id); fid_t spawn_fibril = fibril_create(spawn_task_fibril, user); assert(spawn_fibril); fibril_add_ready(spawn_fibril); /* Wait for all clients to exit. */ fibril_mutex_lock(&user->guard); while (!user_can_be_destroyed_no_lock(user)) { if (user->task_finished) { closesocket(user->socket); user->socket_closed = true; user->srvs.aborted = true; continue; } else if (user->socket_closed) { if (user->task_id != 0) { task_kill(user->task_id); } } fibril_condvar_wait_timeout(&user->refcount_cv, &user->guard, 1000); } fibril_mutex_unlock(&user->guard); rc = loc_service_unregister(user->service_id); if (rc != EOK) { telnet_user_error(user, "Unable to unregister %s from loc: %s (ignored).", user->service_name, str_error(rc)); } telnet_user_log(user, "Destroying..."); telnet_user_destroy(user); return EOK; }
int main(int argc, char *argv[]) { int rc; int argi; rc = inetping_init(&ev_ops); if (rc != EOK) { printf(NAME ": Failed connecting to internet ping service " "(%d).\n", rc); return 1; } argi = 1; if (argi < argc && str_cmp(argv[argi], "-r") == 0) { ping_repeat = true; ++argi; } else { ping_repeat = false; } if (argc - argi != 1) { print_syntax(); return 1; } /* Parse destination address */ rc = addr_parse(argv[argi], &dest_addr); if (rc != EOK) { printf(NAME ": Invalid address format.\n"); print_syntax(); return 1; } /* Determine source address */ rc = inetping_get_srcaddr(&dest_addr, &src_addr); if (rc != EOK) { printf(NAME ": Failed determining source address.\n"); return 1; } fid_t fid; if (ping_repeat) { fid = fibril_create(transmit_fibril, NULL); if (fid == 0) { printf(NAME ": Failed creating transmit fibril.\n"); return 1; } fibril_add_ready(fid); fid = fibril_create(input_fibril, NULL); if (fid == 0) { printf(NAME ": Failed creating input fibril.\n"); return 1; } fibril_add_ready(fid); } else { ping_send(1); } fibril_mutex_lock(&done_lock); rc = EOK; while (!done && rc != ETIMEOUT) { rc = fibril_condvar_wait_timeout(&done_cv, &done_lock, ping_repeat ? 0 : PING_TIMEOUT); } fibril_mutex_unlock(&done_lock); if (rc == ETIMEOUT) { printf(NAME ": Echo request timed out.\n"); return 1; } return 0; }