mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
GB: Refine lazy object GC. v5.0.114 (#3321)
* GB: Refine lazy object GC. 1. Remove gc_set_creator_wrapper, pass by resource constructor. 2. Remove SRS_LAZY_WRAPPER_GENERATOR macro, use template directly. 3. Remove interfaces ISrsGbSipConn and ISrsGbSipConnWrapper. 4. Remove ISrsGbMediaConn and ISrsGbMediaConnWrapper. * GC: Refine wrapper constructor. * GB: Refine lazy object GC. v5.0.114
This commit is contained in:
parent
7eaee46f1f
commit
6f3d6b9b65
8 changed files with 104 additions and 223 deletions
|
@ -139,33 +139,69 @@ extern ISrsLazyGc* _srs_gc;
|
|||
|
||||
// A wrapper template for lazy-sweep resource.
|
||||
// See https://github.com/ossrs/srs/issues/3176#lazy-sweep
|
||||
//
|
||||
// Usage for resource which manages itself in coroutine cycle, see SrsLazyGbSession:
|
||||
// class Resource {
|
||||
// private:
|
||||
// SrsLazyObjectWrapper<Resource>* wrapper_;
|
||||
// private:
|
||||
// friend class SrsLazyObjectWrapper<Resource>;
|
||||
// Resource(SrsLazyObjectWrapper<Resource>* wrapper) { wrapper_ = wrapper; }
|
||||
// public:
|
||||
// srs_error_t Resource::cycle() {
|
||||
// srs_error_t err = do_cycle();
|
||||
// _srs_gb_manager->remove(wrapper_);
|
||||
// return err;
|
||||
// }
|
||||
// };
|
||||
// SrsLazyObjectWrapper<Resource>* obj = new SrsLazyObjectWrapper<Resource>*();
|
||||
// _srs_gb_manager->add(obj); // Add wrapper to resource manager.
|
||||
// Start a coroutine to do obj->resource()->cycle().
|
||||
//
|
||||
// Usage for resource managed by other object:
|
||||
// class Resource {
|
||||
// private:
|
||||
// friend class SrsLazyObjectWrapper<Resource>;
|
||||
// Resource(SrsLazyObjectWrapper<Resource>* /*wrapper*/) {
|
||||
// }
|
||||
// };
|
||||
// class Manager {
|
||||
// private:
|
||||
// SrsLazyObjectWrapper<Resource>* wrapper_;
|
||||
// public:
|
||||
// Manager() { wrapper_ = new SrsLazyObjectWrapper<Resource>(); }
|
||||
// ~Manager() { srs_freep(wrapper_); }
|
||||
// };
|
||||
// Manager* manager = new Manager();
|
||||
// srs_freep(manager);
|
||||
//
|
||||
// Note that under-layer resource are destroyed by _srs_gc, which is literally equal to srs_freep. However, the root
|
||||
// wrapper might be managed by other resource manager, such as _srs_gb_manager for SrsLazyGbSession. Furthermore, other
|
||||
// copied out wrappers might be freed by srs_freep. All are ok, because all wrapper and resources are simply normal
|
||||
// object, so if you added to manager then you should use manager to remove it, and you can also directly delete it.
|
||||
template<typename T>
|
||||
class SrsLazyObjectWrapper : public ISrsResource
|
||||
{
|
||||
private:
|
||||
T* resource_;
|
||||
bool is_root_;
|
||||
public:
|
||||
SrsLazyObjectWrapper(T* resource = NULL, ISrsResource* wrapper = NULL) {
|
||||
resource_ = resource ? resource : new T();
|
||||
resource_->gc_use();
|
||||
|
||||
is_root_ = !resource;
|
||||
if (!resource) {
|
||||
resource_->gc_set_creator_wrapper(wrapper ? wrapper : this);
|
||||
}
|
||||
SrsLazyObjectWrapper() {
|
||||
init(new T(this));
|
||||
}
|
||||
virtual ~SrsLazyObjectWrapper() {
|
||||
resource_->gc_dispose();
|
||||
|
||||
if (is_root_) {
|
||||
resource_->gc_set_creator_wrapper(NULL);
|
||||
}
|
||||
|
||||
if (resource_->gc_ref() == 0) {
|
||||
_srs_gc->remove(resource_);
|
||||
}
|
||||
}
|
||||
private:
|
||||
SrsLazyObjectWrapper(T* resource) {
|
||||
init(resource);
|
||||
}
|
||||
void init(T* resource) {
|
||||
resource_ = resource;
|
||||
resource_->gc_use();
|
||||
}
|
||||
public:
|
||||
SrsLazyObjectWrapper<T>* copy() {
|
||||
return new SrsLazyObjectWrapper<T>(resource_);
|
||||
|
@ -183,31 +219,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Use macro to generate a wrapper class, because typedef will cause IDE incorrect tips.
|
||||
// See https://github.com/ossrs/srs/issues/3176#lazy-sweep
|
||||
#define SRS_LAZY_WRAPPER_GENERATOR(Resource, IWrapper, IResource) \
|
||||
private: \
|
||||
SrsLazyObjectWrapper<Resource> impl_; \
|
||||
public: \
|
||||
Resource##Wrapper(Resource* resource = NULL) : impl_(resource, this) { \
|
||||
} \
|
||||
virtual ~Resource##Wrapper() { \
|
||||
} \
|
||||
public: \
|
||||
IWrapper* copy() { \
|
||||
return new Resource##Wrapper(impl_.resource()); \
|
||||
} \
|
||||
IResource* resource() { \
|
||||
return impl_.resource(); \
|
||||
} \
|
||||
public: \
|
||||
virtual const SrsContextId& get_id() { \
|
||||
return impl_.get_id(); \
|
||||
} \
|
||||
virtual std::string desc() { \
|
||||
return impl_.desc(); \
|
||||
} \
|
||||
|
||||
// If a connection is able be expired, user can use HTTP-API to kick-off it.
|
||||
class ISrsExpire
|
||||
{
|
||||
|
|
|
@ -70,42 +70,11 @@ std::string srs_sip_state(SrsGbSipState ostate, SrsGbSipState state)
|
|||
return srs_fmt("%s->%s", srs_gb_sip_state(ostate).c_str(), srs_gb_sip_state(state).c_str());
|
||||
}
|
||||
|
||||
ISrsGbSipConn::ISrsGbSipConn()
|
||||
SrsLazyGbSession::SrsLazyGbSession(SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root)
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbSipConn::~ISrsGbSipConn()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbSipConnWrapper::ISrsGbSipConnWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbSipConnWrapper::~ISrsGbSipConnWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbMediaConn::ISrsGbMediaConn()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbMediaConn::~ISrsGbMediaConn()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbMediaConnWrapper::ISrsGbMediaConnWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsGbMediaConnWrapper::~ISrsGbMediaConnWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
SrsLazyGbSession::SrsLazyGbSession()
|
||||
{
|
||||
sip_ = new ISrsGbSipConnWrapper();
|
||||
media_ = new ISrsGbMediaConnWrapper();
|
||||
wrapper_root_ = wrapper_root;
|
||||
sip_ = new SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>();
|
||||
media_ = new SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>();
|
||||
muxer_ = new SrsGbMuxer(this);
|
||||
state_ = SrsGbSessionStateInit;
|
||||
|
||||
|
@ -225,7 +194,7 @@ void SrsLazyGbSession::on_ps_pack(SrsPackContext* ctx, SrsPsPacket* ps, const st
|
|||
}
|
||||
}
|
||||
|
||||
void SrsLazyGbSession::on_sip_transport(ISrsGbSipConnWrapper* sip)
|
||||
void SrsLazyGbSession::on_sip_transport(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip)
|
||||
{
|
||||
srs_freep(sip_);
|
||||
sip_ = sip->copy();
|
||||
|
@ -234,12 +203,12 @@ void SrsLazyGbSession::on_sip_transport(ISrsGbSipConnWrapper* sip)
|
|||
sip_->resource()->set_cid(cid_);
|
||||
}
|
||||
|
||||
ISrsGbSipConnWrapper* SrsLazyGbSession::sip_transport()
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* SrsLazyGbSession::sip_transport()
|
||||
{
|
||||
return sip_;
|
||||
}
|
||||
|
||||
void SrsLazyGbSession::on_media_transport(ISrsGbMediaConnWrapper* media)
|
||||
void SrsLazyGbSession::on_media_transport(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media)
|
||||
{
|
||||
srs_freep(media_);
|
||||
media_ = media->copy();
|
||||
|
@ -273,7 +242,7 @@ srs_error_t SrsLazyGbSession::cycle()
|
|||
media_->resource()->interrupt();
|
||||
|
||||
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
|
||||
SrsLazyGbSessionWrapper* wrapper = dynamic_cast<SrsLazyGbSessionWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
|
||||
_srs_gb_manager->remove(wrapper);
|
||||
|
||||
|
@ -366,7 +335,7 @@ srs_error_t SrsLazyGbSession::drive_state()
|
|||
}
|
||||
|
||||
// Now, we're able to query session by ssrc, for media packets.
|
||||
SrsLazyGbSessionWrapper* wrapper = dynamic_cast<SrsLazyGbSessionWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine.
|
||||
_srs_gb_manager->add_with_fast_id(ssrc, wrapper);
|
||||
}
|
||||
|
@ -493,7 +462,7 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
|
|||
|
||||
// Handle TCP connections.
|
||||
if (listener == sip_listener_) {
|
||||
SrsLazyGbSipTcpConnWrapper* conn = new SrsLazyGbSipTcpConnWrapper();
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* conn = new SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>();
|
||||
SrsLazyGbSipTcpConn* resource = dynamic_cast<SrsLazyGbSipTcpConn*>(conn->resource());
|
||||
resource->setup(conf_, sip_listener_, media_listener_, stfd);
|
||||
|
||||
|
@ -504,7 +473,7 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
|
|||
|
||||
_srs_gb_manager->add(conn, NULL);
|
||||
} else if (listener == media_listener_) {
|
||||
SrsLazyGbMediaTcpConnWrapper* conn = new SrsLazyGbMediaTcpConnWrapper();
|
||||
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* conn = new SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>();
|
||||
SrsLazyGbMediaTcpConn* resource = dynamic_cast<SrsLazyGbMediaTcpConn*>(conn->resource());
|
||||
resource->setup(stfd);
|
||||
|
||||
|
@ -522,8 +491,9 @@ srs_error_t SrsGbListener::on_tcp_client(ISrsListener* listener, srs_netfd_t stf
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsLazyGbSipTcpConn::SrsLazyGbSipTcpConn()
|
||||
SrsLazyGbSipTcpConn::SrsLazyGbSipTcpConn(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root)
|
||||
{
|
||||
wrapper_root_ = wrapper_root;
|
||||
session_ = NULL;
|
||||
state_ = SrsGbSipStateInit;
|
||||
register_ = new SrsSipMessage();
|
||||
|
@ -940,7 +910,7 @@ srs_error_t SrsLazyGbSipTcpConn::cycle()
|
|||
sender_->interrupt();
|
||||
|
||||
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
|
||||
SrsLazyGbSipTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbSipTcpConnWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
|
||||
_srs_gb_manager->remove(wrapper);
|
||||
|
||||
|
@ -987,7 +957,7 @@ srs_error_t SrsLazyGbSipTcpConn::do_cycle()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyGbSessionWrapper** psession)
|
||||
srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyObjectWrapper<SrsLazyGbSession>** psession)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -998,14 +968,14 @@ srs_error_t SrsLazyGbSipTcpConn::bind_session(SrsSipMessage* msg, SrsLazyGbSessi
|
|||
if (msg->type_ != HTTP_REQUEST || msg->method_ != HTTP_REGISTER) return err;
|
||||
|
||||
// The lazy-sweep wrapper for this resource.
|
||||
SrsLazyGbSipTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbSipTcpConnWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine of receiver.
|
||||
|
||||
// Find exists session for register, might be created by another object and still alive.
|
||||
SrsLazyGbSessionWrapper* session = dynamic_cast<SrsLazyGbSessionWrapper*>(_srs_gb_manager->find_by_id(device));
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* session = dynamic_cast<SrsLazyObjectWrapper<SrsLazyGbSession>*>(_srs_gb_manager->find_by_id(device));
|
||||
if (!session) {
|
||||
// Create new GB session.
|
||||
session = new SrsLazyGbSessionWrapper();
|
||||
session = new SrsLazyObjectWrapper<SrsLazyGbSession>();
|
||||
|
||||
if ((err = session->resource()->initialize(conf_)) != srs_success) {
|
||||
srs_freep(session);
|
||||
|
@ -1248,8 +1218,9 @@ ISrsPsPackHandler::~ISrsPsPackHandler()
|
|||
{
|
||||
}
|
||||
|
||||
SrsLazyGbMediaTcpConn::SrsLazyGbMediaTcpConn()
|
||||
SrsLazyGbMediaTcpConn::SrsLazyGbMediaTcpConn(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root)
|
||||
{
|
||||
wrapper_root_ = wrapper_root;
|
||||
pack_ = new SrsPackContext(this);
|
||||
trd_ = new SrsSTCoroutine("media", this);
|
||||
buffer_ = new uint8_t[65535];
|
||||
|
@ -1324,7 +1295,7 @@ srs_error_t SrsLazyGbMediaTcpConn::cycle()
|
|||
srs_trace("PS: Media disconnect, code=%d", srs_error_code(err));
|
||||
|
||||
// Note that we added wrapper to manager, so we must free the wrapper, not this connection.
|
||||
SrsLazyGbMediaTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbMediaTcpConnWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // The creator wrapper MUST never be null, because we created it.
|
||||
_srs_gb_manager->remove(wrapper);
|
||||
|
||||
|
@ -1478,18 +1449,18 @@ srs_error_t SrsLazyGbMediaTcpConn::on_ps_pack(SrsPsPacket* ps, const std::vector
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsLazyGbMediaTcpConn::bind_session(uint32_t ssrc, SrsLazyGbSessionWrapper** psession)
|
||||
srs_error_t SrsLazyGbMediaTcpConn::bind_session(uint32_t ssrc, SrsLazyObjectWrapper<SrsLazyGbSession>** psession)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!ssrc) return err;
|
||||
|
||||
// The lazy-sweep wrapper for this resource.
|
||||
SrsLazyGbMediaTcpConnWrapper* wrapper = dynamic_cast<SrsLazyGbMediaTcpConnWrapper*>(gc_creator_wrapper());
|
||||
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper = wrapper_root_;
|
||||
srs_assert(wrapper); // It MUST never be NULL, because this method is in the cycle of coroutine.
|
||||
|
||||
// Find exists session for register, might be created by another object and still alive.
|
||||
SrsLazyGbSessionWrapper* session = dynamic_cast<SrsLazyGbSessionWrapper*>(_srs_gb_manager->find_by_fast_id(ssrc));
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* session = dynamic_cast<SrsLazyObjectWrapper<SrsLazyGbSession>*>(_srs_gb_manager->find_by_fast_id(ssrc));
|
||||
if (!session) return err;
|
||||
|
||||
_srs_gb_manager->add_with_fast_id(ssrc, session);
|
||||
|
|
|
@ -29,8 +29,6 @@ class SrsSipMessage;
|
|||
class SrsLazyGbSession;
|
||||
class SrsLazyGbSipTcpConn;
|
||||
class SrsLazyGbMediaTcpConn;
|
||||
class SrsLazyGbSipTcpConnWrapper;
|
||||
class SrsLazyGbMediaTcpConnWrapper;
|
||||
class SrsLazyGbSipTcpReceiver;
|
||||
class SrsLazyGbSipTcpSender;
|
||||
class SrsAlonePithyPrint;
|
||||
|
@ -88,76 +86,6 @@ enum SrsGbSipState
|
|||
};
|
||||
std::string srs_gb_sip_state(SrsGbSipState state);
|
||||
|
||||
// The interface for GB SIP or HTTP-API connection.
|
||||
class ISrsGbSipConn
|
||||
{
|
||||
public:
|
||||
ISrsGbSipConn();
|
||||
virtual ~ISrsGbSipConn();
|
||||
public:
|
||||
// Interrupt the transport, because session is disposing.
|
||||
virtual void interrupt() {}
|
||||
// Get the device id of device, also used as RTMP stream name.
|
||||
virtual std::string device_id() { return "livestream"; }
|
||||
// Get the state of SIP.
|
||||
virtual SrsGbSipState state() { return SrsGbSipStateInit; }
|
||||
// Reset the SIP state to registered, for re-inviting.
|
||||
virtual void reset_to_register() {}
|
||||
// Whether device is already registered, which might drive the session to connecting state.
|
||||
virtual bool is_registered() { return false; }
|
||||
// Whether device is stable state, which means it's sending heartbeat message.
|
||||
virtual bool is_stable() { return false; }
|
||||
// Whether device is request to bye, which means there might be no stream ever and so the session should be
|
||||
// disposed. This is the control event from client device.
|
||||
virtual bool is_bye() { return false; }
|
||||
// Send invite to device, for SIP it should be an "INVITE" request message. Output the ssrc as ID of session, for
|
||||
// media connection to load from SSRC while receiving and handling RTP packets.
|
||||
virtual srs_error_t invite_request(uint32_t* pssrc) { return srs_success; }
|
||||
// Change id of coroutine.
|
||||
virtual void set_cid(const SrsContextId& cid) {}
|
||||
};
|
||||
|
||||
// The wrapper for ISrsGbSipConn.
|
||||
class ISrsGbSipConnWrapper
|
||||
{
|
||||
private:
|
||||
ISrsGbSipConn dummy_;
|
||||
public:
|
||||
ISrsGbSipConnWrapper();
|
||||
virtual ~ISrsGbSipConnWrapper();
|
||||
public:
|
||||
virtual ISrsGbSipConn* resource() { return &dummy_; }
|
||||
virtual ISrsGbSipConnWrapper* copy() { return new ISrsGbSipConnWrapper(); }
|
||||
};
|
||||
|
||||
// The interface for GB media over TCP or UDP transport.
|
||||
class ISrsGbMediaConn
|
||||
{
|
||||
public:
|
||||
ISrsGbMediaConn();
|
||||
virtual ~ISrsGbMediaConn();
|
||||
public:
|
||||
// Interrupt the transport, because session is disposing.
|
||||
virtual void interrupt() {}
|
||||
// Whether media transport is connected. SRS will invite client to publish stream if not connected.
|
||||
virtual bool is_connected() { return false; }
|
||||
// Change id of coroutine.
|
||||
virtual void set_cid(const SrsContextId& cid) {}
|
||||
};
|
||||
|
||||
// The wrapper for ISrsGbMediaConn.
|
||||
class ISrsGbMediaConnWrapper
|
||||
{
|
||||
private:
|
||||
ISrsGbMediaConn dummy_;
|
||||
public:
|
||||
ISrsGbMediaConnWrapper();
|
||||
virtual ~ISrsGbMediaConnWrapper();
|
||||
public:
|
||||
virtual ISrsGbMediaConn* resource() { return &dummy_; }
|
||||
virtual ISrsGbMediaConnWrapper* copy() { return new ISrsGbMediaConnWrapper(); }
|
||||
};
|
||||
|
||||
// The main logic object for GB, the session.
|
||||
class SrsLazyGbSession : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
|
||||
{
|
||||
|
@ -166,8 +94,9 @@ private:
|
|||
SrsContextId cid_;
|
||||
private:
|
||||
SrsGbSessionState state_;
|
||||
ISrsGbSipConnWrapper* sip_;
|
||||
ISrsGbMediaConnWrapper* media_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media_;
|
||||
SrsGbMuxer* muxer_;
|
||||
private:
|
||||
// The candidate for SDP in configuration.
|
||||
|
@ -202,7 +131,7 @@ private:
|
|||
uint64_t media_reserved_;
|
||||
private:
|
||||
friend class SrsLazyObjectWrapper<SrsLazyGbSession>;
|
||||
SrsLazyGbSession();
|
||||
SrsLazyGbSession(SrsLazyObjectWrapper<SrsLazyGbSession>* wrapper_root);
|
||||
public:
|
||||
virtual ~SrsLazyGbSession();
|
||||
public:
|
||||
|
@ -211,10 +140,10 @@ public:
|
|||
// When got a pack of messages.
|
||||
void on_ps_pack(SrsPackContext* ctx, SrsPsPacket* ps, const std::vector<SrsTsMessage*>& msgs);
|
||||
// When got available SIP transport.
|
||||
void on_sip_transport(ISrsGbSipConnWrapper* sip);
|
||||
ISrsGbSipConnWrapper* sip_transport();
|
||||
void on_sip_transport(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip);
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* sip_transport();
|
||||
// When got available media transport.
|
||||
void on_media_transport(ISrsGbMediaConnWrapper* media);
|
||||
void on_media_transport(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* media);
|
||||
// Get the candidate for SDP generation, the public IP address for device to connect to.
|
||||
std::string pip();
|
||||
// Interface ISrsStartable
|
||||
|
@ -234,12 +163,6 @@ public:
|
|||
virtual std::string desc();
|
||||
};
|
||||
|
||||
// Lazy-sweep wrapper for GB session.
|
||||
class SrsLazyGbSessionWrapper : public ISrsResource
|
||||
{
|
||||
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbSession, SrsLazyGbSessionWrapper, SrsLazyGbSession);
|
||||
};
|
||||
|
||||
// The SIP and Media listener for GB.
|
||||
class SrsGbListener : public ISrsListener, public ISrsTcpHandler
|
||||
{
|
||||
|
@ -261,11 +184,11 @@ public:
|
|||
|
||||
// A GB28181 TCP SIP connection.
|
||||
class SrsLazyGbSipTcpConn : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
|
||||
, public ISrsGbSipConn
|
||||
{
|
||||
private:
|
||||
SrsGbSipState state_;
|
||||
SrsLazyGbSessionWrapper* session_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* session_;
|
||||
SrsSipMessage* register_;
|
||||
SrsSipMessage* invite_ok_;
|
||||
private:
|
||||
|
@ -282,7 +205,7 @@ private:
|
|||
SrsCoroutine* trd_;
|
||||
private:
|
||||
friend class SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>;
|
||||
SrsLazyGbSipTcpConn();
|
||||
SrsLazyGbSipTcpConn(SrsLazyObjectWrapper<SrsLazyGbSipTcpConn>* wrapper_root);
|
||||
public:
|
||||
virtual ~SrsLazyGbSipTcpConn();
|
||||
public:
|
||||
|
@ -337,13 +260,7 @@ private:
|
|||
virtual srs_error_t do_cycle();
|
||||
private:
|
||||
// Create session if no one, or bind to an existed session.
|
||||
srs_error_t bind_session(SrsSipMessage* msg, SrsLazyGbSessionWrapper** psession);
|
||||
};
|
||||
|
||||
// Lazy-sweep wrapper for GB SIP TCP connection.
|
||||
class SrsLazyGbSipTcpConnWrapper : public ISrsResource, public ISrsGbSipConnWrapper
|
||||
{
|
||||
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbSipTcpConn, ISrsGbSipConnWrapper, ISrsGbSipConn);
|
||||
srs_error_t bind_session(SrsSipMessage* msg, SrsLazyObjectWrapper<SrsLazyGbSession>** psession);
|
||||
};
|
||||
|
||||
// Start a coroutine to receive SIP messages.
|
||||
|
@ -414,11 +331,12 @@ public:
|
|||
|
||||
// A GB28181 TCP media connection, for PS stream.
|
||||
class SrsLazyGbMediaTcpConn : public SrsLazyObject, public ISrsResource, public ISrsStartable, public ISrsCoroutineHandler
|
||||
, public ISrsPsPackHandler, public ISrsGbMediaConn
|
||||
, public ISrsPsPackHandler
|
||||
{
|
||||
private:
|
||||
bool connected_;
|
||||
SrsLazyGbSessionWrapper* session_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root_;
|
||||
SrsLazyObjectWrapper<SrsLazyGbSession>* session_;
|
||||
uint32_t nn_rtcp_;
|
||||
private:
|
||||
SrsPackContext* pack_;
|
||||
|
@ -427,7 +345,7 @@ private:
|
|||
uint8_t* buffer_;
|
||||
private:
|
||||
friend class SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>;
|
||||
SrsLazyGbMediaTcpConn();
|
||||
SrsLazyGbMediaTcpConn(SrsLazyObjectWrapper<SrsLazyGbMediaTcpConn>* wrapper_root);
|
||||
public:
|
||||
virtual ~SrsLazyGbMediaTcpConn();
|
||||
public:
|
||||
|
@ -456,13 +374,7 @@ public:
|
|||
virtual srs_error_t on_ps_pack(SrsPsPacket* ps, const std::vector<SrsTsMessage*>& msgs);
|
||||
private:
|
||||
// Create session if no one, or bind to an existed session.
|
||||
srs_error_t bind_session(uint32_t ssrc, SrsLazyGbSessionWrapper** psession);
|
||||
};
|
||||
|
||||
// Lazy-sweep wrapper for GB Media TCP connection.
|
||||
class SrsLazyGbMediaTcpConnWrapper : public ISrsResource, public ISrsGbMediaConnWrapper
|
||||
{
|
||||
SRS_LAZY_WRAPPER_GENERATOR(SrsLazyGbMediaTcpConn, ISrsGbMediaConnWrapper, ISrsGbMediaConn);
|
||||
srs_error_t bind_session(uint32_t ssrc, SrsLazyObjectWrapper<SrsLazyGbSession>** psession);
|
||||
};
|
||||
|
||||
// The queue for mpegts over udp to send packets.
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 113
|
||||
#define VERSION_REVISION 114
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,23 +43,20 @@ ISrsConnection::~ISrsConnection()
|
|||
SrsLazyObject::SrsLazyObject()
|
||||
{
|
||||
gc_ref_ = 0;
|
||||
gc_creator_wrapper_ = NULL;
|
||||
}
|
||||
|
||||
SrsLazyObject::~SrsLazyObject()
|
||||
{
|
||||
}
|
||||
|
||||
SrsLazyObject* SrsLazyObject::gc_use()
|
||||
void SrsLazyObject::gc_use()
|
||||
{
|
||||
gc_ref_++;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsLazyObject* SrsLazyObject::gc_dispose()
|
||||
void SrsLazyObject::gc_dispose()
|
||||
{
|
||||
gc_ref_--;
|
||||
return this;
|
||||
}
|
||||
|
||||
int32_t SrsLazyObject::gc_ref()
|
||||
|
@ -67,16 +64,6 @@ int32_t SrsLazyObject::gc_ref()
|
|||
return gc_ref_;
|
||||
}
|
||||
|
||||
void SrsLazyObject::gc_set_creator_wrapper(ISrsResource* wrapper)
|
||||
{
|
||||
gc_creator_wrapper_ = wrapper;
|
||||
}
|
||||
|
||||
ISrsResource* SrsLazyObject::gc_creator_wrapper()
|
||||
{
|
||||
return gc_creator_wrapper_;
|
||||
}
|
||||
|
||||
ISrsLazyGc::ISrsLazyGc()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -55,24 +55,16 @@ class SrsLazyObject
|
|||
private:
|
||||
// The reference count of resource, 0 is no wrapper and safe to sweep.
|
||||
int32_t gc_ref_;
|
||||
// The creator wrapper, which created this resource. Note that it might be disposed and the pointer is NULL, so be
|
||||
// careful and make sure to check it before use it.
|
||||
ISrsResource* gc_creator_wrapper_;
|
||||
public:
|
||||
SrsLazyObject();
|
||||
virtual ~SrsLazyObject();
|
||||
public:
|
||||
// For wrapper to use this resource.
|
||||
virtual SrsLazyObject* gc_use();
|
||||
virtual void gc_use();
|
||||
// For wrapper to dispose this resource.
|
||||
virtual SrsLazyObject* gc_dispose();
|
||||
virtual void gc_dispose();
|
||||
// The current reference count of resource.
|
||||
virtual int32_t gc_ref();
|
||||
public:
|
||||
// Set the creator wrapper, from which resource clone wrapper.
|
||||
virtual void gc_set_creator_wrapper(ISrsResource* wrapper);
|
||||
// Get the first available wrapper. NULL if the creator wrapper disposed.
|
||||
virtual ISrsResource* gc_creator_wrapper();
|
||||
};
|
||||
|
||||
// The lazy-sweep GC, wait for a long time to dispose resource even when resource is disposable.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue