mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	fix https://github.com/ossrs/srs/issues/3155 Build srt-1-fit fails with `standard attributes in middle of decl-specifiers` on GCC 12,Arch Linux. See https://github.com/Haivision/srt/releases/tag/v1.5.3
		
			
				
	
	
		
			603 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			603 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * 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/.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| /*****************************************************************************
 | |
| Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
 | |
| All rights reserved.
 | |
| 
 | |
| Redistribution and use in source and binary forms, with or without
 | |
| modification, are permitted provided that the following conditions are
 | |
| met:
 | |
| 
 | |
| * Redistributions of source code must retain the above
 | |
|   copyright notice, this list of conditions and the
 | |
|   following disclaimer.
 | |
| 
 | |
| * Redistributions in binary form must reproduce the
 | |
|   above copyright notice, this list of conditions
 | |
|   and the following disclaimer in the documentation
 | |
|   and/or other materials provided with the distribution.
 | |
| 
 | |
| * Neither the name of the University of Illinois
 | |
|   nor the names of its contributors may be used to
 | |
|   endorse or promote products derived from this
 | |
|   software without specific prior written permission.
 | |
| 
 | |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 | |
| IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | |
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | |
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | |
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | |
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | |
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| *****************************************************************************/
 | |
| 
 | |
| /*****************************************************************************
 | |
| written by
 | |
|    Yunhong Gu, last updated 01/12/2011
 | |
| modified by
 | |
|    Haivision Systems Inc.
 | |
| *****************************************************************************/
 | |
| 
 | |
| #ifndef INC_SRT_QUEUE_H
 | |
| #define INC_SRT_QUEUE_H
 | |
| 
 | |
| #include "common.h"
 | |
| #include "packet.h"
 | |
| #include "socketconfig.h"
 | |
| #include "netinet_any.h"
 | |
| #include "utilities.h"
 | |
| #include <list>
 | |
| #include <map>
 | |
| #include <queue>
 | |
| #include <vector>
 | |
| 
 | |
| namespace srt
 | |
| {
 | |
| class CChannel;
 | |
| class CUDT;
 | |
| 
 | |
| struct CUnit
 | |
| {
 | |
|     CPacket m_Packet; // packet
 | |
|     sync::atomic<bool> m_bTaken; // true if the unit is is use (can be stored in the RCV buffer).
 | |
| };
 | |
| 
 | |
| 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:
 | |
|     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();
 | |
| 
 | |
|     void makeUnitFree(CUnit* unit);
 | |
| 
 | |
|     void makeUnitTaken(CUnit* unit);
 | |
| 
 | |
| private:
 | |
|     struct CQEntry
 | |
|     {
 | |
|         CUnit* m_pUnit;   // unit queue
 | |
|         char*  m_pBuffer; // data buffer
 | |
|         int    m_iSize;   // size of each queue
 | |
| 
 | |
|         CQEntry* m_pNext;
 | |
|     };
 | |
| 
 | |
|     /// 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_();
 | |
| 
 | |
|     /// @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:
 | |
|     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
 | |
|     sync::steady_clock::time_point m_tsTimeStamp;
 | |
| 
 | |
|     sync::atomic<int> m_iHeapLoc; // location on the heap, -1 means not on the heap
 | |
| };
 | |
| 
 | |
| class CSndUList
 | |
