Commit ec09c8f5 authored by legoc's avatar legoc
Browse files

Replaced EventStreamSocket of This with an EventListener.

Corrected bug in EventThread: now events are cloned.
parent 17aa1e49
......@@ -44,7 +44,6 @@ libcameo_la_SOURCES = \
cameo/impl/ServicesImpl.cpp \
cameo/Server.cpp \
cameo/impl/HandlerImpl.cpp \
cameo/impl/ApplicationImpl.cpp \
cameo/Application.cpp \
cameo/impl/SocketImpl.h \
cameo/impl/WaitingImpl.h \
......
......@@ -22,7 +22,7 @@
#include <stdexcept>
#include <vector>
#include "EventStreamSocket.h"
#include "impl/ApplicationImpl.h"
#include "impl/ServicesImpl.h"
#include "impl/PublisherImpl.h"
#include "impl/RequesterImpl.h"
#include "impl/RequestImpl.h"
......@@ -31,6 +31,7 @@
#include "impl/SubscriberImpl.h"
#include "impl/WaitingImpl.h"
#include "impl/WaitingImplSet.h"
#include "impl/HandlerImpl.h"
#include "PortEvent.h"
#include "ProtoType.h"
#include "PublisherEvent.h"
......@@ -119,7 +120,7 @@ This::This() :
void This::initApplication(int argc, char *argv[]) {
m_impl = new ApplicationImpl();
m_impl = new ServicesImpl();
Services::setImpl(m_impl);
if (argc == 0) {
......@@ -193,6 +194,10 @@ void This::initApplication(int argc, char *argv[]) {
}
m_waitingSet = unique_ptr<WaitingImplSet>(new WaitingImplSet());
// Init listener.
setName(m_name);
m_server->registerEventListener(this);
}
This::~This() {
......@@ -385,10 +390,6 @@ bool This::removePort(const std::string& name) const {
State This::waitForStop() {
// open the event stream
unique_ptr<EventStreamSocket> socket = openEventStream();
m_impl->setEventSocket(socket);
// test if stop was requested elsewhere
State state = getState(m_id);
if (state == STOPPING
......@@ -398,7 +399,7 @@ State This::waitForStop() {
while (true) {
// waits for a new incoming status
unique_ptr<Event> event = m_impl->m_eventSocket->receive();
unique_ptr<Event> event = popEvent();
// The socket is canceled.
if (event.get() == nullptr) {
......@@ -440,8 +441,18 @@ std::unique_ptr<Instance> This::connectToStarter() {
return unique_ptr<Instance>(nullptr);
}
void This::stoppingFunction(StopFunctionType stop) {
application::State state = waitForStop();
// Only stop in case of STOPPING.
if (state == application::STOPPING) {
stop();
}
}
void This::handleStopImpl(StopFunctionType function) {
m_impl->handleStop(&m_instance, function);
m_stopHandler = unique_ptr<HandlerImpl>(new HandlerImpl(bind(&This::stoppingFunction, this, function)));
}
///////////////////////////////////////////////////////////////////////////////
......
......@@ -44,7 +44,6 @@ enum Option {
class Server;
class EventStreamSocket;
class OutputStreamSocket;
class ApplicationImpl;
class PublisherImpl;
class SubscriberImpl;
class RequestImpl;
......@@ -54,6 +53,7 @@ class WaitingImpl;
class SocketWaitingImpl;
class GenericWaitingImpl;
class WaitingImplSet;
class HandlerImpl;
namespace application {
......@@ -81,7 +81,7 @@ const State STOPPED = 128;
const State KILLED = 256;
class This : private Services {
class This : private Services, private EventListener {
friend class cameo::application::Publisher;
friend class cameo::application::Responder;
......@@ -90,7 +90,6 @@ class This : private Services {
friend class cameo::RequestImpl;
friend class cameo::ResponderImpl;
friend class cameo::RequesterImpl;
friend class cameo::ApplicationImpl;
friend class cameo::SocketWaitingImpl;
friend class cameo::GenericWaitingImpl;
friend class cameo::Server;
......@@ -161,9 +160,11 @@ private:
bool destroyPublisher(const std::string& name) const;
bool removePort(const std::string& name) const;
State waitForStop();
void stoppingFunction(StopFunctionType stop);
void handleStopImpl(StopFunctionType function);
ApplicationImpl * m_impl;
ServicesImpl * m_impl;
std::string m_name;
int m_id;
bool m_managed;
......@@ -176,13 +177,14 @@ private:
std::unique_ptr<Server> m_starterServer;
std::unique_ptr<WaitingImplSet> m_waitingSet;
std::unique_ptr<HandlerImpl> m_stopHandler;
static This m_instance;
static const std::string RUNNING_STATE;
};
class Instance : public EventListener {
class Instance : private EventListener {
friend class cameo::Server;
friend class cameo::application::Subscriber;
......
......@@ -24,6 +24,14 @@ CancelEvent::CancelEvent(int id, const std::string& name) :
Event(id, name) {
}
CancelEvent::CancelEvent(const CancelEvent& event) :
Event(event) {
}
CancelEvent* CancelEvent::clone() {
return new CancelEvent(*this);
}
std::ostream& operator<<(std::ostream& os, const cameo::CancelEvent& event) {
os << "name=" << event.m_name
<< "\nid=" << event.m_id;
......
......@@ -28,6 +28,9 @@ class CancelEvent : public Event {
public:
CancelEvent(int id, const std::string& name);
CancelEvent(const CancelEvent& event);
virtual CancelEvent* clone();
};
std::ostream& operator<<(std::ostream&, const CancelEvent&);
......
......@@ -25,6 +25,11 @@ Event::Event(int id, const std::string& name) :
m_name(name) {
}
Event::Event(const Event& event) :
m_id(event.m_id),
m_name(event.m_name) {
}
Event::~Event() {
}
......
......@@ -25,8 +25,11 @@ class Event {
public:
Event(int id, const std::string& name);
Event(const Event& event);
virtual ~Event();
virtual Event* clone() = 0;
int getId() const;
const std::string& getName() const;
......
......@@ -54,7 +54,12 @@ void EventThread::start() {
// If the application name is null, all the status are pushed, otherwise, filter on the name.
if (listener->getName() == ""
|| listener->getName() == event->getName()) {
listener->pushEvent(event);
// Clone the event is necessary because the event is passed to different listeners working in different threads.
unique_ptr<Event> clonedEvent(event->clone());
// Push the cloned event.
listener->pushEvent(clonedEvent);
}
}
}
......
......@@ -25,6 +25,14 @@ PortEvent::PortEvent(int id, const std::string& name, const std::string& portNam
m_portName(portName) {
}
PortEvent::PortEvent(const PortEvent& event) :
Event(event), m_portName(event.m_portName) {
}
PortEvent* PortEvent::clone() {
return new PortEvent(*this);
}
const std::string& PortEvent::getPortName() const {
return m_portName;
}
......
......@@ -28,6 +28,9 @@ class PortEvent : public Event {
public:
PortEvent(int id, const std::string& name, const std::string& portName);
PortEvent(const PortEvent& event);
virtual PortEvent* clone();
const std::string& getPortName() const;
......
......@@ -25,6 +25,14 @@ PublisherEvent::PublisherEvent(int id, const std::string& name, const std::strin
m_publisherName(publisherName) {
}
PublisherEvent::PublisherEvent(const PublisherEvent& event) :
Event(event), m_publisherName(event.m_publisherName) {
}
PublisherEvent* PublisherEvent::clone() {
return new PublisherEvent(*this);
}
const std::string& PublisherEvent::getPublisherName() const {
return m_publisherName;
}
......
......@@ -28,6 +28,9 @@ class PublisherEvent : public Event {
public:
PublisherEvent(int id, const std::string& name, const std::string& publisherName);
PublisherEvent(const PublisherEvent& event);
virtual PublisherEvent* clone();
const std::string& getPublisherName() const;
......
......@@ -25,6 +25,14 @@ ResultEvent::ResultEvent(int id, const std::string& name, const std::string& dat
m_data(data) {
}
ResultEvent::ResultEvent(const ResultEvent& event) :
Event(event), m_data(event.m_data) {
}
ResultEvent* ResultEvent::clone() {
return new ResultEvent(*this);
}
const std::string& ResultEvent::getData() const {
return m_data;
}
......
......@@ -29,6 +29,9 @@ class ResultEvent : public Event {
public:
ResultEvent(int id, const std::string& name, const std::string& data);
ResultEvent(const ResultEvent& event);
virtual ResultEvent* clone();
const std::string& getData() const;
......
......@@ -26,6 +26,14 @@ StatusEvent::StatusEvent(int id, const std::string& name, application::State sta
m_pastStates(pastStates) {
}
StatusEvent::StatusEvent(const StatusEvent& event) :
Event(event), m_state(event.m_state), m_pastStates(event.m_pastStates) {
}
StatusEvent* StatusEvent::clone() {
return new StatusEvent(*this);
}
application::State StatusEvent::getState() const {
return m_state;
}
......
......@@ -29,6 +29,9 @@ class StatusEvent : public Event {
public:
StatusEvent(int id, const std::string& name, application::State state, application::State pastStates);
StatusEvent(const StatusEvent& event);
virtual StatusEvent* clone();
application::State getState() const;
application::State getPastStates() const;
......
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "ApplicationImpl.h"
#include <memory>
#include <iostream>
#include "../EventStreamSocket.h"
#include "../Application.h"
using namespace std;
namespace cameo {
ApplicationImpl::ApplicationImpl() :
ServicesImpl() {
}
ApplicationImpl::~ApplicationImpl() {
// Cancel the event socket in case it was started with a stop handler.
if (m_eventSocket.get() != nullptr) {
m_eventSocket->cancel();
}
}
void ApplicationImpl::setEventSocket(std::unique_ptr<EventStreamSocket>& eventSocket) {
m_eventSocket = std::move(eventSocket);
}
void ApplicationImpl::handleStop(application::This * application, HandlerImpl::FunctionType stop) {
m_stopHandler = unique_ptr<HandlerImpl>(new HandlerImpl(bind(&ApplicationImpl::stoppingFunction, application, stop)));
}
void ApplicationImpl::stoppingFunction(application::This * application, HandlerImpl::FunctionType stop) {
application::State state = application->waitForStop();
// Only stop in case of STOPPING.
if (state == application::STOPPING) {
stop();
}
}
}
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAMEO_APPLICATIONIMPL_H_
#define CAMEO_APPLICATIONIMPL_H_
#include "HandlerImpl.h"
#include "ServicesImpl.h"
namespace cameo {
class EventStreamSocket;
namespace application {
class This;
}
class ApplicationImpl : public ServicesImpl {
public:
ApplicationImpl();
virtual ~ApplicationImpl();
void setEventSocket(std::unique_ptr<EventStreamSocket>& eventSocket);
void handleStop(application::This * application, HandlerImpl::FunctionType stop);
static void stoppingFunction(application::This * application, HandlerImpl::FunctionType stop);
std::unique_ptr<EventStreamSocket> m_eventSocket;
std::unique_ptr<HandlerImpl> m_stopHandler;
};
}
#endif
......@@ -17,7 +17,7 @@
#include "PublisherImpl.h"
#include "../Application.h"
#include "../Serializer.h"
#include "ApplicationImpl.h"
#include "ServicesImpl.h"
#include <sstream>
using namespace std;
......
......@@ -18,7 +18,7 @@
#include "../Application.h"
#include "../Serializer.h"
#include "ApplicationImpl.h"
#include "ServicesImpl.h"
#include <sstream>
using namespace std;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment