mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
UniquePtr: Support SrsUniquePtr to replace SrsAutoFree. v6.0.136 (#4109)
To manage an object: ```cpp // Before MyClass* ptr = new MyClass(); SrsAutoFree(MyClass, ptr); ptr->do_something(); // Now SrsUniquePtr<MyClass> ptr(new MyClass()); ptr->do_something(); ``` To manage an array of objects: ```cpp // Before char* ptr = new char[10]; SrsAutoFreeA(char, ptr); ptr[0] = 0xf; // Now SrsUniquePtr<char[]> ptr(new char[10]); ptr[0] = 0xf; ``` In fact, SrsUniquePtr is a limited subset of SrsAutoFree, mainly managing pointers and arrays. SrsUniquePtr is better than SrsAutoFree because it has the same API to standard unique ptr. ```cpp SrsUniquePtr<MyClass> ptr(new MyClass()); ptr->do_something(); MyClass* p = ptr.get(); ``` SrsAutoFree actually uses a pointer to a pointer, so it can be set to NULL, allowing the pointer's value to be changed later (this usage is different from SrsUniquePtr). ```cpp // OK to free ptr correctly. MyClass* ptr; SrsAutoFree(MyClass, ptr); ptr = new MyClass(); // Crash because ptr is an invalid pointer. MyClass* ptr; SrsUniquePtr<MyClass> ptr(ptr); ptr = new MyClass(); ``` Additionally, SrsAutoFreeH can use specific release functions, which SrsUniquePtr does not support. --------- Co-authored-by: Jacob Su <suzp1984@gmail.com>
This commit is contained in:
parent
baf22d01c1
commit
23d2602c34
72 changed files with 1720 additions and 1669 deletions
|
@ -9,79 +9,106 @@
|
|||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// The auto free helper, which is actually the unique ptr, without the move feature,
|
||||
// Unique ptr smart pointer, only support unique ptr, with limited APIs and features,
|
||||
// see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
|
||||
//
|
||||
// To free the instance in the current scope, for instance, MyClass* ptr,
|
||||
// which is a ptr and this class will:
|
||||
// 1. free the ptr.
|
||||
// 2. set ptr to NULL.
|
||||
//
|
||||
// Usage:
|
||||
// MyClass* po = new MyClass();
|
||||
// // ...... use po
|
||||
// SrsAutoFree(MyClass, po);
|
||||
// SrsUniquePtr<MyClass> ptr(new MyClass());
|
||||
// ptr->do_something();
|
||||
//
|
||||
// Usage for array:
|
||||
// MyClass** pa = new MyClass*[size];
|
||||
// // ....... use pa
|
||||
// SrsAutoFreeA(MyClass*, pa);
|
||||
// Note that the ptr should be initialized before use it, or it will crash if not set, for example:
|
||||
// Myclass* p;
|
||||
// SrsUniquePtr<MyClass> ptr(p); // crash because p is an invalid pointer.
|
||||
//
|
||||
// @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
|
||||
// where the char* pstr = new char[size].
|
||||
// To delete object.
|
||||
#define SrsAutoFree(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, NULL)
|
||||
// To delete array.
|
||||
#define SrsAutoFreeA(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false, NULL)
|
||||
// Use free instead of delete.
|
||||
#define SrsAutoFreeF(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true, NULL)
|
||||
// Use hook instead of delete.
|
||||
#define SrsAutoFreeH(className, instance, hook) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, hook)
|
||||
// The template implementation.
|
||||
// Note that do not support array or object created by malloc, because we only use delete to dispose
|
||||
// the resource.
|
||||
template<class T>
|
||||
class impl_SrsAutoFree
|
||||
class SrsUniquePtr
|
||||
{
|
||||
private:
|
||||
T** ptr;
|
||||
bool is_array;
|
||||
bool _use_free;
|
||||
void (*_hook)(T*);
|
||||
T* ptr_;
|
||||
public:
|
||||
// If use_free, use free(void*) to release the p.
|
||||
// If specified hook, use hook(p) to release it.
|
||||
// Use delete to release p, or delete[] if p is an array.
|
||||
impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) {
|
||||
ptr = p;
|
||||
is_array = array;
|
||||
_use_free = use_free;
|
||||
_hook = hook;
|
||||
SrsUniquePtr(T* ptr = NULL) {
|
||||
ptr_ = ptr;
|
||||
}
|
||||
|
||||
virtual ~impl_SrsAutoFree() {
|
||||
if (ptr == NULL || *ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
virtual ~SrsUniquePtr() {
|
||||
delete ptr_;
|
||||
}
|
||||
public:
|
||||
// Get the object.
|
||||
T* get() {
|
||||
return ptr_;
|
||||
}
|
||||
// Overload the -> operator.
|
||||
T* operator->() {
|
||||
return ptr_;
|
||||
}
|
||||
private:
|
||||
// Copy the unique ptr.
|
||||
SrsUniquePtr(const SrsUniquePtr<T>&) = delete;
|
||||
// The assign operator.
|
||||
SrsUniquePtr<T>& operator=(const SrsUniquePtr<T>&) = delete;
|
||||
private:
|
||||
// Overload the * operator.
|
||||
T& operator*() = delete;
|
||||
// Overload the bool operator.
|
||||
operator bool() const = delete;
|
||||
#if __cplusplus >= 201103L // C++11
|
||||
private:
|
||||
// The move constructor.
|
||||
SrsUniquePtr(SrsUniquePtr<T>&&) = delete;
|
||||
// The move assign operator.
|
||||
SrsUniquePtr<T>& operator=(SrsUniquePtr<T>&&) = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
if (_use_free) {
|
||||
free(*ptr);
|
||||
} else if (_hook) {
|
||||
_hook(*ptr);
|
||||
} else {
|
||||
if (is_array) {
|
||||
delete[] *ptr;
|
||||
} else {
|
||||
delete *ptr;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = NULL;
|
||||
// The unique ptr for array objects, only support unique ptr, with limited APIs and features,
|
||||
// see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
|
||||
//
|
||||
// Usage:
|
||||
// SrsUniquePtr<MyClass[]> ptr(new MyClass[10]);
|
||||
// ptr[0]->do_something();
|
||||
template<class T>
|
||||
class SrsUniquePtr<T[]>
|
||||
{
|
||||
private:
|
||||
T* ptr_;
|
||||
public:
|
||||
SrsUniquePtr(T* ptr = NULL) {
|
||||
ptr_ = ptr;
|
||||
}
|
||||
virtual ~SrsUniquePtr() {
|
||||
delete[] ptr_;
|
||||
}
|
||||
public:
|
||||
// Get the object.
|
||||
T* get() {
|
||||
return ptr_;
|
||||
}
|
||||
// Overload the [] operator.
|
||||
T& operator[](std::size_t index) {
|
||||
return ptr_[index];
|
||||
}
|
||||
const T& operator[](std::size_t index) const {
|
||||
return ptr_[index];
|
||||
}
|
||||
private:
|
||||
// Copy the unique ptr.
|
||||
SrsUniquePtr(const SrsUniquePtr<T>&) = delete;
|
||||
// The assign operator.
|
||||
SrsUniquePtr<T>& operator=(const SrsUniquePtr<T>&) = delete;
|
||||
private:
|
||||
// Overload the * operator.
|
||||
T& operator*() = delete;
|
||||
// Overload the bool operator.
|
||||
operator bool() const = delete;
|
||||
#if __cplusplus >= 201103L // C++11
|
||||
private:
|
||||
// The move constructor.
|
||||
SrsUniquePtr(SrsUniquePtr<T>&&) = delete;
|
||||
// The move assign operator.
|
||||
SrsUniquePtr<T>& operator=(SrsUniquePtr<T>&&) = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Shared ptr smart pointer, only support shared ptr, no weak ptr, no shared from this, no inheritance,
|
||||
|
|
8
trunk/src/core/srs_core_deprecated.cpp
Normal file
8
trunk/src/core/srs_core_deprecated.cpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// Copyright (c) 2013-2024 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#include <srs_core_deprecated.hpp>
|
||||
|
95
trunk/src/core/srs_core_deprecated.hpp
Normal file
95
trunk/src/core/srs_core_deprecated.hpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Copyright (c) 2013-2024 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_CORE_DEPRECATED_HPP
|
||||
#define SRS_CORE_DEPRECATED_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// Note that the SrsAutoFree is deprecated, please use SrsUniquePtr instead.
|
||||
//
|
||||
// Note: Please use SrsUniquePtr if possible. Please aware that there is a slight difference between SrsAutoFree
|
||||
// and SrsUniquePtr. SrsAutoFree will track the address of pointer, while SrsUniquePtr will not.
|
||||
// MyClass* p;
|
||||
// SrsAutoFree(MyClass, p); // p will be freed even p is changed later.
|
||||
// SrsUniquePtr ptr(p); // crash because p is an invalid pointer.
|
||||
//
|
||||
// The auto free helper, which is actually the unique ptr, without the move feature,
|
||||
// see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
|
||||
//
|
||||
// To free the instance in the current scope, for instance, MyClass* ptr,
|
||||
// which is a ptr and this class will:
|
||||
// 1. free the ptr.
|
||||
// 2. set ptr to NULL.
|
||||
//
|
||||
// Usage:
|
||||
// MyClass* po = new MyClass();
|
||||
// // ...... use po
|
||||
// SrsAutoFree(MyClass, po);
|
||||
//
|
||||
// Usage for array:
|
||||
// MyClass** pa = new MyClass*[size];
|
||||
// // ....... use pa
|
||||
// SrsAutoFreeA(MyClass*, pa);
|
||||
//
|
||||
// @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
|
||||
// where the char* pstr = new char[size].
|
||||
// To delete object.
|
||||
#define SrsAutoFree(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, NULL)
|
||||
// To delete array.
|
||||
#define SrsAutoFreeA(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false, NULL)
|
||||
// Use free instead of delete.
|
||||
#define SrsAutoFreeF(className, instance) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true, NULL)
|
||||
// Use hook instead of delete.
|
||||
#define SrsAutoFreeH(className, instance, hook) \
|
||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, hook)
|
||||
// The template implementation.
|
||||
template<class T>
|
||||
class impl_SrsAutoFree
|
||||
{
|
||||
private:
|
||||
T** ptr;
|
||||
bool is_array;
|
||||
bool _use_free;
|
||||
void (*_hook)(T*);
|
||||
public:
|
||||
// If use_free, use free(void*) to release the p.
|
||||
// If specified hook, use hook(p) to release it.
|
||||
// Use delete to release p, or delete[] if p is an array.
|
||||
impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) {
|
||||
ptr = p;
|
||||
is_array = array;
|
||||
_use_free = use_free;
|
||||
_hook = hook;
|
||||
}
|
||||
|
||||
virtual ~impl_SrsAutoFree() {
|
||||
if (ptr == NULL || *ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_use_free) {
|
||||
free(*ptr);
|
||||
} else if (_hook) {
|
||||
_hook(*ptr);
|
||||
} else {
|
||||
if (is_array) {
|
||||
delete[] *ptr;
|
||||
} else {
|
||||
delete *ptr;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 6
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 135
|
||||
#define VERSION_REVISION 136
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue