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
269
trunk/3rdparty/srt-1-fit/srtcore/epoll.h
vendored
Executable file → Normal file
269
trunk/3rdparty/srt-1-fit/srtcore/epoll.h
vendored
Executable file → Normal file
|
@ -50,8 +50,8 @@ modified by
|
|||
Haivision Systems Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __UDT_EPOLL_H__
|
||||
#define __UDT_EPOLL_H__
|
||||
#ifndef INC_SRT_EPOLL_H
|
||||
#define INC_SRT_EPOLL_H
|
||||
|
||||
|
||||
#include <map>
|
||||
|
@ -59,8 +59,15 @@ modified by
|
|||
#include <list>
|
||||
#include "udt.h"
|
||||
|
||||
namespace srt
|
||||
{
|
||||
|
||||
struct CEPollDesc
|
||||
class CUDT;
|
||||
class CRendezvousQueue;
|
||||
class CUDTGroup;
|
||||
|
||||
|
||||
class CEPollDesc
|
||||
{
|
||||
const int m_iID; // epoll ID
|
||||
|
||||
|
@ -86,40 +93,62 @@ struct CEPollDesc
|
|||
{
|
||||
/// Events the subscriber is interested with. Only those will be
|
||||
/// regarded when updating event flags.
|
||||
int watch;
|
||||
int32_t watch;
|
||||
|
||||
/// Which events should be edge-triggered. When the event isn't
|
||||
/// mentioned in `watch`, this bit flag is disregarded. Otherwise
|
||||
/// it means that the event is to be waited for persistent state
|
||||
/// if this flag is not present here, and for edge trigger, if
|
||||
/// the flag is present here.
|
||||
int edge;
|
||||
int32_t edge;
|
||||
|
||||
/// The current persistent state. This is usually duplicated in
|
||||
/// a dedicated state object in `m_USockEventNotice`, however the state
|
||||
/// here will stay forever as is, regardless of the edge/persistent
|
||||
/// subscription mode for the event.
|
||||
int state;
|
||||
int32_t state;
|
||||
|
||||
/// The iterator to `m_USockEventNotice` container that contains the
|
||||
/// event notice object for this subscription, or the value from
|
||||
/// `nullNotice()` if there is no such object.
|
||||
enotice_t::iterator notit;
|
||||
|
||||
Wait(int sub, bool etr, enotice_t::iterator i)
|
||||
Wait(explicit_t<int32_t> sub, explicit_t<int32_t> etr, enotice_t::iterator i)
|
||||
:watch(sub)
|
||||
,edge(etr ? sub : 0)
|
||||
,edge(etr)
|
||||
,state(0)
|
||||
,notit(i)
|
||||
{
|
||||
}
|
||||
|
||||
int edgeOnly() { return edge & watch; }
|
||||
|
||||
/// Clear all flags for given direction from the notices
|
||||
/// and subscriptions, and checks if this made the event list
|
||||
/// for this watch completely empty.
|
||||
/// @param direction event type that has to be cleared
|
||||
/// @return true, if this cleared the last event (the caller
|
||||
/// want to remove the subscription for this socket)
|
||||
bool clear(int32_t direction)
|
||||
{
|
||||
if (watch & direction)
|
||||
{
|
||||
watch &= ~direction;
|
||||
edge &= ~direction;
|
||||
state &= ~direction;
|
||||
|
||||
return watch == 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<SRTSOCKET, Wait> ewatch_t;
|
||||
|
||||
private:
|
||||
#if ENABLE_HEAVY_LOGGING
|
||||
std::string DisplayEpollWatch();
|
||||
#endif
|
||||
|
||||
/// Sockets that are subscribed for events in this eid.
|
||||
ewatch_t m_USockWatchState;
|
||||
|
@ -135,7 +164,10 @@ private:
|
|||
|
||||
enotice_t::iterator nullNotice() { return m_USockEventNotice.end(); }
|
||||
|
||||
public:
|
||||
// Only CEPoll class should have access to it.
|
||||
// Guarding private access to the class is not necessary
|
||||
// within the epoll module.
|
||||
friend class CEPoll;
|
||||
|
||||
CEPollDesc(int id, int localID)
|
||||
: m_iID(id)
|
||||
|
@ -147,13 +179,13 @@ public:
|
|||
static const int32_t EF_NOCHECK_EMPTY = 1 << 0;
|
||||
static const int32_t EF_CHECK_REP = 1 << 1;
|
||||
|
||||
int32_t flags() { return m_Flags; }
|
||||
bool flags(int32_t f) { return (m_Flags & f) != 0; }
|
||||
int32_t flags() const { return m_Flags; }
|
||||
bool flags(int32_t f) const { return (m_Flags & f) != 0; }
|
||||
void set_flags(int32_t flg) { m_Flags |= flg; }
|
||||
void clr_flags(int32_t flg) { m_Flags &= ~flg; }
|
||||
|
||||
// Container accessors for ewatch_t.
|
||||
bool watch_empty() { return m_USockWatchState.empty(); }
|
||||
bool watch_empty() const { return m_USockWatchState.empty(); }
|
||||
Wait* watch_find(SRTSOCKET sock)
|
||||
{
|
||||
ewatch_t::iterator i = m_USockWatchState.find(sock);
|
||||
|
@ -165,13 +197,16 @@ public:
|
|||
// Container accessors for enotice_t.
|
||||
enotice_t::iterator enotice_begin() { return m_USockEventNotice.begin(); }
|
||||
enotice_t::iterator enotice_end() { return m_USockEventNotice.end(); }
|
||||
enotice_t::const_iterator enotice_begin() const { return m_USockEventNotice.begin(); }
|
||||
enotice_t::const_iterator enotice_end() const { return m_USockEventNotice.end(); }
|
||||
bool enotice_empty() const { return m_USockEventNotice.empty(); }
|
||||
|
||||
const int m_iLocalID; // local system epoll ID
|
||||
std::set<SYSSOCKET> m_sLocals; // set of local (non-UDT) descriptors
|
||||
|
||||
std::pair<ewatch_t::iterator, bool> addWatch(SRTSOCKET sock, int32_t events, bool edgeTrg)
|
||||
std::pair<ewatch_t::iterator, bool> addWatch(SRTSOCKET sock, explicit_t<int32_t> events, explicit_t<int32_t> et_events)
|
||||
{
|
||||
return m_USockWatchState.insert(std::make_pair(sock, Wait(events, edgeTrg, nullNotice())));
|
||||
return m_USockWatchState.insert(std::make_pair(sock, Wait(events, et_events, nullNotice())));
|
||||
}
|
||||
|
||||
void addEventNotice(Wait& wait, SRTSOCKET sock, int events)
|
||||
|
@ -224,6 +259,12 @@ public:
|
|||
m_USockWatchState.erase(i);
|
||||
}
|
||||
|
||||
void clearAll()
|
||||
{
|
||||
m_USockEventNotice.clear();
|
||||
m_USockWatchState.clear();
|
||||
}
|
||||
|
||||
void removeExistingNotices(Wait& wait)
|
||||
{
|
||||
m_USockEventNotice.erase(wait.notit);
|
||||
|
@ -281,12 +322,44 @@ public:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// This should work in a loop around the notice container of
|
||||
/// the given eid container and clear out the notice for
|
||||
/// particular event type. If this has cleared effectively the
|
||||
/// last existing event, it should return the socket id
|
||||
/// so that the caller knows to remove it also from subscribers.
|
||||
///
|
||||
/// @param i iterator in the notice container
|
||||
/// @param event event type to be cleared
|
||||
/// @retval (socket) Socket to be removed from subscriptions
|
||||
/// @retval SRT_INVALID_SOCK Nothing to be done (associated socket
|
||||
/// still has other subscriptions)
|
||||
SRTSOCKET clearEventSub(enotice_t::iterator i, int event)
|
||||
{
|
||||
// We need to remove the notice and subscription
|
||||
// for this event. The 'i' iterator is safe to
|
||||
// delete, even indirectly.
|
||||
|
||||
// This works merely like checkEdge, just on request to clear the
|
||||
// identified event, if found.
|
||||
if (i->events & event)
|
||||
{
|
||||
// The notice has a readiness flag on this event.
|
||||
// This means that there exists also a subscription.
|
||||
Wait* w = i->parent;
|
||||
if (w->clear(event))
|
||||
return i->fd;
|
||||
}
|
||||
|
||||
return SRT_INVALID_SOCK;
|
||||
}
|
||||
};
|
||||
|
||||
class CEPoll
|
||||
{
|
||||
friend class CUDT;
|
||||
friend class CRendezvousQueue;
|
||||
friend class srt::CUDT;
|
||||
friend class srt::CUDTGroup;
|
||||
friend class srt::CRendezvousQueue;
|
||||
|
||||
public:
|
||||
CEPoll();
|
||||
|
@ -294,90 +367,122 @@ public:
|
|||
|
||||
public: // for CUDTUnited API
|
||||
|
||||
/// create a new EPoll.
|
||||
/// @return new EPoll ID if success, otherwise an error number.
|
||||
/// create a new EPoll.
|
||||
/// @return new EPoll ID if success, otherwise an error number.
|
||||
int create(CEPollDesc** ppd = 0);
|
||||
|
||||
int create();
|
||||
|
||||
/// add a UDT socket to an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT Socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
/// delete all user sockets (SRT sockets) from an EPoll
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @return 0
|
||||
int clear_usocks(int eid);
|
||||
|
||||
int add_usock(const int eid, const SRTSOCKET& u, const int* events = NULL) { return update_usock(eid, u, events); }
|
||||
|
||||
/// add a system socket to an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] s system Socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
/// add a system socket to an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] s system Socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int add_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL);
|
||||
|
||||
/// remove a UDT socket event from an EPoll; socket will be removed if no events to watch.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT socket ID.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int remove_usock(const int eid, const SRTSOCKET& u) { static const int Null(0); return update_usock(eid, u, &Null);}
|
||||
|
||||
/// remove a system socket event from an EPoll; socket will be removed if no events to watch.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] s system socket ID.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
/// remove a system socket event from an EPoll; socket will be removed if no events to watch.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] s system socket ID.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int remove_ssock(const int eid, const SYSSOCKET& s);
|
||||
/// update a UDT socket events from an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
/// update a UDT socket events from an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int update_usock(const int eid, const SRTSOCKET& u, const int* events);
|
||||
|
||||
/// update a system socket events from an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
/// update a system socket events from an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [in] u UDT socket ID.
|
||||
/// @param [in] events events to watch.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int update_ssock(const int eid, const SYSSOCKET& s, const int* events = NULL);
|
||||
|
||||
/// wait for EPoll events or timeout.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [out] readfds UDT sockets available for reading.
|
||||
/// @param [out] writefds UDT sockets available for writing.
|
||||
/// @param [in] msTimeOut timeout threshold, in milliseconds.
|
||||
/// @param [out] lrfds system file descriptors for reading.
|
||||
/// @param [out] lwfds system file descriptors for writing.
|
||||
/// @return number of sockets available for IO.
|
||||
/// wait for EPoll events or timeout.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [out] readfds UDT sockets available for reading.
|
||||
/// @param [out] writefds UDT sockets available for writing.
|
||||
/// @param [in] msTimeOut timeout threshold, in milliseconds.
|
||||
/// @param [out] lrfds system file descriptors for reading.
|
||||
/// @param [out] lwfds system file descriptors for writing.
|
||||
/// @return number of sockets available for IO.
|
||||
|
||||
int wait(const int eid, std::set<SRTSOCKET>* readfds, std::set<SRTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds, std::set<SYSSOCKET>* lwfds);
|
||||
|
||||
/// wait for EPoll events or timeout optimized with explicit EPOLL_ERR event and the edge mode option.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [out] fdsSet array of user socket events (SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR).
|
||||
/// @param [int] fdsSize of fds array
|
||||
/// @param [in] msTimeOut timeout threshold, in milliseconds.
|
||||
/// @return total of available events in the epoll system (can be greater than fdsSize)
|
||||
typedef std::map<SRTSOCKET, int> fmap_t;
|
||||
|
||||
/// Lightweit and more internal-reaching version of `uwait` for internal use only.
|
||||
/// This function wait for sockets to be ready and reports them in `st` map.
|
||||
///
|
||||
/// @param d the internal structure of the epoll container
|
||||
/// @param st output container for the results: { socket_type, event }
|
||||
/// @param msTimeOut timeout after which return with empty output is allowed
|
||||
/// @param report_by_exception if true, errors will result in exception intead of returning -1
|
||||
/// @retval -1 error occurred
|
||||
/// @retval >=0 number of ready sockets (actually size of `st`)
|
||||
int swait(CEPollDesc& d, fmap_t& st, int64_t msTimeOut, bool report_by_exception = true);
|
||||
|
||||
/// Empty subscription check - for internal use only.
|
||||
bool empty(const CEPollDesc& d) const;
|
||||
|
||||
/// Reports which events are ready on the given socket.
|
||||
/// @param mp socket event map retirned by `swait`
|
||||
/// @param sock which socket to ask
|
||||
/// @return event flags for given socket, or 0 if none
|
||||
static int ready(const fmap_t& mp, SRTSOCKET sock)
|
||||
{
|
||||
fmap_t::const_iterator y = mp.find(sock);
|
||||
if (y == mp.end())
|
||||
return 0;
|
||||
return y->second;
|
||||
}
|
||||
|
||||
/// Reports whether socket is ready for given event.
|
||||
/// @param mp socket event map retirned by `swait`
|
||||
/// @param sock which socket to ask
|
||||
/// @param event which events it should be ready for
|
||||
/// @return true if the given socket is ready for given event
|
||||
static bool isready(const fmap_t& mp, SRTSOCKET sock, SRT_EPOLL_OPT event)
|
||||
{
|
||||
return (ready(mp, sock) & event) != 0;
|
||||
}
|
||||
|
||||
// Could be a template directly, but it's now hidden in the imp file.
|
||||
void clear_ready_usocks(CEPollDesc& d, int direction);
|
||||
|
||||
/// wait for EPoll events or timeout optimized with explicit EPOLL_ERR event and the edge mode option.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @param [out] fdsSet array of user socket events (SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR).
|
||||
/// @param [int] fdsSize of fds array
|
||||
/// @param [in] msTimeOut timeout threshold, in milliseconds.
|
||||
/// @return total of available events in the epoll system (can be greater than fdsSize)
|
||||
|
||||
int uwait(const int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut);
|
||||
|
||||
/// close and release an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
/// close and release an EPoll.
|
||||
/// @param [in] eid EPoll ID.
|
||||
/// @return 0 if success, otherwise an error number.
|
||||
|
||||
int release(const int eid);
|
||||
|
||||
public: // for CUDT to acknowledge IO status
|
||||
|
||||
/// Update events available for a UDT socket.
|
||||
/// @param [in] uid UDT socket ID.
|
||||
/// @param [in] eids EPoll IDs to be set
|
||||
/// @param [in] events Combination of events to update
|
||||
/// @param [in] enable true -> enable, otherwise disable
|
||||
/// @return 0 if success, otherwise an error number
|
||||
/// Update events available for a UDT socket. At the end this function
|
||||
/// counts the number of updated EIDs with given events.
|
||||
/// @param [in] uid UDT socket ID.
|
||||
/// @param [in] eids EPoll IDs to be set
|
||||
/// @param [in] events Combination of events to update
|
||||
/// @param [in] enable true -> enable, otherwise disable
|
||||
/// @return -1 if invalid events, otherwise the number of changes
|
||||
|
||||
int update_events(const SRTSOCKET& uid, std::set<int>& eids, int events, bool enable);
|
||||
|
||||
|
@ -385,11 +490,17 @@ public: // for CUDT to acknowledge IO status
|
|||
|
||||
private:
|
||||
int m_iIDSeed; // seed to generate a new ID
|
||||
pthread_mutex_t m_SeedLock;
|
||||
srt::sync::Mutex m_SeedLock;
|
||||
|
||||
std::map<int, CEPollDesc> m_mPolls; // all epolls
|
||||
pthread_mutex_t m_EPollLock;
|
||||
mutable srt::sync::Mutex m_EPollLock;
|
||||
};
|
||||
|
||||
#if ENABLE_HEAVY_LOGGING
|
||||
std::string DisplayEpollResults(const std::map<SRTSOCKET, int>& sockset);
|
||||
#endif
|
||||
|
||||
} // namespace srt
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue