22#include "mytheventhandler.h"
23#include "private/debug.h"
24#include "proto/mythprotoevent.h"
25#include "private/os/threads/thread.h"
26#include "private/os/threads/event.h"
27#include "private/cppdef.h"
28#include "private/builtin.h"
41EventHandler::EventHandlerThread::EventHandlerThread(
const std::string& server,
unsigned port)
47EventHandler::EventHandlerThread::~EventHandlerThread()
58 class SubscriptionHandlerThread :
private OS::Thread
62 virtual ~SubscriptionHandlerThread();
64 bool IsRunning() {
return OS::Thread::is_running(); }
65 void PostMessage(
const EventMessagePtr& msg);
70 mutable OS::Mutex m_mutex;
71 OS::Event m_queueContent;
72 std::list<EventMessagePtr> m_msgQueue;
80SubscriptionHandlerThread::SubscriptionHandlerThread(
EventSubscriber *handle,
unsigned subid)
88 if (m_handle && Start())
89 DBG(DBG_DEBUG,
"%s: subscription is started (%p:%u)\n", __FUNCTION__, m_handle, m_subId);
91 DBG(DBG_ERROR,
"%s: subscription failed (%p:%u)\n", __FUNCTION__, m_handle, m_subId);
94SubscriptionHandlerThread::~SubscriptionHandlerThread()
100bool SubscriptionHandlerThread::Start()
102 if (OS::Thread::is_running())
104 return OS::Thread::start_thread();
107void SubscriptionHandlerThread::Stop()
109 if (OS::Thread::is_running())
111 DBG(DBG_DEBUG,
"%s: subscription thread (%p:%u)\n", __FUNCTION__, m_handle, m_subId);
113 OS::Thread::stop_thread(
false);
114 m_queueContent.notify_one();
116 OS::Thread::stop_thread(
true);
117 DBG(DBG_DEBUG,
"%s: subscription thread (%p:%u) stopped\n", __FUNCTION__, m_handle, m_subId);
121void SubscriptionHandlerThread::PostMessage(
const EventMessagePtr& msg)
124 OS::LockGuard lock(m_mutex);
125 m_msgQueue.push_back(msg);
126 m_queueContent.notify_one();
129void *SubscriptionHandlerThread::process()
131 while (!is_stopped())
133 while (!m_msgQueue.empty() && !is_stopped())
137 EventMessagePtr msg = m_msgQueue.front();
138 m_msgQueue.pop_front();
141 m_handle->HandleBackendMessage(msg);
144 m_queueContent.wait();
159 BasicEventHandler(
const std::string& server,
unsigned port);
160 virtual ~BasicEventHandler();
162 virtual bool Start();
164 virtual void Reset();
165 virtual bool HasStarted();
166 virtual bool IsConnected();
168 virtual bool SubscribeForEvent(
unsigned subid, EVENT_t event);
169 virtual void RevokeSubscription(
unsigned subid);
177 typedef std::map<EVENT_t, std::list<unsigned> > subscriptionsByEvent_t;
178 subscriptionsByEvent_t m_subscriptionsByEvent;
179 typedef std::map<unsigned, SubscriptionHandlerThread*> subscriptions_t;
180 subscriptions_t m_subscriptions;
182 void DispatchEvent(
const EventMessagePtr& msg);
183 virtual void* process(
void);
184 void AnnounceStatus(
const char *status);
185 void AnnounceTimer();
190BasicEventHandler::BasicEventHandler(
const std::string& server,
unsigned port)
191: EventHandlerThread(server, port), OS::Thread()
197BasicEventHandler::~BasicEventHandler()
201 OS::LockGuard lock(m_mutex);
202 for (subscriptions_t::iterator it = m_subscriptions.begin(); it != m_subscriptions.end(); ++it)
204 m_subscriptions.clear();
205 m_subscriptionsByEvent.clear();
207 SAFE_DELETE(m_event);
210bool BasicEventHandler::Start()
212 if (OS::Thread::is_running())
214 return OS::Thread::start_thread();
217void BasicEventHandler::Stop()
219 if (OS::Thread::is_running())
221 DBG(DBG_DEBUG,
"%s: event handler thread (%p)\n", __FUNCTION__,
this);
222 OS::Thread::stop_thread(
true);
223 DBG(DBG_DEBUG,
"%s: event handler thread (%p) stopped\n", __FUNCTION__,
this);
225 if (m_event->IsOpen())
229void BasicEventHandler::Reset()
235bool BasicEventHandler::HasStarted()
237 return OS::Thread::is_running();
240bool BasicEventHandler::IsConnected()
242 return m_event->IsOpen();
248 OS::LockGuard lock(m_mutex);
249 subscriptions_t::const_reverse_iterator it = m_subscriptions.rbegin();
250 if (it != m_subscriptions.rend())
252 SubscriptionHandlerThread *handler =
new SubscriptionHandlerThread(sub, ++
id);
253 if (handler->IsRunning())
255 m_subscriptions.insert(std::make_pair(
id, handler));
263bool BasicEventHandler::SubscribeForEvent(
unsigned subid, EVENT_t event)
265 OS::LockGuard lock(m_mutex);
267 if (m_subscriptions.find(subid) == m_subscriptions.end())
269 std::list<unsigned>& sevt = m_subscriptionsByEvent[event];
270 std::list<unsigned>::const_iterator it = sevt.begin();
271 while (it != sevt.end())
277 sevt.push_back(subid);
281void BasicEventHandler::RevokeSubscription(
unsigned subid)
283 OS::LockGuard lock(m_mutex);
284 subscriptions_t::iterator it = m_subscriptions.find(subid);
285 if (it != m_subscriptions.end())
288 m_subscriptions.erase(it);
294 OS::LockGuard lock(m_mutex);
295 std::vector<subscriptions_t::iterator> its;
296 for (subscriptions_t::iterator it = m_subscriptions.begin(); it != m_subscriptions.end(); ++it)
298 if (sub == it->second->GetHandle())
301 for (std::vector<subscriptions_t::iterator>::const_iterator it = its.begin(); it != its.end(); ++it)
303 delete (*it)->second;
304 m_subscriptions.erase(*it);
308void BasicEventHandler::DispatchEvent(
const EventMessagePtr& msg)
310 OS::LockGuard lock(m_mutex);
311 std::vector<std::list<unsigned>::iterator> revoked;
312 std::list<unsigned>& sevt = m_subscriptionsByEvent[msg->event];
313 std::list<unsigned>::iterator itsevt = sevt.begin();
314 std::list<unsigned>::iterator itsend = sevt.end();
315 while (itsevt != itsend)
317 subscriptions_t::const_iterator itsub = m_subscriptions.find(*itsevt);
318 if (itsub != m_subscriptions.end())
319 itsub->second->PostMessage(msg);
321 revoked.push_back(itsevt);
324 std::vector<std::list<unsigned>::iterator>::const_iterator itr;
325 for (itr = revoked.begin(); itr != revoked.end(); ++itr)
326 m_subscriptionsByEvent[msg->event].erase(*itr);
329void *BasicEventHandler::process()
333 AnnounceStatus(EVENTHANDLER_CONNECTED);
334 while (!OS::Thread::is_stopped())
337 EventMessage *msg =
nullptr;
338 r = m_event->RcvBackendMessage(EVENTHANDLER_TIMEOUT, &msg);
340 DispatchEvent(EventMessagePtr(msg));
343 AnnounceStatus(EVENTHANDLER_DISCONNECTED);
358 AnnounceStatus(EVENTHANDLER_STOPPED);
364void BasicEventHandler::AnnounceStatus(
const char *status)
366 DBG(DBG_DEBUG,
"%s: (%p) %s\n", __FUNCTION__,
this, status);
367 EventMessage *msg =
new EventMessage();
368 msg->event = EVENT_HANDLER_STATUS;
369 msg->subject.push_back(status);
370 msg->subject.push_back(m_server);
371 DispatchEvent(EventMessagePtr(msg));
374void BasicEventHandler::AnnounceTimer()
376 EventMessage *msg =
new EventMessage();
377 msg->event = EVENT_HANDLER_TIMER;
378 msg->subject.push_back(
"");
379 DispatchEvent(EventMessagePtr(msg));
382void BasicEventHandler::RetryConnect()
385 while (!OS::Thread::is_stopped())
391 AnnounceStatus(EVENTHANDLER_CONNECTED);
396 DBG(DBG_INFO,
"%s: could not open event socket (%d)\n", __FUNCTION__, m_event->GetSocketErrNo());
397 AnnounceStatus(EVENTHANDLER_NOTCONNECTED);
408EventHandler::EventHandler(
const std::string& server,
unsigned port)
412 m_imp = EventHandlerThreadPtr(
new BasicEventHandler(server, port));
This is the main namespace that encloses all public classes.