/* Initialize nodes array from component message */
static inline gcs_node_t*
group_nodes_init (const gcs_group_t* group, const gcs_comp_msg_t* comp)
{
    const long my_idx     = gcs_comp_msg_self (comp);
    const long nodes_num  = gcs_comp_msg_num  (comp);
    gcs_node_t* ret = GU_CALLOC (nodes_num, gcs_node_t);
    long i;

    if (ret) {
        for (i = 0; i < nodes_num; i++) {
            const gcs_comp_memb_t* memb = gcs_comp_msg_member(comp, i);
            assert(NULL != memb);

            if (my_idx != i) {
                gcs_node_init (&ret[i], group->cache, memb->id,
                               NULL, NULL, -1, -1, -1, memb->segment);
            }
            else { // this node
                gcs_node_init (&ret[i], group->cache, memb->id,
                               group->my_name, group->my_address,
                               group->gcs_proto_ver, group->repl_proto_ver,
                               group->appl_proto_ver, memb->segment);
            }
        }
    }
    else {
        gu_error ("Could not allocate %ld x %z bytes", nodes_num,
                  sizeof(gcs_node_t));
    }
    return ret;
}
예제 #2
0
파일: gu_to.c 프로젝트: latinovic/galera
gu_to_t *gu_to_create (int len, gu_seqno_t seqno)
{
    gu_to_t *ret;

    assert (seqno >= 0);

    if (len <= 0) {
        gu_error ("Negative length parameter: %d", len);
        return NULL;
    }

    ret = GU_CALLOC (1, gu_to_t);
    
    if (ret) {

        /* Make queue length a power of 2 */
        ret->qlen = 1;
        while (ret->qlen < len) {
            // unsigned, can be bigger than any integer
            ret->qlen = ret->qlen << 1;
        }
        ret->qmask = ret->qlen - 1;
        ret->seqno = seqno;

        ret->queue = GU_CALLOC (ret->qlen, to_waiter_t);

        if (ret->queue) {
            ssize_t i;
            for (i = 0; i < ret->qlen; i++) {
                to_waiter_t *w = ret->queue + i;
#ifdef TO_USE_SIGNAL
                gu_cond_init (&w->cond, NULL);
#else
                pthread_mutex_init (&w->mtx, NULL);
#endif
                w->state       = RELEASED;
            }
            gu_mutex_init (&ret->lock, NULL);
        
            return ret;
        }
        gu_free (ret);
    }

    return NULL;
}
int
gcs_group_init (gcs_group_t* group, gcache_t* const cache,
                const char* node_name, const char* inc_addr,
                gcs_proto_t const gcs_proto_ver, int const repl_proto_ver,
                int const appl_proto_ver)
{
    // here we also create default node instance.
    group->cache        = cache;
    group->act_id       = GCS_SEQNO_ILL;
    group->conf_id      = GCS_SEQNO_ILL;
    group->state_uuid   = GU_UUID_NIL;
    group->group_uuid   = GU_UUID_NIL;
    group->num          = 1; // this must be removed (#474)
    group->my_idx       = 0; // this must be -1 (#474)
    group->my_name      = strdup(node_name ? node_name : NODE_NO_NAME);
    group->my_address   = strdup(inc_addr  ? inc_addr  : NODE_NO_ADDR);
    group->state        = GCS_GROUP_NON_PRIMARY;
    group->last_applied = GCS_SEQNO_ILL; // mark for recalculation
    group->last_node    = -1;
    group->frag_reset   = true; // just in case
    group->nodes        = GU_CALLOC(group->num, gcs_node_t); // this must be removed (#474)

    if (!group->nodes) return -ENOMEM; // this should be removed (#474)

    /// this should be removed (#474)
    gcs_node_init (&group->nodes[group->my_idx], group->cache, NODE_NO_ID,
                   group->my_name, group->my_address, gcs_proto_ver,
                   repl_proto_ver, appl_proto_ver, 0);

    group->prim_uuid  = GU_UUID_NIL;
    group->prim_seqno = GCS_SEQNO_ILL;
    group->prim_num   = 0;
    group->prim_state = GCS_NODE_STATE_NON_PRIM;

    *(gcs_proto_t*)&group->gcs_proto_ver = gcs_proto_ver;
    *(int*)&group->repl_proto_ver = repl_proto_ver;
    *(int*)&group->appl_proto_ver = appl_proto_ver;

    group->quorum = GCS_QUORUM_NON_PRIMARY;

    group->last_applied_proto_ver = -1;

    return 0;
}
/* Creates FIFO object. Since it practically consists of array of (void*),
 * the length can be chosen arbitrarily high - to minimize the risk
 * of overflow situation.
 */
gcs_fifo_lite_t* gcs_fifo_lite_create (size_t length, size_t item_size)
{
    gcs_fifo_lite_t* ret = NULL;
    uint64_t l = 1;

    /* check limits */
    if (length < 1 || item_size < 1)
        return NULL;

    /* Find real length. It must be power of 2*/
    while (l < length) l = l << 1;

    if (l * item_size > (uint64_t)GU_LONG_MAX) {
        gu_error ("Resulting FIFO size %lld exceeds signed limit: %lld",
                  (long long)(l*item_size), (long long)GU_LONG_MAX);
        return NULL;
    }

    ret = GU_CALLOC (1, gcs_fifo_lite_t);

    if (ret) {
        ret->length    = l;
        ret->item_size = item_size;
	ret->mask      = ret->length - 1;
        ret->closed    = true;
	ret->queue     = gu_malloc (ret->length * item_size);

	if (ret->queue) {
	    gu_mutex_init (&ret->lock,     NULL);
	    gu_cond_init  (&ret->put_cond, NULL);
	    gu_cond_init  (&ret->get_cond, NULL);
	    /* everything else must be initialized to 0 by calloc */
	}
	else {
	    gu_free (ret);
	    ret = NULL;
	}
    }

    return ret;
}