| {
 | |
| public:
 | |
|     CSndUList(sync::CTimer* pTimer);
 | |
|     ~CSndUList();
 | |
| 
 | |
| public:
 | |
|     enum EReschedule
 | |
|     {
 | |
|         DONT_RESCHEDULE = 0,
 | |
|         DO_RESCHEDULE   = 1
 | |
|     };
 | |
| 
 | |
|     static EReschedule rescheduleIf(bool cond) { return cond ? DO_RESCHEDULE : DONT_RESCHEDULE; }
 | |
| 
 | |
|     /// 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());
 | |
| 
 | |
|     /// 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();
 | |
| 
 | |
|     /// Remove UDT instance from the list.
 | |
|     /// @param [in] u pointer to the UDT instance
 | |
|     void remove(const CUDT* u);// EXCLUDES(m_ListLock);
 | |
| 
 | |
|     /// Retrieve the next scheduled processing time.
 | |
|     /// @return Scheduled processing time of the first UDT socket in the list.
 | |
|     sync::steady_clock::time_point getNextProcTime();
 | |
| 
 | |
|     /// Wait for the list to become non empty.
 | |
|     void waitNonEmpty() const;
 | |
| 
 | |
|     /// Signal to stop waiting in waitNonEmpty().
 | |
|     void signalInterrupt() const;
 | |
| 
 | |
| private:
 | |
|     /// Doubles the size of the list.
 | |
|     ///
 | |
|     void realloc_();// REQUIRES(m_ListLock);
 | |
| 
 | |
|     /// 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 without realloc.
 | |
|     /// Should be called if there is a guaranteed 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);
 | |
| 
 | |
|     /// 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 or -1 if empty.
 | |
| 
 | |
|     mutable sync::Mutex     m_ListLock; // Protects the list (m_pHeap, m_iArrayLength, m_iLastEntry).
 | |
|     mutable sync::Condition m_ListCond;
 | |
| 
 | |
|     sync::CTimer* const m_pTimer;
 | |
| 
 | |
| private:
 | |
|     CSndUList(const CSndUList&);
 | |
|     CSndUList& operator=(const CSndUList&);
 | |
| };
 | |
| 
 | |
| struct CRNode
 | |
| {
 | |
|     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
 | |
| 
 | |
|     sync::atomic<bool> m_bOnList; // if the node is already on the list
 | |
| };
 | |
| 
 | |
| class CRcvUList
 | |
| {
 | |
| public:
 | |
|     CRcvUList();
 | |
|     ~CRcvUList();
 | |
| 
 | |
| public:
 | |
|     /// Insert a new UDT instance to the list.
 | |
|     /// @param [in] u pointer to the UDT instance
 | |
| 
 | |
|     void insert(const CUDT* u);
 | |
| 
 | |
|     /// Remove the UDT instance from the list.
 | |
|     /// @param [in] u pointer to the UDT instance
 | |
| 
 | |
|     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
 | |
| 
 | |
|     void update(const CUDT* u);
 | |
| 
 | |
| public:
 | |
|     CRNode* m_pUList; // the head node
 | |
| 
 | |
| private:
 | |
|     CRNode* m_pLast; // the last node
 | |
| 
 | |
| private:
 | |
|     CRcvUList(const CRcvUList&);
 | |
|     CRcvUList& operator=(const CRcvUList&);
 | |
| };
 | |
| 
 | |
| class CHash
 | |
| {
 | |
| public:
 | |
|     CHash();
 | |
|     ~CHash();
 | |
| 
 | |
| public:
 | |
|     /// Initialize the hash table.
 | |
|     /// @param [in] size hash table 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.
 | |
| 
 | |
|     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
 | |
| 
 | |
|     void insert(int32_t id, CUDT* u);
 | |
| 
 | |
|     /// Remove an entry from the hash table.
 | |
|     /// @param [in] id socket ID
 | |
| 
 | |
|     void remove(int32_t id);
 | |
| 
 | |
| private:
 | |
|     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)
 | |
| 
 | |
|     int m_iHashSize; // size of hash table
 | |
| 
 | |
| private:
 | |
|     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();
 | |
| 
 | |
| public:
 | |
|     /// @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);
 | |
| 
 | |
|     /// @brief Remove a socket from the connection pending list.
 | |
|     /// @param id socket ID.
 | |
|     void remove(const SRTSOCKET& id);
 | |
| 
 | |
|     /// @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 LinkStatusInfo
 | |
|     {
 | |
|         CUDT*        u;
 | |
|         SRTSOCKET    id;
 | |
|         int          errorcode;
 | |
|         sockaddr_any peeraddr;
 | |
|         int          token;
 | |
| 
 | |
|         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;
 | |
| 
 | |
| public:
 | |
|     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 ""; }
 | |
| 
 | |
|     /// 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);
 | |
| 
 | |
