244 lines
6.4 KiB
C++
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();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|