2 Copyright 2007-2020 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, see <https://www.gnu.org/licenses/>.
20 #include "eventdispatcher.h"
22 void EventDispatcher::edRegister(EDReceiver* edr)
25 receivers.push_back(edr);
29 bool EventDispatcher::edFindAndCall(void* userTag)
33 EDReceiver* edr = NULL;
35 for(i = receivers.begin(); i != receivers.end(); i++)
37 if (ed_cb_find(*i, userTag))
40 break; // found (by asking the EventDispatcher implementor to check if userTag is for *i
44 if ((i == receivers.end()) || edr->callinprogress || edr->nomorecalls)
50 edr->callinprogress = true;
52 bool r_deregisterEDR = false;
53 bool r_wakeThread = false;
54 bool r_deleteEDR = false;
55 edr->call(userTag, r_deregisterEDR, r_wakeThread, r_deleteEDR);
57 edr->callinprogress = false;
60 // if it's a stream packet (r_deregisterEDR == false)
61 // and edr->nomorecalls == true
62 // then something has called unregister for this EDR while we were out on the call
63 // set r_wakeThread to ensure that we signal the edr->cond to wake up that thread in edUnregister below
64 if ((r_deregisterEDR == false) && (edr->nomorecalls))
71 for(i = receivers.begin(); i != receivers.end(); i++)
80 if (i == receivers.end()) abort(); // should never happen
81 // but it can happen under windows ... how??
87 edr->cond.notify_one();
99 void EventDispatcher::edUnregister(EDReceiver* edr)
101 std::unique_lock<std::mutex> ul(edMutex);
104 for(i = receivers.begin(); i != receivers.end(); i++)
106 if (*i == edr) break; // found
109 // Not in the list. Already unregistered? Perhaps vdr::connectionDied already removed this streamclient
110 // 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.
111 if (i == receivers.end()) return;
113 if (!edr->callinprogress)
119 edr->nomorecalls = true;
121 // edUnlock, wait for callinprogres=false (cond to be signalled), lock
124 for(i = receivers.begin(); i != receivers.end(); i++)
126 if (*i == edr) break; // found
129 if (i == receivers.end()) abort(); // should never happen
134 // ---------------------------------------
136 void EventDispatcher::edSleepThisReceiver(EDReceiver* edr)
138 // For blocking version, not callback version. Call with edLock locked
139 std::unique_lock<std::mutex> ul(edMutex, std::defer_lock);