/* * File: NextViewBuffer.cc * Author: stubbfel * * Created on 14. August 2013, 21:24 */ #include "NextViewBuffer.h" #include "Dispatcher.h" #include "mt/msg/MulticastMessage.h" #include "ms/events/ViewChangeEvent.h" #define DEBUG(msg) if(getLocalState()== DISJOINED){ MOV_DEBUG <<"NVB@TA_"<(this); dispatcher.subscribe(this); lockedSendMsgSemaphore = false; sendingMessageQueue.clear(); receivingMessageQueue.clear(); } /** * @brief Method reset semaphorecount and clear queues */ void NextViewBuffer::finalise() { dispatcher.unsubscribeAll(this); lockedSendMsgSemaphore = false; sendingMessageQueue.clear(); receivingMessageQueue.clear(); } /** * @brief Method stores received MulticastMessage * @param msg */ void NextViewBuffer::pushReceiveMsg(const MulticastMessage & msg) { MulticastMessage * aMsg = msg.dup(); if (!receivingMessageQueue.contains(aMsg)) { DEBUG("add message (MREF=" << msg.getMessageReference() << ") from view " << aMsg->getViewID() << " to receivingMessageQueue"); // insert the clone of the message receivingMessageQueue.add(aMsg); } } /** * @brief Method start handleMessage() for stored received Message, * which has a certain viewID * @param viewID of the messages */ void NextViewBuffer::popReceiveMsgs(ViewID viewID) { MulticastMessageQueue removeMsg; for (size_t i = 0; i < receivingMessageQueue.size(); i++) { MulticastMessage * tmpMsg = receivingMessageQueue.get(i); // search messages with less equal viewid if (tmpMsg->getViewID() <= viewID) { DEBUG("replay message (MREF=" << tmpMsg->getMessageReference() << ", view " << tmpMsg->getViewID()<<") from receivingMessageQueue"); // handle Message tmpMsg->handleReceive(dispatcher); removeMsg.add(tmpMsg); } } receivingMessageQueue.remove(removeMsg); removeMsg.clear(); } /** * @brief Method stores MulticastMessage, which had to been sent * @param msg */ void NextViewBuffer::pushSendMsg(MulticastMessage* msg) { if (!sendingMessageQueue.contains(msg)) { DEBUG("add message (MREF=" << msg->getMessageReference() << ") from view " << msg->getViewID() << " to sendingMessageQueue"); // insert a dup of the Message sendingMessageQueue.add(msg->dup()); } } /** * @brief Method start sendMessage() for stored "sent" Message, */ void NextViewBuffer::popSendMsgs() { // sending Message if Semaphore is inactived while (sendingMessageQueue.size() > 0 && !isLockedSendMsgSemaphoreActivated()) { MulticastMessage * tmpMsg = sendingMessageQueue.first(); DEBUG("replay message (MREF=" << tmpMsg->getMessageReference() << ", view " << tmpMsg->getViewID()<<") from sendingMessageQueue"); // send the Message dispatcher.sendMessage(*(tmpMsg->dup())); sendingMessageQueue.pop(); } } /** * @brief Method check if the LockedSendMsgSemaphore activated * @return true, if the LockedSendMsgSemaphore is activated, othewise false */ bool NextViewBuffer::isLockedSendMsgSemaphoreActivated() { return lockedSendMsgSemaphore; } /** * @brief Method set the LockedSendMsgSemaphore */ void NextViewBuffer::setLockedSendMsgSemaphore() { if (!lockedSendMsgSemaphore) { lockedSendMsgSemaphore = true; DEBUG("SendLock is active"); } } /** * @brief Method release the LockedSendMsgSemaphore */ void NextViewBuffer::unsetLockedSendMsgSemaphore() { if (lockedSendMsgSemaphore) { lockedSendMsgSemaphore = false; DEBUG("SendLock is deactive"); } } /** * @brief Method check if the messagetype is an type, which need a lock of SendMsgSemaphore * @param MoversightMessageType : msgType * @return result - true if its an lockabletype, otherwise false */ bool NextViewBuffer::isViewChangeAbleMessageType(const MoversightMessageType & msgType) { bool result = true; switch (msgType) { case JA: case LA: case RSA: result = true; break; default: result = false; break; } return result; } /** * @brief Handles the ViewChangeEvent event by reading stored messages * @param e The event to handle */ void NextViewBuffer::handleEvent(const ViewChangeEvent& e) { popReceiveMsgs(e.getViewID()); } /** * @brief Handles the JoinGroupDone event by updating the master ID * threshold map and pop the first received message of the next view buffer. * @param The event to handle. */ void NextViewBuffer::handleEvent(const JoinGroupDoneEvent & /* e */) { popReceiveMsgs(getViewID()); } /** * @brief Method set the LockedSendMsgSemaphore and set the localSubState to FLUSCHING */ void NextViewBuffer::setLockedSendMsgSemaphoreAndStartFlush() { if (!isLockedSendMsgSemaphoreActivated()) { lastState = getLocalSubState(); setLocalSubState(FLUSHING); setLockedSendMsgSemaphore(); } } /** * @brief Method release the LockedSendMsgSemaphore, stop flusching and read saved messages */ void NextViewBuffer::unsetLockedSendMsgSemaphoreAndStopFlush() { if (isLockedSendMsgSemaphoreActivated()) { unsetLockedSendMsgSemaphore(); setLocalSubState(lastState); lastState = NO_SUB_STATE; popSendMsgs(); } } } }