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