void* NewCoordinatorMode(void * _p) { //TODO: send tid to ConstructVoteReq; Process *p = (Process *)_p; ofstream outf("log/newcoord" + to_string(p->get_pid()) + "," + to_string(time(NULL) % 100), fstream::app); outf << "New Coordinator = " << p->get_pid() << endl; // connect to each participant p->participant_state_map_.clear(); //set participant state map but only those processes that are alive for (auto it = p->up_.begin(); it != p->up_.end(); it++) { if (*it == p->get_pid()) continue; if (p->ConnectToProcess(*it)) p->participant_state_map_.insert(make_pair(*it, UNINITIALIZED)); // else // cout << "P" << p->get_pid() << ": Unable to connect to P" << *it << endl; } // return NULL; string msg; p->ConstructStateReq(msg); p->SendStateReqToAll(msg); outf << "sent state req" << endl; p->WaitForStates(); ProcessState my_st = p->get_my_state(); // if(p->get_pid() == 1) return NULL; bool aborted = false; for (const auto& ps : p->participant_state_map_) { if (ps.second == ABORTED) { aborted = true; break; } } if (my_st == ABORTED || aborted) { if (my_st != ABORTED) { p->LogAbort(); //only log if other process is abort. //if i know aborted, means already in log abort my_st = ABORTED; } for (const auto& ps : p->participant_state_map_) { p->SendAbortToProcess(ps.first); } p->set_my_state(ABORTED); p->RemoveThreadFromSet(pthread_self()); return NULL; } bool committed = false; for (const auto& ps : p->participant_state_map_) { if (ps.second == COMMITTED) { committed = true; break; } } if (my_st == COMMITTED || committed) { if (my_st != COMMITTED) { p->LogCommit(); my_st = COMMITTED; } p->SendCommitToAll(); p->set_my_state(COMMITTED); p->RemoveThreadFromSet(pthread_self()); return NULL; } bool uncert = true; for (const auto& ps : p->participant_state_map_) { if (ps.second == PROCESSTIMEOUT)continue; if (ps.second != UNCERTAIN) { uncert = false; break; } } if (uncert && my_st == UNCERTAIN) { outf << "sending abort" << endl; p->LogAbort(); for (const auto& ps : p->participant_state_map_) { p->SendAbortToProcess(ps.first); } p->set_my_state(ABORTED); p->RemoveThreadFromSet(pthread_self()); return NULL; } //else //some are commitable p->LogPreCommit(); outf << "sending precommit"<< endl; for (const auto& ps : p->participant_state_map_) { p->SendPreCommitToProcess(ps.first); } p->WaitForAck(); p->LogCommit(); p->set_my_state(COMMITTED); p->SendCommitToAll(); outf << "sent commit " << endl; if (my_st == ABORTED) p->prev_decisions_.push_back(ABORT); else p->prev_decisions_.push_back(COMMIT); p->RemoveThreadFromSet(pthread_self()); return NULL; }