Files
rtphone/src/engine/helper/HL_SocketHeap.h

114 lines
3.1 KiB
C++

/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __SOCKET_HEAP_H
#define __SOCKET_HEAP_H
#include "../engine_config.h"
#include <map>
#include <vector>
#include <algorithm>
#include <thread>
#include "HL_NetworkSocket.h"
#include "HL_Sync.h"
#include "HL_Rtp.h"
// Class is used to process incoming datagrams
class SocketSink
{
public:
virtual ~SocketSink();
virtual void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize) = 0;
};
// Class allocates new UDP sockets and tracks incoming packets on them. It runs in separate thread
class SocketHeap
{
public:
enum Multiplex
{
DoMultiplexing,
DontMultiplexing
};
SocketHeap(unsigned short start, unsigned short finish);
virtual ~SocketHeap();
static SocketHeap& instance();
void start();
void stop();
// Specifies ne\ port number range. The sockets will be allocated in range [start..finish]
void setRange(unsigned short start, unsigned short finish);
// Returns used port number range
void range(unsigned short& start, unsigned short& finish);
// Attempts to allocate and return socket + allocated port number. REQUIRES pointer to data sink - it will be used to process incoming datagrams
PDatagramSocket allocSocket(int family, SocketSink* sink, int port = 0);
RtpPair<PDatagramSocket> allocSocketPair(int family, SocketSink* sink, Multiplex m);
// Stops receiving data for specified socket and frees socket itself.
void freeSocket(PDatagramSocket socket);
void freeSocketPair(const RtpPair<PDatagramSocket>& p);
// Sends data to specified address on specified socket.
void sendData(DatagramSocket& socket, InternetAddress& dest, const void* dataPtr, int dataSize);
protected:
struct SocketItem
{
// Local port number for socket
PDatagramSocket mSocket;
// Data sink pointer
SocketSink* mSink;
SocketItem()
:mSink(nullptr)
{ }
SocketItem(unsigned short portnumber, SocketSink* sink)
:mSink(sink)
{
mSocket->mLocalPort = portnumber;
}
~SocketItem()
{ }
};
typedef std::map<SOCKET, SocketItem> SocketMap;
typedef std::vector<unsigned short> PortVector;
typedef std::vector<PDatagramSocket> SocketVector;
Mutex mGuard;
SocketMap mSocketMap;
PortVector mPortVector;
unsigned short mStart,
mFinish;
SocketVector mDeleteVector;
Mutex mDeleteGuard;
char mTempPacket[MAX_UDPPACKET_SIZE];
std::shared_ptr<std::thread> mWorkerThread;
std::thread::id mThreadId;
bool mShutdown = false;
bool isShutdown() const { return mShutdown; }
void thread();
// Processes mDeleteVector -> updates mSocketMap, removes socket items and closes sockets specified in mDeleteVector
void processDeleted();
};
#endif