2 Copyright 2007 Chris Tallon
4 This file is part of VOMP.
6 VOMP 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.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "eventdispatcher.h"
23 EventDispatcher::EventDispatcher()
26 pthread_mutex_init(&mutex, NULL);
28 mutex = CreateMutex(NULL, FALSE, NULL);
32 void EventDispatcher::edRegister(EDReceiver* edr)
35 receivers.push_back(edr);
39 bool EventDispatcher::edFindAndCall(void* userTag)
43 EDReceiver* edr = NULL;
45 for(i = receivers.begin(); i != receivers.end(); i++)
47 if (ed_cb_find(*i, userTag))
50 break; // found (by asking the EventDispatcher implementor to check if userTag is for *i
54 if ((i == receivers.end()) || edr->callinprogress || edr->nomorecalls)
60 edr->callinprogress = true;
62 bool edrType = edr->call(userTag);
64 edr->callinprogress = false;
66 if (edrType == false) // it's a multicall
68 if (edr->nomorecalls) // External has called unRegister - probably the receiver
70 // wake up the thread waiting in unregister
72 pthread_cond_signal(&edr->cond);
78 else // It's a single call. The receiver should be removed from the list. There will be a thread to wake up
80 for(i = receivers.begin(); i != receivers.end(); i++)
88 if (i == receivers.end()) abort(); // should never happen
91 pthread_cond_signal(&edr->cond);
101 void EventDispatcher::edUnregister(EDReceiver* edr)
106 for(i = receivers.begin(); i != receivers.end(); i++)
108 if (*i == edr) break; // found
111 if (i == receivers.end()) abort(); // should never happen
113 if (!edr->callinprogress)
120 edr->nomorecalls = true;
122 // edUnlock, wait for callinprogres=false (cond to be signalled), lock
124 pthread_cond_wait(&edr->cond, &mutex);
129 for(i = receivers.begin(); i != receivers.end(); i++)
131 if (*i == edr) break; // found
134 if (i == receivers.end()) abort(); // should never happen
140 // ---------------------------------------
142 void EventDispatcher::edLock()
145 pthread_mutex_lock(&mutex);
147 WaitForSingleObject(mutex, INFINITE);
151 void EventDispatcher::edUnlock()
154 pthread_mutex_unlock(&mutex);
160 // ---------------------------------------
162 void EventDispatcher::edSleepThisReceiver(EDReceiver* edr)
164 // For blocking version, not callback version. Call with edLock locked
167 pthread_cond_init(&edr->cond, NULL);
168 pthread_cond_wait(&edr->cond, &mutex);
174 // -------------- EDReceiver implementation
176 EDReceiver::EDReceiver()
179 callinprogress = false;