/* * call-seq: * mq.notify = signal => signal * * Registers the notification request to deliver a given +signal+ * to the current process when message is received. * If +signal+ is +nil+, it will unregister and disable the notification * request to allow other processes to register a request. * If +signal+ is +false+, it will register a no-op notification request * which will prevent other processes from registering a notification. * If +signal+ is an +IO+ object, it will spawn a thread upon the * arrival of the next message and write one "\\0" byte to the file * descriptor belonging to that IO object. * Only one process may have a notification request for a queue * at a time, Errno::EBUSY will be raised if there is already * a notification request registration for the queue. * * Notifications are only fired once and processes must reregister * for subsequent notifications. * * For readers of the mq_notify(3) manpage, passing +false+ * is equivalent to SIGEV_NONE, and passing +nil+ is equivalent * of passing a NULL notification pointer to mq_notify(3). */ static VALUE setnotify(VALUE self, VALUE arg) { struct posix_mq *mq = get(self, 1); struct sigevent not; struct sigevent * notification = ¬ VALUE rv = arg; notify_cleanup(self); not.sigev_notify = SIGEV_SIGNAL; switch (TYPE(arg)) { case T_FALSE: not.sigev_notify = SIGEV_NONE; break; case T_NIL: notification = NULL; break; case T_FIXNUM: not.sigev_signo = NUM2INT(arg); break; case T_SYMBOL: case T_STRING: not.sigev_signo = lookup_sig(arg); rv = INT2NUM(not.sigev_signo); break; default: rb_raise(rb_eArgError, "must be a signal or nil"); } my_mq_notify(mq->des, notification); return rv; }
/** * Clean up zone. * */ void zone_cleanup(zone_type* zone) { allocator_type* allocator; lock_basic_type zone_lock; lock_basic_type xfr_lock; if (!zone) { return; } allocator = zone->allocator; zone_lock = zone->zone_lock; xfr_lock = zone->xfr_lock; ldns_rdf_deep_free(zone->apex); adapter_cleanup(zone->adinbound); adapter_cleanup(zone->adoutbound); namedb_cleanup(zone->db); ixfr_cleanup(zone->ixfr); xfrd_cleanup(zone->xfrd); notify_cleanup(zone->notify); signconf_cleanup(zone->signconf); stats_cleanup(zone->stats); allocator_deallocate(allocator, (void*) zone->notify_command); allocator_deallocate(allocator, (void*) zone->notify_args); allocator_deallocate(allocator, (void*) zone->policy_name); allocator_deallocate(allocator, (void*) zone->signconf_filename); allocator_deallocate(allocator, (void*) zone->name); allocator_deallocate(allocator, (void*) zone); allocator_cleanup(allocator); lock_basic_destroy(&xfr_lock); lock_basic_destroy(&zone_lock); return; }
/** * Update DNS configuration for zone. * */ static int dnsconfig_zone(engine_type* engine, zone_type* zone) { int numdns = 0; ods_log_assert(engine); ods_log_assert(engine->xfrhandler); ods_log_assert(engine->xfrhandler->netio); ods_log_assert(zone); ods_log_assert(zone->adinbound); ods_log_assert(zone->adoutbound); ods_log_assert(zone->name); if (zone->adinbound->type == ADAPTER_DNS) { /* zone transfer handler */ if (!zone->xfrd) { ods_log_debug("[%s] add transfer handler for zone %s", engine_str, zone->name); zone->xfrd = xfrd_create((void*) engine->xfrhandler, (void*) zone); ods_log_assert(zone->xfrd); netio_add_handler(engine->xfrhandler->netio, &zone->xfrd->handler); } else if (!zone->xfrd->serial_disk_acquired) { xfrd_set_timer_now(zone->xfrd); } numdns++; } else if (zone->xfrd) { netio_remove_handler(engine->xfrhandler->netio, &zone->xfrd->handler); xfrd_cleanup(zone->xfrd); zone->xfrd = NULL; } if (zone->adoutbound->type == ADAPTER_DNS) { /* notify handler */ if (!zone->notify) { ods_log_debug("[%s] add notify handler for zone %s", engine_str, zone->name); zone->notify = notify_create((void*) engine->xfrhandler, (void*) zone); ods_log_assert(zone->notify); netio_add_handler(engine->xfrhandler->netio, &zone->notify->handler); } numdns++; } else if (zone->notify) { netio_remove_handler(engine->xfrhandler->netio, &zone->notify->handler); notify_cleanup(zone->notify); zone->notify = NULL; } return numdns; }
/** * Create notify structure. * */ notify_type* notify_create(void* xfrhandler, void* zone) { notify_type* notify = NULL; allocator_type* allocator = NULL; if (!xfrhandler || !zone) { return NULL; } allocator = allocator_create(malloc, free); if (!allocator) { ods_log_error("[%s] unable to create notify structure: " "allocator_create() failed", notify_str); return NULL; } notify = (notify_type*) allocator_alloc(allocator, sizeof(notify_type)); if (!notify) { ods_log_error("[%s] unable to create notify structure: " " allocator_alloc() failed", notify_str); allocator_cleanup(allocator); return NULL; } notify->allocator = allocator; notify->zone = zone; notify->xfrhandler = xfrhandler; notify->waiting_next = NULL; notify->secondary = NULL; notify->soa = NULL; notify->tsig_rr = tsig_rr_create(allocator); if (!notify->tsig_rr) { notify_cleanup(notify); return NULL; } notify->retry = 0; notify->query_id = 0; notify->is_waiting = 0; notify->handler.fd = -1; notify->timeout.tv_sec = 0; notify->timeout.tv_nsec = 0; notify->handler.timeout = NULL; notify->handler.user_data = notify; notify->handler.event_types = NETIO_EVENT_READ|NETIO_EVENT_TIMEOUT; notify->handler.event_handler = notify_handle_zone; return notify; }
static void kill_server_callback (server * serv) { serv->cleanup (serv); serv_list = g_slist_remove (serv_list, serv); dcc_notify_kill (serv); serv->flush_queue (serv); free_away_messages (serv); free (serv->nick_modes); free (serv->nick_prefixes); free (serv->chanmodes); free (serv->chantypes); if (serv->bad_nick_prefixes) free (serv->bad_nick_prefixes); if (serv->last_away_reason) free (serv->last_away_reason); if (serv->eom_cmd) free (serv->eom_cmd); if (serv->username) free (serv->username); if (serv->realname) free (serv->realname); if (serv->networkname) free (serv->networkname); if (serv->encoding) free (serv->encoding); fe_server_callback (serv); free (serv); notify_cleanup (); }