Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmartPtr: Use shared ptr to manage GB objects. v6.0.126 #4080

Merged
merged 16 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v6-changes"></a>

## SRS 6.0 Changelog
* v6.0, 2024-06-12, Merge [#4080](https://github.com/ossrs/srs/pull/4080): SmartPtr: Use shared ptr to manage GB objects. v6.0.126 (#4080)
* v6.0, 2024-06-03, Merge [#4057](https://github.com/ossrs/srs/pull/4057): RTC: Support dropping h.264 SEI from NALUs. v6.0.125 (#4057)
* v6.0, 2024-04-26, Merge [#4044](https://github.com/ossrs/srs/pull/4044): fix: correct SRS_ERRNO_MAP_HTTP duplicate error code. v6.0.124 (#4044)
* v6.0, 2024-04-23, Merge [#4038](https://github.com/ossrs/srs/pull/4038): RTMP: Do not response publish start message if hooks fail. v6.0.123 (#4038)
Expand Down
22 changes: 0 additions & 22 deletions trunk/src/app/srs_app_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,28 +413,6 @@ void SrsResourceManager::dispose(ISrsResource* c)
}
}

SrsLazySweepGc::SrsLazySweepGc()
{
}

SrsLazySweepGc::~SrsLazySweepGc()
{
}

srs_error_t SrsLazySweepGc::start()
{
srs_error_t err = srs_success;
return err;
}

void SrsLazySweepGc::remove(SrsLazyObject* c)
{
// TODO: FIXME: MUST lazy sweep.
srs_freep(c);
}

ISrsLazyGc* _srs_gc = NULL;

ISrsExpire::ISrsExpire()
{
}
Expand Down
117 changes: 43 additions & 74 deletions trunk/src/app/srs_app_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <srs_protocol_kbps.hpp>
#include <srs_app_reload.hpp>
#include <srs_protocol_conn.hpp>
#include <srs_core_autofree.hpp>

class SrsWallClock;
class SrsBuffer;
Expand Down Expand Up @@ -125,98 +126,66 @@ class SrsResourceManager : public ISrsCoroutineHandler, public ISrsResourceManag
void dispose(ISrsResource* c);
};

// A simple lazy-sweep GC, just wait for a long time to delete the disposable resources.
class SrsLazySweepGc : public ISrsLazyGc
{
public:
SrsLazySweepGc();
virtual ~SrsLazySweepGc();
public:
virtual srs_error_t start();
virtual void remove(SrsLazyObject* c);
};

extern ISrsLazyGc* _srs_gc;

// A wrapper template for lazy-sweep resource.
// See https://github.com/ossrs/srs/issues/3176#lazy-sweep
// This class implements the ISrsResource interface using a smart pointer, allowing the Manager to delete this
// smart pointer resource, such as by implementing delayed release.
//
// 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().
// It embeds an SrsSharedPtr to provide the same interface, but it is not an inheritance relationship. Its usage
// is identical to SrsSharedPtr, but they cannot replace each other. They are not related and cannot be converted
// to one another.
//
// 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 we don't need to implement the move constructor and move assignment operator, because we directly
// use SrsSharedPtr as instance member, so we can only copy it.
//
// 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.
// Usage:
// SrsSharedResource<MyClass>* ptr = new SrsSharedResource<MyClass>(new MyClass());
// (*ptr)->do_something();
//
// ISrsResourceManager* manager = ...;
// manager->remove(ptr);
template<typename T>
class SrsLazyObjectWrapper : public ISrsResource
class SrsSharedResource : public ISrsResource
{
private:
T* resource_;
SrsSharedPtr<T> ptr_;
public:
SrsLazyObjectWrapper() {
init(new T(this));
SrsSharedResource(T* ptr) : ptr_(ptr) {
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
}
virtual ~SrsLazyObjectWrapper() {
resource_->gc_dispose();
if (resource_->gc_ref() == 0) {
_srs_gc->remove(resource_);
}
SrsSharedResource(const SrsSharedResource<T>& cp) : ptr_(cp.ptr_) {
}
private:
SrsLazyObjectWrapper(T* resource) {
init(resource);
}
void init(T* resource) {
resource_ = resource;
resource_->gc_use();
virtual ~SrsSharedResource() {
}
public:
SrsLazyObjectWrapper<T>* copy() {
return new SrsLazyObjectWrapper<T>(resource_);
// Get the object.
T* get() {
return ptr_.get();
}
// Overload the -> operator.
T* operator->() {
return ptr_.operator->();
}
// The assign operator.
SrsSharedResource<T>& operator=(const SrsSharedResource<T>& cp) {
if (this != &cp) {
ptr_ = cp.ptr_;
}
return *this;
}
private:
// Overload the * operator.
T& operator*() {
return ptr_.operator*();
}
T* resource() {
return resource_;
// Overload the bool operator.
operator bool() const {
return ptr_.operator bool();
}
// Interface ISrsResource
public:
virtual const SrsContextId& get_id() {
return resource_->get_id();
return ptr_->get_id();
}
virtual std::string desc() {
return resource_->desc();
return ptr_->desc();
}
};

Expand Down
Loading
Loading