1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version. This program is released under
10  * the GPL with the additional exemption that compiling, linking,
11  * and/or using OpenSSL is allowed.
12  *
13  * For a license to use the SEMS software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * SEMS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 
28 #include "AmEventQueue.h"
29 #include "log.h"
30 #include "AmConfig.h"
31 
32 #include <typeinfo>
AmEventQueue(AmEventHandler * handler)33 AmEventQueue::AmEventQueue(AmEventHandler* handler)
34   : handler(handler),
35     wakeup_handler(NULL),
36     ev_pending(false),
37     finalized(false)
38 {
39 }
40 
~AmEventQueue()41 AmEventQueue::~AmEventQueue()
42 {
43   m_queue.lock();
44   while(!ev_queue.empty()){
45     delete ev_queue.front();
46     ev_queue.pop();
47   }
48   m_queue.unlock();
49 }
50 
postEvent(AmEvent * event)51 void AmEventQueue::postEvent(AmEvent* event)
52 {
53   if (AmConfig::LogEvents)
54     DBG("AmEventQueue: trying to post event\n");
55 
56   m_queue.lock();
57 
58   if(event)
59     ev_queue.push(event);
60 
61   if(!ev_pending.get()) {
62     ev_pending.set(true);
63     if (NULL != wakeup_handler)
64       wakeup_handler->notify(this);
65   }
66 
67   m_queue.unlock();
68 
69   if (AmConfig::LogEvents)
70     DBG("AmEventQueue: event posted\n");
71 }
72 
processEvents()73 void AmEventQueue::processEvents()
74 {
75   m_queue.lock();
76 
77   while(!ev_queue.empty()) {
78 
79     AmEvent* event = ev_queue.front();
80     ev_queue.pop();
81     m_queue.unlock();
82 
83     if (AmConfig::LogEvents)
84       DBG("before processing event (%s)\n",
85 	  typeid(*event).name());
86     handler->process(event);
87     if (AmConfig::LogEvents)
88       DBG("event processed (%s)\n",
89 	  typeid(*event).name());
90     delete event;
91     m_queue.lock();
92   }
93 
94   ev_pending.set(false);
95   m_queue.unlock();
96 }
97 
waitForEvent()98 void AmEventQueue::waitForEvent()
99 {
100   ev_pending.wait_for();
101 }
102 
processSingleEvent()103 void AmEventQueue::processSingleEvent()
104 {
105   m_queue.lock();
106 
107   if (!ev_queue.empty()) {
108 
109     AmEvent* event = ev_queue.front();
110     ev_queue.pop();
111     m_queue.unlock();
112 
113     if (AmConfig::LogEvents)
114       DBG("before processing event\n");
115     handler->process(event);
116     if (AmConfig::LogEvents)
117       DBG("event processed\n");
118     delete event;
119 
120     m_queue.lock();
121     if (ev_queue.empty())
122       ev_pending.set(false);
123   }
124 
125   m_queue.unlock();
126 }
127 
eventPending()128 bool AmEventQueue::eventPending() {
129   m_queue.lock();
130   bool res = !ev_queue.empty();
131   m_queue.unlock();
132   return res;
133 }
134 
setEventNotificationSink(AmEventNotificationSink * _wakeup_handler)135 void AmEventQueue::setEventNotificationSink(AmEventNotificationSink*
136 					    _wakeup_handler) {
137   // locking actually not necessary - if replacing pointer is atomic
138   m_queue.lock();
139   wakeup_handler = _wakeup_handler;
140   if(wakeup_handler && ev_pending.get())
141     wakeup_handler->notify(this);
142   m_queue.unlock();
143 }
144