예제 #1
0
파일: proposer.c 프로젝트: Gustfh/libpaxos2
/*-------------------------------------------------------------------------*/
static void
pro_clear_instance_info(p_inst_info * ii) {
    ii->iid = 0;
    ii->status = empty;
    ii->my_ballot = 0;
    ii->p1_value_ballot = 0;
    ii->promises_bitvector = 0;
    ii->promises_count = 0;
    if(ii->p1_value != NULL) {
        PAX_FREE(ii->p1_value);
    }
    ii->p1_value = NULL;
    if(ii->p2_value != NULL) {
        PAX_FREE(ii->p2_value);
    }
    ii->p2_value = NULL;
}
예제 #2
0
파일: proposer.c 프로젝트: Gustfh/libpaxos2
static void
pro_save_prepare_ack(p_inst_info * ii, prepare_ack * pa, short int acceptor_id) {
    
    //Ack from already received!
    if(ii->promises_bitvector & (1<acceptor_id)) {
        LOG(DBG, ("Dropping duplicate promise from:%d, iid:%ld, \n", acceptor_id, ii->iid));
        return;
    }
    
    // promise is new
    ii->promises_bitvector &= (1<acceptor_id);
    ii->promises_count++;
    LOG(DBG, ("Received valid promise from:%d, iid:%ld, \n", acceptor_id, ii->iid));
    
    //Promise contains no value
    if(pa->value_size == 0) {
        LOG(DBG, (" No value in promise\n"));
        return;
    }

    //Promise contains a value
    
    //Our value has same or greater ballot
    if(ii->p1_value_ballot >= pa->value_ballot) {
        //Keep the current value
        LOG(DBG, (" Included value is ignored (cause:value_ballot)\n"));
        return;
    }
    
    //Ballot is greater but the value is actually the same
    if ((ii->p1_value != NULL) &&
        (ii->p1_value->value_size == pa->value_size) && 
        (memcmp(ii->p1_value->value, pa->value, pa->value_size) == 0)) {
        //Just update the value ballot
        LOG(DBG, (" Included value is the same with higher value_ballot\n"));
        ii->p1_value_ballot = pa->value_ballot;
        return;
    }
    
    //Value should replace the one we have (if any)
    //Free the old one
    if (ii->p1_value != NULL) {
        PAX_FREE(ii->p1_value);
    }
    
    //Save the received value 
    ii->p1_value = vh_wrap_value(pa->value, pa->value_size);
    ii->p1_value_ballot = pa->value_ballot;
    LOG(DBG, (" Value in promise saved\n"));
}
예제 #3
0
static void
leader_check_p1_pending() {
    iid_t iid_iterator;
    p_inst_info * ii;

    //Create an empty prepare batch in send buffer
    sendbuf_clear(to_acceptors, prepare_reqs, this_proposer_id);
    LOG(DBG, ("Checking pending phase 1 from %lu to %lu\n",
        current_iid, p1_info.highest_open));
    
    //Get current time for checking expired    
    struct timeval time_now;
    gettimeofday(&time_now, NULL);
    
    for(iid_iterator = current_iid; 
        iid_iterator <= p1_info.highest_open; iid_iterator++) {

        //Get instance from state array
        ii = GET_PRO_INSTANCE(iid_iterator);
        assert(ii->iid == iid_iterator);
        
        //Still pending -> it's expired
        if(ii->status == p1_pending && leader_is_expired(&ii->timeout, &time_now)) {
            LOG(DBG, ("Phase 1 of instance %ld expired!\n", ii->iid));

            //Reset fields used for previous phase 1
            ii->promises_bitvector = 0;
            ii->promises_count = 0;
            ii->p1_value_ballot = 0;
            if(ii->p1_value != NULL) {
                PAX_FREE(ii->p1_value);
            }
            ii->p1_value = NULL;
            
            //Ballot is incremented
            ii->my_ballot = NEXT_BALLOT(ii->my_ballot);


            //Send prepare to acceptors
            sendbuf_add_prepare_req(to_acceptors, ii->iid, ii->my_ballot);        
            leader_set_expiration(ii, P1_TIMEOUT_INTERVAL);
            
            COUNT_EVENT(p1_timeout);
        }
    }    

    //Send if something is still there
    sendbuf_flush(to_acceptors);
}
예제 #4
0
void 
vh_shutdown() {
    //Delete event
    event_del(&leader_msg_event);

    //Close socket and free receiver
    udp_receiver_destroy(for_leader);
    
    //All values in pending could not be delivered yet.
    // Notify the respective clients
    vh_value_wrapper * vw;
    while ((vw = vh_get_next_pending()) != NULL) {
        vh_notify_client(-1, vw);
        PAX_FREE(vw);        
    }
}
예제 #5
0
static void
leader_execute_p2(p_inst_info * ii) {
    
    if(ii->p1_value == NULL && ii->p2_value == NULL) {
        //Happens when p1 completes without value        
        //Assign a p2_value and execute
        ii->p2_value = vh_get_next_pending();
        assert(ii->p2_value != NULL);
        
    } else if (ii->p1_value != NULL) {
        //Only p1 value is present, MUST execute p2 with it
        //Save it as p2 value and execute
        ii->p2_value = ii->p1_value;
        ii->p1_value = NULL;
        ii->p1_value_ballot = 0;
        
    } else if (ii->p2_value != NULL) {
        // Only p2 valye is present
        //Do phase 2 with it
        
    } else {
        // There are both p1 and p2 value
        //Compare them
        if(vh_value_compare(ii->p1_value, ii->p2_value) == 0) {
            // Same value, just delete p1_value
            PAX_FREE(ii->p1_value);
            ii->p1_value = NULL;
            ii->p1_value_ballot = 0;
        } else {
            // Different values
            // p2_value is pushed back to pending list
            vh_push_back_value(ii->p2_value);
            // Must execute p2 with p1 value
            ii->p2_value = ii->p1_value;
            ii->p1_value = NULL;
            ii->p1_value_ballot = 0;            
        }
    }
    //Change instance status
    ii->status = p2_pending;

    //Send the accept request
    sendbuf_add_accept_req(to_acceptors, ii->iid, ii->my_ballot, ii->p2_value->value, ii->p2_value->value_size);
    
    //Set the deadline for this instance
    leader_set_expiration(ii, P2_TIMEOUT_INTERVAL);
}