Files
scandocs/uni/masterarbeit/source/moversight/mrs/sync/NextViewBuffer.cc
2014-06-30 13:58:10 +02:00

244 lines
6.4 KiB
C++

/*
* 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_"<<getLocalAddress()<<" "<<msg<<endl; } else{ MOV_DEBUG <<"NVB@"<<getLocalID() <<" "<<msg<<endl;}
namespace ubeeme {
namespace moversight {
/**
* @brief Constructor
* @param dis : Dispatcher
*/
NextViewBuffer::NextViewBuffer(Dispatcher & dis) : MoversightService(dis, "MaintanceRoleService"),lastState(NO_SUB_STATE) {
}
/**
* @brief DeConstructor
*/
NextViewBuffer::~NextViewBuffer() {
}
/**
* @brief Copy Constructor
*/
NextViewBuffer::NextViewBuffer(const NextViewBuffer& other) : MoversightService(other) {
operator=(other);
}
/**
* @brief assignment operator
*/
NextViewBuffer & NextViewBuffer::operator=(const NextViewBuffer& rhs) {
if (this == &rhs) {
// handle self assignment
return *this;
}
lockedSendMsgSemaphore = rhs.lockedSendMsgSemaphore;
receivingMessageQueue = rhs.receivingMessageQueue;
sendingMessageQueue = rhs.sendingMessageQueue;
lastState = rhs.lastState;
return *this;
}
/**
* @brief Method set semaphorestartcount and clear queues
*/
void
NextViewBuffer::initialise() {
dispatcher.subscribe<ViewChangeEvent>(this);
dispatcher.subscribe<JoinGroupDoneEvent>(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();
}
}
}
}