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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "eventdispatcher.h"
25 EventDispatcher::EventDispatcher()
28 pthread_mutex_init(&mutex, NULL);
30 mutex = CreateMutex(NULL, FALSE, NULL);
34 void EventDispatcher::edRegister(EDReceiver* edr)
37 receivers.push_back(edr);
41 bool EventDispatcher::edFindAndCall(void* userTag)
45 EDReceiver* edr = NULL;
47 for(i = receivers.begin(); i != receivers.end(); i++)
49 if (ed_cb_find(*i, userTag))
52 break; // found (by asking the EventDispatcher implementor to check if userTag is for *i
56 if ((i == receivers.end()) || edr->callinprogress || edr->nomorecalls)
62 edr->callinprogress = true;
64 bool r_deregisterEDR = false;
65 bool r_wakeThread = false;
66 bool r_deleteEDR = false;
67 edr->call(userTag, r_deregisterEDR, r_wakeThread, r_deleteEDR);
69 edr->callinprogress = false;
72 // if it's a stream packet (r_deregisterEDR == false)
73 // and edr->nomorecalls == true
74 // then something has called unregister for this EDR while we were out on the call
75 // set r_wakeThread to ensure that we signal the edr->cond to wake up that thread in edUnregister below
76 if ((r_deregisterEDR == false) && (edr->nomorecalls))
83 for(i = receivers.begin(); i != receivers.end(); i++)
92 if (i == receivers.end()) abort(); // should never happen
93 // but it can happen under windows ... how??
100 pthread_cond_signal(&edr->cond);
115 void EventDispatcher::edUnregister(EDReceiver* edr)
120 for(i = receivers.begin(); i != receivers.end(); i++)
122 if (*i == edr) break; // found
125 // Not in the list. Already unregistered? Perhaps vdr::connectionDied already removed this streamclient
126 // FIXME, this should probably be done another way. A call to edUnregister with an object that may or may not be in the list? Not good.
127 if (i == receivers.end())
133 if (!edr->callinprogress)
140 edr->nomorecalls = true;
142 // edUnlock, wait for callinprogres=false (cond to be signalled), lock
144 pthread_cond_wait(&edr->cond, &mutex);
147 WaitForSingleObject(edr->cond,INFINITE);
148 WaitForSingleObject(mutex, INFINITE);
149 ResetEvent(edr->cond);
153 for(i = receivers.begin(); i != receivers.end(); i++)
155 if (*i == edr) break; // found
158 if (i == receivers.end()) abort(); // should never happen
164 // ---------------------------------------
166 void EventDispatcher::edLock()
169 pthread_mutex_lock(&mutex);
171 WaitForSingleObject(mutex, INFINITE);
175 void EventDispatcher::edUnlock()
178 pthread_mutex_unlock(&mutex);
184 // ---------------------------------------
186 void EventDispatcher::edSleepThisReceiver(EDReceiver* edr)
188 // For blocking version, not callback version. Call with edLock locked
191 pthread_cond_wait(&edr->cond, &mutex);
193 ResetEvent(edr->cond);
195 WaitForSingleObject(edr->cond,INFINITE);
196 ResetEvent(edr->cond);
197 WaitForSingleObject(mutex, INFINITE);
201 // -------------- EDReceiver implementation
203 EDReceiver::EDReceiver()
206 callinprogress = false;
208 pthread_cond_init(&cond, NULL);
210 cond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
214 EDReceiver::~EDReceiver()
217 if (cond!=NULL) CloseHandle(cond);
219 pthread_cond_destroy(&cond);