示例#1
0
文件: gu_to.c 项目: latinovic/galera
long gu_to_destroy (gu_to_t** to)
{
    gu_to_t *t = *to;
    long      ret;
    ssize_t    i;

    gu_mutex_lock (&t->lock);
    if (t->used) {
        gu_mutex_unlock (&t->lock);
        return -EBUSY;
    }
    
    for (i = 0; i < t->qlen; i++) {
        to_waiter_t *w = t->queue + i;
#ifdef TO_USE_SIGNAL
        if (gu_cond_destroy (&w->cond)) {
            // @todo: what if someone is waiting?
            gu_warn ("Failed to destroy condition %d. Should not happen", i);
        }
#else
        if (pthread_mutex_destroy (&w->mtx)) {
            // @todo: what if someone is waiting?
            gu_warn ("Failed to destroy mutex %d. Should not happen", i);
        }
#endif
    }    
    t->qlen = 0;
    
    gu_mutex_unlock (&t->lock);
    /* What else can be done here? */
    ret = gu_mutex_destroy (&t->lock);
    if (ret) return -ret; // application can retry

    gu_free (t->queue);
    gu_free (t);
    *to = NULL;
    return 0;
}
void
gcs_sm_destroy (gcs_sm_t* sm)
{
    gu_mutex_destroy(&sm->lock);
    gu_free (sm);
}
long gcs_fifo_lite_destroy (gcs_fifo_lite_t* f)
{
    if (f) {
	if (gu_mutex_lock (&f->lock)) { abort(); }

	if (f->destroyed) {
	    gu_mutex_unlock (&f->lock);
	    return -EALREADY;
	}

        f->closed    = true;
	f->destroyed = true;

	/* get rid of "put" threads waiting for lock or signal */
	while (pthread_cond_destroy (&f->put_cond)) {
            if (f->put_wait <= 0) {
                gu_fatal ("Can't destroy condition while nobody's waiting");
                abort();
            }
            f->put_wait = 0;
            gu_cond_broadcast (&f->put_cond);
	}

	while (f->used) {
	    /* there are some items in FIFO - and that means
	     * no gcs_fifo_lite_safe_get() is waiting on condition */
	    gu_mutex_unlock (&f->lock);
	    /* let them get remaining items from FIFO,
	     * we don't know how to deallocate them ourselves.
	     * unfortunately this may take some time */
	    usleep (10000); /* sleep a bit to avoid busy loop */
	    gu_mutex_lock (&f->lock);
	}
	f->length = 0;

	/* now all we have - "get" threads waiting for lock or signal */
	while (pthread_cond_destroy (&f->get_cond)) {
            if (f->get_wait <= 0) {
                gu_fatal ("Can't destroy condition while nobody's waiting");
                abort();
            }
            f->get_wait = 0;
            gu_cond_broadcast (&f->get_cond);
	}

	/* at this point there are only functions waiting for lock */
	gu_mutex_unlock (&f->lock);
	while (gu_mutex_destroy (&f->lock)) {
	    /* this should be fast provided safe get and safe put are
	     * wtitten correctly. They should immediately freak out. */
	    gu_mutex_lock   (&f->lock);
	    gu_mutex_unlock (&f->lock);
	}

	/* now nobody's waiting for anything */
	gu_free (f->queue);
	gu_free (f);
	return 0;
    }
    return -EINVAL;
}