|     /// Send out a packet to a given address. The @a src parameter is
 | |
|     /// blindly passed by the caller down the call with intention to
 | |
|     /// be received eventually by CChannel::sendto, and used only if
 | |
|     /// appropriate conditions state so.
 | |
|     /// @param [in] addr destination address
 | |
|     /// @param [in,ref] packet packet to be sent out
 | |
|     /// @param [in] src The source IP address (details above)
 | |
|     /// @return Size of data sent out.
 | |
|     int sendto(const sockaddr_any& addr, CPacket& packet, const sockaddr_any& src);
 | |
| 
 | |
|     /// Get the IP TTL.
 | |
|     /// @param [in] ttl IP Time To Live.
 | |
|     /// @return TTL.
 | |
|     int getIpTTL() const;
 | |
| 
 | |
|     /// Get the IP Type of Service.
 | |
|     /// @return ToS.
 | |
|     int getIpToS() const;
 | |
| 
 | |
| #ifdef SRT_ENABLE_BINDTODEVICE
 | |
|     bool getBind(char* dst, size_t len) const;
 | |
| #endif
 | |
| 
 | |
|     int ioctlQuery(int type) const;
 | |
|     int sockoptQuery(int level, int type) const;
 | |
| 
 | |
|     void setClosing() { m_bClosing = true; }
 | |
| 
 | |
| private:
 | |
|     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
 | |
|     sync::CTimer* m_pTimer;    // Timing facility
 | |
| 
 | |
|     sync::atomic<bool> m_bClosing;            // closing the worker
 | |
| 
 | |
| public:
 | |
| #if defined(SRT_DEBUG_SNDQ_HIGHRATE) //>>debug high freq worker
 | |
|     sync::steady_clock::duration m_DbgPeriod;
 | |
|     mutable sync::steady_clock::time_point m_DbgTime;
 | |
|     struct
 | |
|     {
 | |
|         unsigned long lIteration;   //
 | |
|         unsigned long lSleepTo;     // SleepTo
 | |
|         unsigned long lNotReadyPop; // Continue
 | |
|         unsigned long lSendTo;
 | |
|         unsigned long lNotReadyTs;
 | |
|         unsigned long lCondWait; // block on m_WindowCond
 | |
|     } mutable m_WorkerStats;
 | |
| #endif /* SRT_DEBUG_SNDQ_HIGHRATE */
 | |
| 
 | |
| private:
 | |
| 
 | |
| #if ENABLE_LOGGING
 | |
|     static int m_counter;
 | |
| #endif
 | |
| 
 | |
|     CSndQueue(const CSndQueue&);
 | |
|     CSndQueue& operator=(const CSndQueue&);
 | |
| };
 | |
| 
 | |
| class CRcvQueue
 | |
| {
 | |
|     friend class CUDT;
 | |
|     friend class CUDTUnited;
 | |
| 
 | |
| public:
 | |
|     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 ""; }
 | |
| 
 | |
|     /// 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);
 | |
| 
 | |
|     /// 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 stopWorker();
 | |
| 
 | |
|     void setClosing() { m_bClosing = true; }
 | |
| 
 | |
|     int getIPversion() { return m_iIPversion; }
 | |
| 
 | |
| private:
 | |
|     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_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 receiving packets
 | |
|     sync::CTimer* m_pTimer;     // shared timer with the snd queue
 | |
| 
 | |
|     int m_iIPversion;           // IP version
 | |
|     size_t m_szPayloadSize;     // packet payload size
 | |
| 
 | |
|     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);
 | |
| 
 | |
|     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 storePktClone(int32_t id, const CPacket& pkt);
 | |
| 
 | |
| private:
 | |
|     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
 | |
|     sync::Mutex        m_IDLock;
 | |
| 
 | |
|     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&);
 | |
| };
 | |
| 
 | |
| struct CMultiplexer
 | |
| {
 | |
|     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; // Address family (AF_INET or AF_INET6)
 | |
|     int m_iRefCount;  // number of UDT instances that are associated with this multiplexer
 | |
| 
 | |
|     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
 |