mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
SRT: Upgrade libsrt from 1.4.1 to 1.5.1. v6.0.12 (#3362)
Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
parent
7a56208f2f
commit
fe086dfc31
143 changed files with 38185 additions and 15108 deletions
686
trunk/3rdparty/srt-1-fit/srtcore/queue.h
vendored
686
trunk/3rdparty/srt-1-fit/srtcore/queue.h
vendored
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -50,13 +50,12 @@ modified by
|
|||
Haivision Systems Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef INC_SRT_QUEUE_H
|
||||
#define INC_SRT_QUEUE_H
|
||||
|
||||
#ifndef __UDT_QUEUE_H__
|
||||
#define __UDT_QUEUE_H__
|
||||
|
||||
#include "channel.h"
|
||||
#include "common.h"
|
||||
#include "packet.h"
|
||||
#include "socketconfig.h"
|
||||
#include "netinet_any.h"
|
||||
#include "utilities.h"
|
||||
#include <list>
|
||||
|
@ -64,485 +63,548 @@ modified by
|
|||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
namespace srt
|
||||
{
|
||||
class CChannel;
|
||||
class CUDT;
|
||||
|
||||
struct CUnit
|
||||
{
|
||||
CPacket m_Packet; // packet
|
||||
enum Flag { FREE = 0, GOOD = 1, PASSACK = 2, DROPPED = 3 };
|
||||
Flag m_iFlag; // 0: free, 1: occupied, 2: msg read but not freed (out-of-order), 3: msg dropped
|
||||
CPacket m_Packet; // packet
|
||||
enum Flag
|
||||
{
|
||||
FREE = 0,
|
||||
GOOD = 1,
|
||||
PASSACK = 2,
|
||||
DROPPED = 3
|
||||
};
|
||||
|
||||
// TODO: The new RcvBuffer allows to use atomic_bool here.
|
||||
sync::atomic<Flag> m_iFlag; // 0: free, 1: occupied, 2: msg read but not freed (out-of-order), 3: msg dropped
|
||||
};
|
||||
|
||||
class CUnitQueue
|
||||
{
|
||||
public:
|
||||
/// @brief Construct a unit queue.
|
||||
/// @param mss Initial number of units to allocate.
|
||||
/// @param mss Maximum segment size meaning the size of each unit.
|
||||
/// @throws CUDTException SRT_ENOBUF.
|
||||
CUnitQueue(int initNumUnits, int mss);
|
||||
~CUnitQueue();
|
||||
|
||||
public:
|
||||
|
||||
CUnitQueue();
|
||||
~CUnitQueue();
|
||||
|
||||
public: // Storage size operations
|
||||
|
||||
/// Initialize the unit queue.
|
||||
/// @param [in] size queue size
|
||||
/// @param [in] mss maximum segment size
|
||||
/// @param [in] version IP version
|
||||
/// @return 0: success, -1: failure.
|
||||
|
||||
int init(int size, int mss, int version);
|
||||
|
||||
/// Increase (double) the unit queue size.
|
||||
/// @return 0: success, -1: failure.
|
||||
|
||||
int increase();
|
||||
|
||||
/// Decrease (halve) the unit queue size.
|
||||
/// @return 0: success, -1: failure.
|
||||
|
||||
int shrink();
|
||||
|
||||
public: // Operations on units
|
||||
|
||||
/// find an available unit for incoming packet.
|
||||
/// @return Pointer to the available unit, NULL if not found.
|
||||
|
||||
CUnit* getNextAvailUnit();
|
||||
|
||||
|
||||
void makeUnitFree(CUnit * unit);
|
||||
|
||||
void makeUnitGood(CUnit * unit);
|
||||
int capacity() const { return m_iSize; }
|
||||
int size() const { return m_iSize - m_iNumTaken; }
|
||||
|
||||
public:
|
||||
/// @brief Find an available unit for incoming packet. Allocate new units if 90% or more are in use.
|
||||
/// @note This function is not thread-safe. Currently only CRcvQueue::worker thread calls it, thus
|
||||
/// it is not an issue. However, must be protected if used from several threads in the future.
|
||||
/// @return Pointer to the available unit, NULL if not found.
|
||||
CUnit* getNextAvailUnit();
|
||||
|
||||
inline int getIPversion() const { return m_iIPversion; }
|
||||
void makeUnitFree(CUnit* unit);
|
||||
|
||||
void makeUnitGood(CUnit* unit);
|
||||
|
||||
private:
|
||||
struct CQEntry
|
||||
{
|
||||
CUnit* m_pUnit; // unit queue
|
||||
char* m_pBuffer; // data buffer
|
||||
int m_iSize; // size of each queue
|
||||
struct CQEntry
|
||||
{
|
||||
CUnit* m_pUnit; // unit queue
|
||||
char* m_pBuffer; // data buffer
|
||||
int m_iSize; // size of each queue
|
||||
|
||||
CQEntry* m_pNext;
|
||||
}
|
||||
*m_pQEntry, // pointer to the first unit queue
|
||||
*m_pCurrQueue, // pointer to the current available queue
|
||||
*m_pLastQueue; // pointer to the last unit queue
|
||||
CQEntry* m_pNext;
|
||||
};
|
||||
|
||||
CUnit* m_pAvailUnit; // recent available unit
|
||||
/// Increase the unit queue size (by @a m_iBlockSize units).
|
||||
/// Uses m_mtx to protect access and changes of the queue state.
|
||||
/// @return 0: success, -1: failure.
|
||||
int increase_();
|
||||
|
||||
int m_iSize; // total size of the unit queue, in number of packets
|
||||
int m_iCount; // total number of valid packets in the queue
|
||||
|
||||
int m_iMSS; // unit buffer size
|
||||
int m_iIPversion; // IP version
|
||||
/// @brief Allocated a CQEntry of iNumUnits with each unit of mss bytes.
|
||||
/// @param iNumUnits a number of units to allocate
|
||||
/// @param mss the size of each unit in bytes.
|
||||
/// @return a pointer to a newly allocated entry on success, NULL otherwise.
|
||||
static CQEntry* allocateEntry(const int iNumUnits, const int mss);
|
||||
|
||||
private:
|
||||
CUnitQueue(const CUnitQueue&);
|
||||
CUnitQueue& operator=(const CUnitQueue&);
|
||||
CQEntry* m_pQEntry; // pointer to the first unit queue
|
||||
CQEntry* m_pCurrQueue; // pointer to the current available queue
|
||||
CQEntry* m_pLastQueue; // pointer to the last unit queue
|
||||
CUnit* m_pAvailUnit; // recent available unit
|
||||
int m_iSize; // total size of the unit queue, in number of packets
|
||||
sync::atomic<int> m_iNumTaken; // total number of valid (occupied) packets in the queue
|
||||
const int m_iMSS; // unit buffer size
|
||||
const int m_iBlockSize; // Number of units in each CQEntry.
|
||||
|
||||
private:
|
||||
CUnitQueue(const CUnitQueue&);
|
||||
CUnitQueue& operator=(const CUnitQueue&);
|
||||
};
|
||||
|
||||
struct CSNode
|
||||
{
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
uint64_t m_llTimeStamp_tk; // Time Stamp
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
sync::steady_clock::time_point m_tsTimeStamp;
|
||||
|
||||
int m_iHeapLoc; // location on the heap, -1 means not on the heap
|
||||
sync::atomic<int> m_iHeapLoc; // location on the heap, -1 means not on the heap
|
||||
};
|
||||
|
||||
class CSndUList
|
||||
{
|
||||
friend class CSndQueue;
|
||||
public:
|
||||
CSndUList(sync::CTimer* pTimer);
|
||||
~CSndUList();
|
||||
|
||||
public:
|
||||
CSndUList();
|
||||
~CSndUList();
|
||||
enum EReschedule
|
||||
{
|
||||
DONT_RESCHEDULE = 0,
|
||||
DO_RESCHEDULE = 1
|
||||
};
|
||||
|
||||
public:
|
||||
static EReschedule rescheduleIf(bool cond) { return cond ? DO_RESCHEDULE : DONT_RESCHEDULE; }
|
||||
|
||||
enum EReschedule { DONT_RESCHEDULE = 0, DO_RESCHEDULE = 1 };
|
||||
/// Update the timestamp of the UDT instance on the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
/// @param [in] reschedule if the timestamp should be rescheduled
|
||||
/// @param [in] ts the next time to trigger sending logic on the CUDT
|
||||
void update(const CUDT* u, EReschedule reschedule, sync::steady_clock::time_point ts = sync::steady_clock::now());
|
||||
|
||||
static EReschedule rescheduleIf(bool cond) { return cond ? DO_RESCHEDULE : DONT_RESCHEDULE; }
|
||||
/// Retrieve the next (in time) socket from the heap to process its sending request.
|
||||
/// @return a pointer to CUDT instance to process next.
|
||||
CUDT* pop();
|
||||
|
||||
/// Update the timestamp of the UDT instance on the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
/// @param [in] reschedule if the timestamp should be rescheduled
|
||||
/// Remove UDT instance from the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void remove(const CUDT* u);// EXCLUDES(m_ListLock);
|
||||
|
||||
void update(const CUDT* u, EReschedule reschedule);
|
||||
/// Retrieve the next scheduled processing time.
|
||||
/// @return Scheduled processing time of the first UDT socket in the list.
|
||||
sync::steady_clock::time_point getNextProcTime();
|
||||
|
||||
/// Retrieve the next packet and peer address from the first entry, and reschedule it in the queue.
|
||||
/// @param [out] addr destination address of the next packet
|
||||
/// @param [out] pkt the next packet to be sent
|
||||
/// @return 1 if successfully retrieved, -1 if no packet found.
|
||||
/// Wait for the list to become non empty.
|
||||
void waitNonEmpty() const;
|
||||
|
||||
int pop(sockaddr*& addr, CPacket& pkt);
|
||||
|
||||
/// Remove UDT instance from the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
void remove(const CUDT* u);
|
||||
|
||||
/// Retrieve the next scheduled processing time.
|
||||
/// @return Scheduled processing time of the first UDT socket in the list.
|
||||
|
||||
uint64_t getNextProcTime();
|
||||
/// Signal to stop waiting in waitNonEmpty().
|
||||
void signalInterrupt() const;
|
||||
|
||||
private:
|
||||
/// Doubles the size of the list.
|
||||
///
|
||||
void realloc_();// REQUIRES(m_ListLock);
|
||||
|
||||
/// Doubles the size of the list.
|
||||
///
|
||||
void realloc_();
|
||||
/// Insert a new UDT instance into the list with realloc if required.
|
||||
///
|
||||
/// @param [in] ts time stamp: next processing time
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert_(const sync::steady_clock::time_point& ts, const CUDT* u);
|
||||
|
||||
/// Insert a new UDT instance into the list with realloc if required.
|
||||
///
|
||||
/// @param [in] ts time stamp: next processing time
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert_(int64_t ts, const CUDT* u);
|
||||
/// Insert a new UDT instance into the list without realloc.
|
||||
/// Should be called if there is a gauranteed space for the element.
|
||||
///
|
||||
/// @param [in] ts time stamp: next processing time
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert_norealloc_(const sync::steady_clock::time_point& ts, const CUDT* u);// REQUIRES(m_ListLock);
|
||||
|
||||
/// Insert a new UDT instance into the list without realloc.
|
||||
/// Should be called if there is a gauranteed space for the element.
|
||||
///
|
||||
/// @param [in] ts time stamp: next processing time
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert_norealloc_(int64_t ts, const CUDT* u);
|
||||
|
||||
void remove_(const CUDT* u);
|
||||
/// Removes CUDT entry from the list.
|
||||
/// If the last entry is removed, calls sync::CTimer::interrupt().
|
||||
void remove_(const CUDT* u);
|
||||
|
||||
private:
|
||||
CSNode** m_pHeap; // The heap array
|
||||
int m_iArrayLength; // physical length of the array
|
||||
int m_iLastEntry; // position of last entry on the heap array
|
||||
CSNode** m_pHeap; // The heap array
|
||||
int m_iArrayLength; // physical length of the array
|
||||
int m_iLastEntry; // position of last entry on the heap array or -1 if empty.
|
||||
|
||||
pthread_mutex_t m_ListLock;
|
||||
mutable sync::Mutex m_ListLock; // Protects the list (m_pHeap, m_iArrayLength, m_iLastEntry).
|
||||
mutable sync::Condition m_ListCond;
|
||||
|
||||
pthread_mutex_t* m_pWindowLock;
|
||||
pthread_cond_t* m_pWindowCond;
|
||||
|
||||
CTimer* m_pTimer;
|
||||
sync::CTimer* const m_pTimer;
|
||||
|
||||
private:
|
||||
CSndUList(const CSndUList&);
|
||||
CSndUList& operator=(const CSndUList&);
|
||||
CSndUList(const CSndUList&);
|
||||
CSndUList& operator=(const CSndUList&);
|
||||
};
|
||||
|
||||
struct CRNode
|
||||
{
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
uint64_t m_llTimeStamp_tk; // Time Stamp
|
||||
CUDT* m_pUDT; // Pointer to the instance of CUDT socket
|
||||
sync::steady_clock::time_point m_tsTimeStamp; // Time Stamp
|
||||
|
||||
CRNode* m_pPrev; // previous link
|
||||
CRNode* m_pNext; // next link
|
||||
CRNode* m_pPrev; // previous link
|
||||
CRNode* m_pNext; // next link
|
||||
|
||||
bool m_bOnList; // if the node is already on the list
|
||||
sync::atomic<bool> m_bOnList; // if the node is already on the list
|
||||
};
|
||||
|
||||
class CRcvUList
|
||||
{
|
||||
public:
|
||||
CRcvUList();
|
||||
~CRcvUList();
|
||||
CRcvUList();
|
||||
~CRcvUList();
|
||||
|
||||
public:
|
||||
/// Insert a new UDT instance to the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
/// Insert a new UDT instance to the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert(const CUDT* u);
|
||||
|
||||
void insert(const CUDT* u);
|
||||
/// Remove the UDT instance from the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
/// Remove the UDT instance from the list.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void remove(const CUDT* u);
|
||||
|
||||
void remove(const CUDT* u);
|
||||
/// Move the UDT instance to the end of the list, if it already exists; otherwise, do nothing.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
/// Move the UDT instance to the end of the list, if it already exists; otherwise, do nothing.
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
void update(const CUDT* u);
|
||||
void update(const CUDT* u);
|
||||
|
||||
public:
|
||||
CRNode* m_pUList; // the head node
|
||||
CRNode* m_pUList; // the head node
|
||||
|
||||
private:
|
||||
CRNode* m_pLast; // the last node
|
||||
CRNode* m_pLast; // the last node
|
||||
|
||||
private:
|
||||
CRcvUList(const CRcvUList&);
|
||||
CRcvUList& operator=(const CRcvUList&);
|
||||
CRcvUList(const CRcvUList&);
|
||||
CRcvUList& operator=(const CRcvUList&);
|
||||
};
|
||||
|
||||
class CHash
|
||||
{
|
||||
public:
|
||||
CHash();
|
||||
~CHash();
|
||||
CHash();
|
||||
~CHash();
|
||||
|
||||
public:
|
||||
/// Initialize the hash table.
|
||||
/// @param [in] size hash table size
|
||||
|
||||
/// Initialize the hash table.
|
||||
/// @param [in] size hash table size
|
||||
void init(int size);
|
||||
|
||||
void init(int size);
|
||||
/// Look for a UDT instance from the hash table.
|
||||
/// @param [in] id socket ID
|
||||
/// @return Pointer to a UDT instance, or NULL if not found.
|
||||
|
||||
/// Look for a UDT instance from the hash table.
|
||||
/// @param [in] id socket ID
|
||||
/// @return Pointer to a UDT instance, or NULL if not found.
|
||||
CUDT* lookup(int32_t id);
|
||||
|
||||
CUDT* lookup(int32_t id);
|
||||
/// Insert an entry to the hash table.
|
||||
/// @param [in] id socket ID
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
|
||||
/// Insert an entry to the hash table.
|
||||
/// @param [in] id socket ID
|
||||
/// @param [in] u pointer to the UDT instance
|
||||
void insert(int32_t id, CUDT* u);
|
||||
|
||||
void insert(int32_t id, CUDT* u);
|
||||
/// Remove an entry from the hash table.
|
||||
/// @param [in] id socket ID
|
||||
|
||||
/// Remove an entry from the hash table.
|
||||
/// @param [in] id socket ID
|
||||
|
||||
void remove(int32_t id);
|
||||
void remove(int32_t id);
|
||||
|
||||
private:
|
||||
struct CBucket
|
||||
{
|
||||
int32_t m_iID; // Socket ID
|
||||
CUDT* m_pUDT; // Socket instance
|
||||
struct CBucket
|
||||
{
|
||||
int32_t m_iID; // Socket ID
|
||||
CUDT* m_pUDT; // Socket instance
|
||||
|
||||
CBucket* m_pNext; // next bucket
|
||||
} **m_pBucket; // list of buckets (the hash table)
|
||||
CBucket* m_pNext; // next bucket
|
||||
} * *m_pBucket; // list of buckets (the hash table)
|
||||
|
||||
int m_iHashSize; // size of hash table
|
||||
int m_iHashSize; // size of hash table
|
||||
|
||||
private:
|
||||
CHash(const CHash&);
|
||||
CHash& operator=(const CHash&);
|
||||
CHash(const CHash&);
|
||||
CHash& operator=(const CHash&);
|
||||
};
|
||||
|
||||
/// @brief A queue of sockets pending for connection.
|
||||
/// It can be either a caller socket in a non-blocking mode
|
||||
/// (the connection has to be handled in background),
|
||||
/// or a socket in rendezvous connection mode.
|
||||
class CRendezvousQueue
|
||||
{
|
||||
public:
|
||||
CRendezvousQueue();
|
||||
~CRendezvousQueue();
|
||||
CRendezvousQueue();
|
||||
~CRendezvousQueue();
|
||||
|
||||
public:
|
||||
void insert(const SRTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl);
|
||||
/// @brief Insert a new socket pending for connection (non-blocking caller or rendezvous).
|
||||
/// @param id socket ID.
|
||||
/// @param u pointer to a corresponding CUDT instance.
|
||||
/// @param addr remote address to connect to.
|
||||
/// @param ttl timepoint for connection attempt to expire.
|
||||
void insert(const SRTSOCKET& id, CUDT* u, const sockaddr_any& addr, const srt::sync::steady_clock::time_point& ttl);
|
||||
|
||||
// The should_lock parameter is given here to state as to whether
|
||||
// the lock should be applied here. If called from some internals
|
||||
// and the lock IS ALREADY APPLIED, use false here to prevent
|
||||
// double locking and deadlock in result.
|
||||
void remove(const SRTSOCKET& id, bool should_lock);
|
||||
CUDT* retrieve(const sockaddr* addr, ref_t<SRTSOCKET> id);
|
||||
/// @brief Remove a socket from the connection pending list.
|
||||
/// @param id socket ID.
|
||||
void remove(const SRTSOCKET& id);
|
||||
|
||||
void updateConnStatus(EReadStatus rst, EConnectStatus, const CPacket& response);
|
||||
/// @brief Locate a socket in the connection pending queue.
|
||||
/// @param addr source address of the packet received over UDP (peer address).
|
||||
/// @param id socket ID.
|
||||
/// @return a pointer to CUDT instance retrieved, or NULL if nothing was found.
|
||||
CUDT* retrieve(const sockaddr_any& addr, SRTSOCKET& id) const;
|
||||
|
||||
/// @brief Update status of connections in the pending queue.
|
||||
/// Stop connecting if TTL expires. Resend handshake request every 250 ms if no response from the peer.
|
||||
/// @param rst result of reading from a UDP socket: received packet / nothin read / read error.
|
||||
/// @param cst target status for pending connection: reject or proceed.
|
||||
/// @param pktIn packet received from the UDP socket.
|
||||
void updateConnStatus(EReadStatus rst, EConnectStatus cst, CUnit* unit);
|
||||
|
||||
private:
|
||||
struct CRL
|
||||
{
|
||||
SRTSOCKET m_iID; // UDT socket ID (self)
|
||||
CUDT* m_pUDT; // UDT instance
|
||||
int m_iIPversion; // IP version
|
||||
sockaddr* m_pPeerAddr; // UDT sonnection peer address
|
||||
uint64_t m_ullTTL; // the time that this request expires
|
||||
};
|
||||
std::list<CRL> m_lRendezvousID; // The sockets currently in rendezvous mode
|
||||
struct LinkStatusInfo
|
||||
{
|
||||
CUDT* u;
|
||||
SRTSOCKET id;
|
||||
int errorcode;
|
||||
sockaddr_any peeraddr;
|
||||
int token;
|
||||
|
||||
pthread_mutex_t m_RIDVectorLock;
|
||||
struct HasID
|
||||
{
|
||||
SRTSOCKET id;
|
||||
HasID(SRTSOCKET p)
|
||||
: id(p)
|
||||
{
|
||||
}
|
||||
bool operator()(const LinkStatusInfo& i) { return i.id == id; }
|
||||
};
|
||||
};
|
||||
|
||||
/// @brief Qualify pending connections:
|
||||
/// - Sockets with expired TTL go to the 'to_remove' list and removed from the queue straight away.
|
||||
/// - If HS request is to be resent (resend 250 ms if no response from the peer) go to the 'to_process' list.
|
||||
///
|
||||
/// @param rst result of reading from a UDP socket: received packet / nothin read / read error.
|
||||
/// @param cst target status for pending connection: reject or proceed.
|
||||
/// @param iDstSockID destination socket ID of the received packet.
|
||||
/// @param[in,out] toRemove stores sockets with expired TTL.
|
||||
/// @param[in,out] toProcess stores sockets which should repeat (resend) HS connection request.
|
||||
bool qualifyToHandle(EReadStatus rst,
|
||||
EConnectStatus cst,
|
||||
int iDstSockID,
|
||||
std::vector<LinkStatusInfo>& toRemove,
|
||||
std::vector<LinkStatusInfo>& toProcess);
|
||||
|
||||
private:
|
||||
struct CRL
|
||||
{
|
||||
SRTSOCKET m_iID; // SRT socket ID (self)
|
||||
CUDT* m_pUDT; // CUDT instance
|
||||
sockaddr_any m_PeerAddr; // SRT sonnection peer address
|
||||
sync::steady_clock::time_point m_tsTTL; // the time that this request expires
|
||||
};
|
||||
std::list<CRL> m_lRendezvousID; // The sockets currently in rendezvous mode
|
||||
|
||||
mutable sync::Mutex m_RIDListLock;
|
||||
};
|
||||
|
||||
class CSndQueue
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
|
||||
public:
|
||||
CSndQueue();
|
||||
~CSndQueue();
|
||||
CSndQueue();
|
||||
~CSndQueue();
|
||||
|
||||
public:
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the queue is currently working for. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the queue is currently working for. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
/// Initialize the sending queue.
|
||||
/// @param [in] c UDP channel to be associated to the queue
|
||||
/// @param [in] t Timer
|
||||
|
||||
/// Initialize the sending queue.
|
||||
/// @param [in] c UDP channel to be associated to the queue
|
||||
/// @param [in] t Timer
|
||||
void init(CChannel* c, sync::CTimer* t);
|
||||
|
||||
void init(CChannel* c, CTimer* t);
|
||||
/// Send out a packet to a given address.
|
||||
/// @param [in] addr destination address
|
||||
/// @param [in] packet packet to be sent out
|
||||
/// @return Size of data sent out.
|
||||
|
||||
/// Send out a packet to a given address.
|
||||
/// @param [in] addr destination address
|
||||
/// @param [in] packet packet to be sent out
|
||||
/// @return Size of data sent out.
|
||||
int sendto(const sockaddr_any& addr, CPacket& packet);
|
||||
|
||||
int sendto(const sockaddr* addr, CPacket& packet);
|
||||
/// Get the IP TTL.
|
||||
/// @param [in] ttl IP Time To Live.
|
||||
/// @return TTL.
|
||||
|
||||
#ifdef SRT_ENABLE_IPOPTS
|
||||
/// Get the IP TTL.
|
||||
/// @param [in] ttl IP Time To Live.
|
||||
/// @return TTL.
|
||||
int getIpTTL() const;
|
||||
|
||||
int getIpTTL() const;
|
||||
/// Get the IP Type of Service.
|
||||
/// @return ToS.
|
||||
|
||||
/// Get the IP Type of Service.
|
||||
/// @return ToS.
|
||||
int getIpToS() const;
|
||||
|
||||
int getIpToS() const;
|
||||
#ifdef SRT_ENABLE_BINDTODEVICE
|
||||
bool getBind(char* dst, size_t len) const;
|
||||
#endif
|
||||
|
||||
int ioctlQuery(int type) const { return m_pChannel->ioctlQuery(type); }
|
||||
int sockoptQuery(int level, int type) const { return m_pChannel->sockoptQuery(level, type); }
|
||||
int ioctlQuery(int type) const;
|
||||
int sockoptQuery(int level, int type) const;
|
||||
|
||||
void setClosing()
|
||||
{
|
||||
m_bClosing = true;
|
||||
}
|
||||
void setClosing() { m_bClosing = true; }
|
||||
|
||||
private:
|
||||
static void* worker(void* param);
|
||||
pthread_t m_WorkerThread;
|
||||
|
||||
static void* worker(void* param);
|
||||
sync::CThread m_WorkerThread;
|
||||
|
||||
private:
|
||||
CSndUList* m_pSndUList; // List of UDT instances for data sending
|
||||
CChannel* m_pChannel; // The UDP channel for data sending
|
||||
CTimer* m_pTimer; // Timing facility
|
||||
CSndUList* m_pSndUList; // List of UDT instances for data sending
|
||||
CChannel* m_pChannel; // The UDP channel for data sending
|
||||
sync::CTimer* m_pTimer; // Timing facility
|
||||
|
||||
pthread_mutex_t m_WindowLock;
|
||||
pthread_cond_t m_WindowCond;
|
||||
sync::atomic<bool> m_bClosing; // closing the worker
|
||||
|
||||
volatile bool m_bClosing; // closing the worker
|
||||
|
||||
#if defined(SRT_DEBUG_SNDQ_HIGHRATE)//>>debug high freq worker
|
||||
uint64_t m_ullDbgPeriod;
|
||||
uint64_t m_ullDbgTime;
|
||||
struct {
|
||||
#if defined(SRT_DEBUG_SNDQ_HIGHRATE) //>>debug high freq worker
|
||||
uint64_t m_ullDbgPeriod;
|
||||
uint64_t m_ullDbgTime;
|
||||
struct
|
||||
{
|
||||
unsigned long lIteration; //
|
||||
unsigned long lSleepTo; //SleepTo
|
||||
unsigned long lNotReadyPop; //Continue
|
||||
unsigned long lSleepTo; // SleepTo
|
||||
unsigned long lNotReadyPop; // Continue
|
||||
unsigned long lSendTo;
|
||||
unsigned long lNotReadyTs;
|
||||
unsigned long lCondWait; //block on m_WindowCond
|
||||
} m_WorkerStats;
|
||||
unsigned long lNotReadyTs;
|
||||
unsigned long lCondWait; // block on m_WindowCond
|
||||
} m_WorkerStats;
|
||||
#endif /* SRT_DEBUG_SNDQ_HIGHRATE */
|
||||
|
||||
#if ENABLE_LOGGING
|
||||
static int m_counter;
|
||||
#endif
|
||||
|
||||
private:
|
||||
CSndQueue(const CSndQueue&);
|
||||
CSndQueue& operator=(const CSndQueue&);
|
||||
CSndQueue(const CSndQueue&);
|
||||
CSndQueue& operator=(const CSndQueue&);
|
||||
};
|
||||
|
||||
class CRcvQueue
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
friend class CUDT;
|
||||
friend class CUDTUnited;
|
||||
|
||||
public:
|
||||
CRcvQueue();
|
||||
~CRcvQueue();
|
||||
CRcvQueue();
|
||||
~CRcvQueue();
|
||||
|
||||
public:
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the queue is currently working. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
|
||||
// XXX There's currently no way to access the socket ID set for
|
||||
// whatever the queue is currently working. Required to find
|
||||
// some way to do this, possibly by having a "reverse pointer".
|
||||
// Currently just "unimplemented".
|
||||
std::string CONID() const { return ""; }
|
||||
/// Initialize the receiving queue.
|
||||
/// @param [in] size queue size
|
||||
/// @param [in] mss maximum packet size
|
||||
/// @param [in] version IP version
|
||||
/// @param [in] hsize hash table size
|
||||
/// @param [in] c UDP channel to be associated to the queue
|
||||
/// @param [in] t timer
|
||||
void init(int size, size_t payload, int version, int hsize, CChannel* c, sync::CTimer* t);
|
||||
|
||||
/// Initialize the receiving queue.
|
||||
/// @param [in] size queue size
|
||||
/// @param [in] mss maximum packet size
|
||||
/// @param [in] version IP version
|
||||
/// @param [in] hsize hash table size
|
||||
/// @param [in] c UDP channel to be associated to the queue
|
||||
/// @param [in] t timer
|
||||
/// Read a packet for a specific UDT socket id.
|
||||
/// @param [in] id Socket ID
|
||||
/// @param [out] packet received packet
|
||||
/// @return Data size of the packet
|
||||
int recvfrom(int32_t id, CPacket& to_packet);
|
||||
|
||||
void init(int size, int payload, int version, int hsize, CChannel* c, CTimer* t);
|
||||
void stopWorker();
|
||||
|
||||
/// Read a packet for a specific UDT socket id.
|
||||
/// @param [in] id Socket ID
|
||||
/// @param [out] packet received packet
|
||||
/// @return Data size of the packet
|
||||
void setClosing() { m_bClosing = true; }
|
||||
|
||||
int recvfrom(int32_t id, ref_t<CPacket> packet);
|
||||
|
||||
void setClosing()
|
||||
{
|
||||
m_bClosing = true;
|
||||
}
|
||||
int getIPversion() { return m_iIPversion; }
|
||||
|
||||
private:
|
||||
static void* worker(void* param);
|
||||
pthread_t m_WorkerThread;
|
||||
// Subroutines of worker
|
||||
EReadStatus worker_RetrieveUnit(ref_t<int32_t> id, ref_t<CUnit*> unit, sockaddr* sa);
|
||||
EConnectStatus worker_ProcessConnectionRequest(CUnit* unit, const sockaddr* sa);
|
||||
EConnectStatus worker_TryAsyncRend_OrStore(int32_t id, CUnit* unit, const sockaddr* sa);
|
||||
EConnectStatus worker_ProcessAddressedPacket(int32_t id, CUnit* unit, const sockaddr* sa);
|
||||
static void* worker(void* param);
|
||||
sync::CThread m_WorkerThread;
|
||||
// Subroutines of worker
|
||||
EReadStatus worker_RetrieveUnit(int32_t& id, CUnit*& unit, sockaddr_any& sa);
|
||||
EConnectStatus worker_ProcessConnectionRequest(CUnit* unit, const sockaddr_any& sa);
|
||||
EConnectStatus worker_TryAsyncRend_OrStore(int32_t id, CUnit* unit, const sockaddr_any& sa);
|
||||
EConnectStatus worker_ProcessAddressedPacket(int32_t id, CUnit* unit, const sockaddr_any& sa);
|
||||
|
||||
private:
|
||||
CUnitQueue m_UnitQueue; // The received packet queue
|
||||
CUnitQueue* m_pUnitQueue; // The received packet queue
|
||||
CRcvUList* m_pRcvUList; // List of UDT instances that will read packets from the queue
|
||||
CHash* m_pHash; // Hash table for UDT socket looking up
|
||||
CChannel* m_pChannel; // UDP channel for receving packets
|
||||
sync::CTimer* m_pTimer; // shared timer with the snd queue
|
||||
|
||||
CRcvUList* m_pRcvUList; // List of UDT instances that will read packets from the queue
|
||||
CHash* m_pHash; // Hash table for UDT socket looking up
|
||||
CChannel* m_pChannel; // UDP channel for receving packets
|
||||
CTimer* m_pTimer; // shared timer with the snd queue
|
||||
int m_iIPversion; // IP version
|
||||
size_t m_szPayloadSize; // packet payload size
|
||||
|
||||
int m_iPayloadSize; // packet payload size
|
||||
|
||||
volatile bool m_bClosing; // closing the worker
|
||||
sync::atomic<bool> m_bClosing; // closing the worker
|
||||
#if ENABLE_LOGGING
|
||||
static srt::sync::atomic<int> m_counter; // A static counter to log RcvQueue worker thread number.
|
||||
#endif
|
||||
|
||||
private:
|
||||
int setListener(CUDT* u);
|
||||
void removeListener(const CUDT* u);
|
||||
int setListener(CUDT* u);
|
||||
void removeListener(const CUDT* u);
|
||||
|
||||
void registerConnector(const SRTSOCKET& id, CUDT* u, int ipv, const sockaddr* addr, uint64_t ttl);
|
||||
void removeConnector(const SRTSOCKET& id, bool should_lock = true);
|
||||
void registerConnector(const SRTSOCKET& id,
|
||||
CUDT* u,
|
||||
const sockaddr_any& addr,
|
||||
const sync::steady_clock::time_point& ttl);
|
||||
void removeConnector(const SRTSOCKET& id);
|
||||
|
||||
void setNewEntry(CUDT* u);
|
||||
bool ifNewEntry();
|
||||
CUDT* getNewEntry();
|
||||
void setNewEntry(CUDT* u);
|
||||
bool ifNewEntry();
|
||||
CUDT* getNewEntry();
|
||||
|
||||
void storePkt(int32_t id, CPacket* pkt);
|
||||
void storePkt(int32_t id, CPacket* pkt);
|
||||
|
||||
private:
|
||||
pthread_mutex_t m_LSLock;
|
||||
CUDT* m_pListener; // pointer to the (unique, if any) listening UDT entity
|
||||
CRendezvousQueue* m_pRendezvousQueue; // The list of sockets in rendezvous mode
|
||||
sync::Mutex m_LSLock;
|
||||
CUDT* m_pListener; // pointer to the (unique, if any) listening UDT entity
|
||||
CRendezvousQueue* m_pRendezvousQueue; // The list of sockets in rendezvous mode
|
||||
|
||||
std::vector<CUDT*> m_vNewEntry; // newly added entries, to be inserted
|
||||
pthread_mutex_t m_IDLock;
|
||||
std::vector<CUDT*> m_vNewEntry; // newly added entries, to be inserted
|
||||
sync::Mutex m_IDLock;
|
||||
|
||||
std::map<int32_t, std::queue<CPacket*> > m_mBuffer; // temporary buffer for rendezvous connection request
|
||||
pthread_mutex_t m_PassLock;
|
||||
pthread_cond_t m_PassCond;
|
||||
std::map<int32_t, std::queue<CPacket*> > m_mBuffer; // temporary buffer for rendezvous connection request
|
||||
sync::Mutex m_BufferLock;
|
||||
sync::Condition m_BufferCond;
|
||||
|
||||
private:
|
||||
CRcvQueue(const CRcvQueue&);
|
||||
CRcvQueue& operator=(const CRcvQueue&);
|
||||
CRcvQueue(const CRcvQueue&);
|
||||
CRcvQueue& operator=(const CRcvQueue&);
|
||||
};
|
||||
|
||||
struct CMultiplexer
|
||||
{
|
||||
CSndQueue* m_pSndQueue; // The sending queue
|
||||
CRcvQueue* m_pRcvQueue; // The receiving queue
|
||||
CChannel* m_pChannel; // The UDP channel for sending and receiving
|
||||
CTimer* m_pTimer; // The timer
|
||||
CSndQueue* m_pSndQueue; // The sending queue
|
||||
CRcvQueue* m_pRcvQueue; // The receiving queue
|
||||
CChannel* m_pChannel; // The UDP channel for sending and receiving
|
||||
sync::CTimer* m_pTimer; // The timer
|
||||
|
||||
int m_iPort; // The UDP port number of this multiplexer
|
||||
int m_iIPversion; // IP version
|
||||
#ifdef SRT_ENABLE_IPOPTS
|
||||
int m_iIpTTL;
|
||||
int m_iIpToS;
|
||||
#endif
|
||||
int m_iMSS; // Maximum Segment Size
|
||||
int m_iRefCount; // number of UDT instances that are associated with this multiplexer
|
||||
int m_iIpV6Only; // IPV6_V6ONLY option
|
||||
bool m_bReusable; // if this one can be shared with others
|
||||
int m_iPort; // The UDP port number of this multiplexer
|
||||
int m_iIPversion; // Address family (AF_INET or AF_INET6)
|
||||
int m_iRefCount; // number of UDT instances that are associated with this multiplexer
|
||||
|
||||
int m_iID; // multiplexer ID
|
||||
CSrtMuxerConfig m_mcfg;
|
||||
|
||||
int m_iID; // multiplexer ID
|
||||
|
||||
// Constructor should reset all pointers to NULL
|
||||
// to prevent dangling pointer when checking for memory alloc fails
|
||||
CMultiplexer()
|
||||
: m_pSndQueue(NULL)
|
||||
, m_pRcvQueue(NULL)
|
||||
, m_pChannel(NULL)
|
||||
, m_pTimer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void destroy();
|
||||
};
|
||||
|
||||
} // namespace srt
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue