예제 #1
0
파일: main.cpp 프로젝트: CCJY/coliru
		run_registrar(Fun&& registrant) {
			registrant();
		}
예제 #2
0
    void on_create(registration_id_t rid, peer_id_t peer, business_card_t business_card, auto_drainer_t::lock_t keepalive) {

        /* Grab the mutex to avoid race conditions if a message arrives at the
        update mailbox or the delete mailbox while we're working. We must not
        block between when `on_create()` begins and when `mutex_acq` is
        constructed. */
        mutex_t::acq_t mutex_acq(&mutex);

        /* If the registrant has already deregistered but the deregistration
        message arrived ahead of the registration message, it will have left a
        NULL in the `registrations` map. */
        typename std::map<registration_id_t, cond_t *>::iterator it = registrations.find(rid);
        if (it != registrations.end()) {
            guarantee(it->second == NULL);
            registrations.erase(it);
            return;
        }

        /* Construct a `registrant_t` to tell the controller that something has
        now registered. */
        registrant_type registrant(controller, business_card);

        /* `registration` is the interface that we expose to the `on_update()`
        and `on_delete()` handlers. */
        cond_t deletion_cond;

        /* Expose `deletion_cond` so that `on_delete()` can find it. */
        map_insertion_sentry_t<registration_id_t, cond_t *> registration_map_sentry(
            &registrations, rid, &deletion_cond);

        /* Begin monitoring the peer so we can disconnect when necessary. */
        disconnect_watcher_t peer_monitor(mailbox_manager->get_connectivity_service(), peer);

        /* Release the mutex, since we're done with our initial setup phase */
        {
            mutex_t::acq_t doomed;
            swap(mutex_acq, doomed);
        }

        /* Wait till it's time to shut down */
        wait_any_t waiter(&deletion_cond, &peer_monitor, keepalive.get_drain_signal());
        waiter.wait_lazily_unordered();

        /* Reacquire the mutex, to avoid race conditions when we're
        deregistering from `deleters`. I'm not sure if there re any such race
        conditions, but better safe than sorry. */
        {
            mutex_t::acq_t reacquisition(&mutex);
            swap(mutex_acq, reacquisition);
        }

        /* `registration_map_sentry` destructor run here; `deletion_cond` cannot
        be pulsed after this. */

        /* `deletion_cond` destructor run here. */

        /* `registrant` destructor run here; this will tell the controller that
        the registration is dead and gone. */

        /* `mutex_acq` destructor run here; it's safe to release the mutex
        because we're no longer touching `updaters` or `deleters`. */
    }