Skip to content

Commit

Permalink
GC: Refine wrapper constructor.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Dec 20, 2022
1 parent cb0f49f commit 7df5465
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions trunk/src/app/srs_app_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +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_;
public:
SrsLazyObjectWrapper(T* resource = NULL) {
resource_ = resource ? resource : new T(this);
resource_->gc_use();
SrsLazyObjectWrapper() {
init(new T(this));
}
virtual ~SrsLazyObjectWrapper() {
resource_->gc_dispose();
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_);
Expand Down

0 comments on commit 7df5465

Please # to comment.