blob: 9f241adf6bb7c56e793e590e10824aebaff2eaf1 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2006 Federico Montesino Pouzols <fedemp@altern.org>
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002//
Emeric Vigier2f625822012-08-06 11:09:52 -04003// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
Alexandre Lisionddd731e2014-01-31 11:50:08 -05007//
Emeric Vigier2f625822012-08-06 11:09:52 -04008// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
Alexandre Lisionddd731e2014-01-31 11:50:08 -050012//
Emeric Vigier2f625822012-08-06 11:09:52 -040013// You should have received a copy of the GNU General Public License
Alexandre Lisionddd731e2014-01-31 11:50:08 -050014// along with this program; if not, write to the Free Software
Emeric Vigier2f625822012-08-06 11:09:52 -040015// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Alexandre Lisionddd731e2014-01-31 11:50:08 -050016//
Emeric Vigier2f625822012-08-06 11:09:52 -040017// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
Alexandre Lisionddd731e2014-01-31 11:50:08 -050022// the GNU General Public License. This exception does not however
Emeric Vigier2f625822012-08-06 11:09:52 -040023// invalidate any other reasons why the executable file might be covered by
Alexandre Lisionddd731e2014-01-31 11:50:08 -050024// the GNU General Public License.
Emeric Vigier2f625822012-08-06 11:09:52 -040025//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38/**
39 * @file pool.h
40 * @short Pools of RTP sessions.
41 **/
42
43#ifndef CCXX_RTP_POOL_H
44#define CCXX_RTP_POOL_H
45
46#include <list>
47#include <ccrtp/rtp.h>
48
Alexandre Lisionddd731e2014-01-31 11:50:08 -050049NAMESPACE_COMMONCPP
Emeric Vigier2f625822012-08-06 11:09:52 -040050using std::list;
Emeric Vigier2f625822012-08-06 11:09:52 -040051
52typedef TRTPSessionBase<> RTPSessionBase;
53
54class RTPSessionBaseHandler
55{
56public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050057 inline microtimeout_t getSchedulingTimeout(RTPSessionBase& s)
58 { return s.getSchedulingTimeout(); }
Emeric Vigier2f625822012-08-06 11:09:52 -040059
Alexandre Lisionddd731e2014-01-31 11:50:08 -050060 inline timeval getRTCPCheckInterval(RTPSessionBase& s)
61 { return s.getRTCPCheckInterval(); }
Emeric Vigier2f625822012-08-06 11:09:52 -040062
Alexandre Lisionddd731e2014-01-31 11:50:08 -050063 size_t
64 takeInDataPacket(RTPSessionBase& s)
65 { return s.takeInDataPacket(); }
66
67 size_t
68 dispatchDataPacket(RTPSessionBase& s)
69 { return s.dispatchDataPacket(); }
70
71 void
72 controlReceptionService(RTPSessionBase& s)
73 { s.controlReceptionService(); }
74
75 void
76 controlTransmissionService(RTPSessionBase& s)
77 { s.controlTransmissionService(); }
78
79 inline SOCKET getDataRecvSocket(RTPSessionBase& s) const
80 { return s.getDataRecvSocket(); }
81
82 inline SOCKET getControlRecvSocket(RTPSessionBase& s) const
83 { return s.getControlRecvSocket(); }
Emeric Vigier2f625822012-08-06 11:09:52 -040084};
85
86/**
87 * Class for tracking session status. Session pools arrange sessions
88 * in lists of SessionListElement objects.
89 *
90 * @author Jorgen Terner
91 **/
92
93class SessionListElement {
94private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050095 RTPSessionBase* elem;
96 bool cleared;
Emeric Vigier2f625822012-08-06 11:09:52 -040097
98public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -050099 SessionListElement(RTPSessionBase* e);
100 void clear();
101 bool isCleared();
102 RTPSessionBase* get();
Emeric Vigier2f625822012-08-06 11:09:52 -0400103};
104
105
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500106inline SessionListElement::SessionListElement(RTPSessionBase* e)
107 : elem(e), cleared(false) {
Emeric Vigier2f625822012-08-06 11:09:52 -0400108}
109
110inline void SessionListElement::clear() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500111 cleared = true;
112 delete elem;
113 elem = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -0400114}
115
116inline bool SessionListElement::isCleared() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500117 return cleared;
Emeric Vigier2f625822012-08-06 11:09:52 -0400118}
119
120inline RTPSessionBase* SessionListElement::get() {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500121 return elem;
Emeric Vigier2f625822012-08-06 11:09:52 -0400122}
123
124/**
125 * std equality for SessionListElement objects.
126 *
127 * @author Jorgen Terner
128 **/
129class PredEquals
130{
131protected:
132 RTPSessionBase* elem;
133public:
134 PredEquals(RTPSessionBase* e) : elem(e) {}
135
136 bool operator() (SessionListElement* e)
137 {
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500138 return e->get() == elem;
Emeric Vigier2f625822012-08-06 11:09:52 -0400139 }
140};
141
142/**
143 * This class is a base class for classes that define a group of RTP
144 * sessions that will be served by one or more execution
145 * threads. Derived classes are responsible for serving each RTP
146 * session with a thread at least.
147 *
148 * In order to use the RTP session "pool" you just have to build
149 * RTPSessionBase objects for each RTP session (instead of RTPSession
150 * objects). Then, add the RTPSessionBase objects to an RTP session
151 * "pool" and call startRunning() method of the session pool.
152 *
153 * @author Federico Montesino Pouzols <fedemp@altern.org>
154 **/
155class __EXPORT RTPSessionPool: public RTPSessionBaseHandler
156{
157public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500158 RTPSessionPool();
Emeric Vigier2f625822012-08-06 11:09:52 -0400159
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500160 inline virtual ~RTPSessionPool()
161 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400162
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500163 bool
164 addSession(RTPSessionBase& session);
Emeric Vigier2f625822012-08-06 11:09:52 -0400165
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500166 bool
167 removeSession(RTPSessionBase& session);
Emeric Vigier2f625822012-08-06 11:09:52 -0400168
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500169 size_t
170 getPoolLength() const;
Emeric Vigier2f625822012-08-06 11:09:52 -0400171
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500172 virtual void startRunning() = 0;
Emeric Vigier2f625822012-08-06 11:09:52 -0400173
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500174 inline bool isActive()
175 { return poolActive; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400176
177protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500178 inline void setActive()
179 { poolActive = true; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400180
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500181 inline timeval getPoolTimeout()
182 { return poolTimeout; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400183
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500184 inline void setPoolTimeout(int sec, int usec)
185 { poolTimeout.tv_sec = sec; poolTimeout.tv_usec = usec; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400186
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500187 inline void setPoolTimeout(struct timeval to)
188 { poolTimeout = to; }
Emeric Vigier2f625822012-08-06 11:09:52 -0400189
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500190 std::list<SessionListElement*> sessionList;
191 typedef std::list<SessionListElement*>::iterator PoolIterator;
Emeric Vigier2f625822012-08-06 11:09:52 -0400192
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500193 mutable ThreadLock poolLock;
194
195#ifndef _MSWINDOWS_
196 fd_set recvSocketSet;
197 SOCKET highestSocket; // highest socket number + 1
Emeric Vigier2f625822012-08-06 11:09:52 -0400198#endif
199
200private:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500201 timeval poolTimeout;
202 mutable bool poolActive;
Emeric Vigier2f625822012-08-06 11:09:52 -0400203};
204
205
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500206class __EXPORT SingleRTPSessionPool :
207 public RTPSessionPool,
208 public Thread
Emeric Vigier2f625822012-08-06 11:09:52 -0400209{
210public:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500211 /**
212 * @param pri optional thread priority value.
213 **/
214 SingleRTPSessionPool(int pri = 0) :
215 RTPSessionPool(),
216 Thread(pri)
217 { }
Emeric Vigier2f625822012-08-06 11:09:52 -0400218
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500219 ~SingleRTPSessionPool()
220 { }
221
222 void startRunning()
223 { setActive(); Thread::start(); }
Emeric Vigier2f625822012-08-06 11:09:52 -0400224
225protected:
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500226 /**
227 * Runnable method for the thread. This thread serves all the
228 * RTP sessions.added to this pool.
229 */
230 void run();
Emeric Vigier2f625822012-08-06 11:09:52 -0400231};
232
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500233END_NAMESPACE
Emeric Vigier2f625822012-08-06 11:09:52 -0400234
235#endif //CCXX_RTP_POOL_H
236
237/** EMACS **
238 * Local variables:
239 * mode: c++
240 * c-basic-offset: 8
241 * End:
242 */