int init_state(State* s) { int rc; char* default_file = "/tmp/data"; size_t default_file_len = strnlen(default_file, MAXFILENAMELEN); s->fc = 98000000; // 98 MHz s->fs = 20000000; // 20 MHz s->lna_gain = 0; s->vga_gain = 0; s->samples_needed = 10000; s->filename = NULL; change_filename(s, default_file, default_file_len); s->fd = fopen(s->filename, "w"); rc = pthread_mutex_init(&(s->lock), NULL); CHECK_PTHREAD(rc) rc = pthread_cond_init(&(s->cond), NULL); CHECK_PTHREAD(rc) rc = pthread_mutex_lock(&(s->lock)); CHECK_PTHREAD(rc) return 0; }
static inline void handle(pone_world* world, int sig) { pone_universe* universe = world->universe; if (kv_size(universe->signal_channels[sig]) == 0) { // There's no signal handlers. // Then, remove sigmask sigset_t set; sigemptyset(&set); sigaddset(&set, sig); CHECK_PTHREAD(pthread_sigmask(SIG_UNBLOCK, &set, NULL)); signal(sig, SIG_DFL); // Send signal to me. CHECK_PTHREAD(pthread_kill(pthread_self(), sig)); // restore sigmask sigfillset(&set); CHECK_PTHREAD(pthread_sigmask(SIG_BLOCK, &set, NULL)); } // Send signal to channels. pone_push_scope(world); pone_val* sig_v = pone_int_new(world, sig); for (pone_int_t i = 0; i < kv_size(universe->signal_channels[sig]); i++) { pone_val* chan = kv_A(universe->signal_channels[sig], i); if (!pone_chan_trysend(world, chan, sig_v)) { fprintf(stderr, "[pone] cannot send signal to channel(%p): signal:%d\n", chan, sig); // this may not critical error. } } pone_pop_scope(world); }
static void* signal_thread(void* p) { pone_world* world = p; int sig; sigset_t set; sigfillset(&set); #ifdef __APPLE__ pthread_setname_np("pone signal ^^;"); #else pthread_setname_np(pthread_self(), "pone signal ^^;"); #endif CHECK_PTHREAD(pthread_mutex_lock(&(world->mutex))); THREAD_TRACE("Started signal thread"); for (;;) { if (sigwait(&set, &sig) != 0) { perror("sigwait"); // sigwait returns EINVAL. abort(); } CHECK_PTHREAD(pthread_mutex_lock(&(world->universe->signal_channels_mutex))); handle(world, sig); if (world->gc_requested) { pone_gc_run(world); } CHECK_PTHREAD(pthread_mutex_unlock(&(world->universe->signal_channels_mutex))); } abort(); // should not reach here. }
// Start signal thread. You should call this before run any threads. void pone_signal_start_thread(pone_world* world) { // mask all signals sigset_t set; sigfillset(&set); CHECK_PTHREAD(pthread_sigmask(SIG_BLOCK, &set, NULL)); world->universe->signal_world = pone_world_new(world->universe); CHECK_PTHREAD(pthread_create(&(world->universe->signal_thread), NULL, signal_thread, world->universe->signal_world)); }