/*-------------------------------------------------------------------------*/ 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; }
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")); }
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); }
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); } }
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); }