Support custom deleter for SrsUniquePtr. (#4309)
SrsUniquePtr does not support array or object created by malloc, because
we only use delete to dispose the resource. You can use a custom
function to free the memory allocated by malloc or other allocators.
```cpp
char* p = (char*)malloc(1024);
SrsUniquePtr<char> ptr(p, your_free_chars);
```
This is used to replace the SrsAutoFreeH. For example:
```cpp
addrinfo* r = NULL;
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
getaddrinfo("127.0.0.1", NULL, &hints, &r);
```
Now, this can be replaced by:
```cpp
addrinfo* r = NULL;
getaddrinfo("127.0.0.1", NULL, &hints, &r);
SrsUniquePtr<addrinfo> r2(r, freeaddrinfo);
```
Please aware that there is a slight difference between SrsAutoFreeH and
SrsUniquePtr. SrsAutoFreeH will track the address of pointer, while
SrsUniquePtr will not.
```cpp
addrinfo* r = NULL;
SrsAutoFreeH(addrinfo, r, freeaddrinfo); // r will be freed even r is changed later.
SrsUniquePtr<addrinfo> ptr(r, freeaddrinfo); // crash because r is an invalid pointer.
```
---------
Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: john <hondaxiao@tencent.com>
This commit is contained in:
parent
5881155095
commit
4e55bc83b7
20
.vscode/settings.json
vendored
20
.vscode/settings.json
vendored
|
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"cmake.sourceDirectory": "${workspaceFolder}/trunk/ide/srs_clion",
|
"cmake.sourceDirectory": "${workspaceFolder}/trunk/ide/srs_clion",
|
||||||
"cmake.buildDirectory": "${workspaceFolder}/trunk/ide/vscode-build",
|
"cmake.buildDirectory": "${workspaceFolder}/trunk/ide/vscode-build",
|
||||||
"cmake.configureOnOpen": false
|
"cmake.configureOnOpen": false,
|
||||||
|
"files.associations": {
|
||||||
|
"vector": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__split_buffer": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"queue": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"stack": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"unordered_map": "cpp"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
73
trunk/3rdparty/st-srs/utest/st_utest.hpp
vendored
73
trunk/3rdparty/st-srs/utest/st_utest.hpp
vendored
|
|
@ -50,78 +50,5 @@ extern std::ostream& operator<<(std::ostream& out, const ErrorObject* err);
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The time unit in ms, for example 100 * SRS_UTIME_MILLISECONDS means 100ms.
|
|
||||||
#define SRS_UTIME_MILLISECONDS 1000
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,7 @@ function parse_user_option() {
|
||||||
--gmp) SRS_GPERF_MP=$(switch2value $value) ;;
|
--gmp) SRS_GPERF_MP=$(switch2value $value) ;;
|
||||||
--gcp) SRS_GPERF_CP=$(switch2value $value) ;;
|
--gcp) SRS_GPERF_CP=$(switch2value $value) ;;
|
||||||
--gprof) SRS_GPROF=$(switch2value $value) ;;
|
--gprof) SRS_GPROF=$(switch2value $value) ;;
|
||||||
|
--asan) SRS_SANITIZER=$(switch2value $value) ;;
|
||||||
--sanitizer) SRS_SANITIZER=$(switch2value $value) ;;
|
--sanitizer) SRS_SANITIZER=$(switch2value $value) ;;
|
||||||
--sanitizer-static) SRS_SANITIZER_STATIC=$(switch2value $value) ;;
|
--sanitizer-static) SRS_SANITIZER_STATIC=$(switch2value $value) ;;
|
||||||
--sanitizer-log) SRS_SANITIZER_LOG=$(switch2value $value) ;;
|
--sanitizer-log) SRS_SANITIZER_LOG=$(switch2value $value) ;;
|
||||||
|
|
|
||||||
|
|
@ -1638,41 +1638,15 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket* pkt)
|
||||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
|
return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset SPS/PPS cache, ensuring that the next SPS/PPS will be handled when both are received.
|
// Packet SPS/PPS to RTMP keyframe.
|
||||||
// Note that we should use SrsAutoFree to set the ptr to NULL.
|
err = packet_sps_pps(pkt, sps, pps);
|
||||||
SrsAutoFree(SrsRtpPacket, obs_whip_sps_);
|
|
||||||
SrsAutoFree(SrsRtpPacket, obs_whip_pps_);
|
|
||||||
|
|
||||||
// h264 raw to h264 packet.
|
// Always reset the SPS/PPS cache after used it.
|
||||||
std::string sh;
|
srs_freep(obs_whip_sps_);
|
||||||
SrsUniquePtr<SrsRawH264Stream> avc(new SrsRawH264Stream());
|
srs_freep(obs_whip_pps_);
|
||||||
|
|
||||||
if ((err = avc->mux_sequence_header(string(sps->bytes, sps->size), string(pps->bytes, pps->size), sh)) != srs_success) {
|
if (err != srs_success) {
|
||||||
return srs_error_wrap(err, "mux sequence header");
|
return srs_error_wrap(err, "packet sps/pps");
|
||||||
}
|
|
||||||
|
|
||||||
// h264 packet to flv packet.
|
|
||||||
char* flv = NULL;
|
|
||||||
int nb_flv = 0;
|
|
||||||
if ((err = avc->mux_avc2flv(sh, SrsVideoAvcFrameTypeKeyFrame, SrsVideoAvcFrameTraitSequenceHeader, pkt->get_avsync_time(),
|
|
||||||
pkt->get_avsync_time(), &flv, &nb_flv)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "avc to flv");
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsMessageHeader header;
|
|
||||||
header.initialize_video(nb_flv, pkt->get_avsync_time(), 1);
|
|
||||||
SrsCommonMessage rtmp;
|
|
||||||
if ((err = rtmp.create(&header, flv, nb_flv)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "create rtmp");
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsSharedPtrMessage msg;
|
|
||||||
if ((err = msg.create(&rtmp)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "create message");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = bridge_->on_frame(&msg)) != srs_success) {
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1729,6 +1703,48 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket* pkt)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_error_t SrsRtcFrameBuilder::packet_sps_pps(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps)
|
||||||
|
{
|
||||||
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
// h264 raw to h264 packet.
|
||||||
|
std::string sh;
|
||||||
|
SrsUniquePtr<SrsRawH264Stream> avc(new SrsRawH264Stream());
|
||||||
|
|
||||||
|
string sps2 = string(sps->bytes, sps->size);
|
||||||
|
string pps2 = string(pps->bytes, pps->size);
|
||||||
|
if ((err = avc->mux_sequence_header(sps2, pps2, sh)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "mux sequence header");
|
||||||
|
}
|
||||||
|
|
||||||
|
// h264 packet to flv packet.
|
||||||
|
char* flv = NULL;
|
||||||
|
int nb_flv = 0;
|
||||||
|
if ((err = avc->mux_avc2flv(sh, SrsVideoAvcFrameTypeKeyFrame,
|
||||||
|
SrsVideoAvcFrameTraitSequenceHeader, pkt->get_avsync_time(),
|
||||||
|
pkt->get_avsync_time(), &flv, &nb_flv)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "avc to flv");
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsMessageHeader header;
|
||||||
|
header.initialize_video(nb_flv, pkt->get_avsync_time(), 1);
|
||||||
|
SrsCommonMessage rtmp;
|
||||||
|
if ((err = rtmp.create(&header, flv, nb_flv)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "create rtmp");
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsSharedPtrMessage msg;
|
||||||
|
if ((err = msg.create(&rtmp)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "create message");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = bridge_->on_frame(&msg)) != srs_success) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
srs_error_t SrsRtcFrameBuilder::packet_video_rtmp(const uint16_t start, const uint16_t end)
|
srs_error_t SrsRtcFrameBuilder::packet_video_rtmp(const uint16_t start, const uint16_t end)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,8 @@ private:
|
||||||
private:
|
private:
|
||||||
srs_error_t packet_video(SrsRtpPacket* pkt);
|
srs_error_t packet_video(SrsRtpPacket* pkt);
|
||||||
srs_error_t packet_video_key_frame(SrsRtpPacket* pkt);
|
srs_error_t packet_video_key_frame(SrsRtpPacket* pkt);
|
||||||
|
srs_error_t packet_sps_pps(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps);
|
||||||
|
private:
|
||||||
inline uint16_t cache_index(uint16_t current_sn) {
|
inline uint16_t cache_index(uint16_t current_sn) {
|
||||||
return current_sn % s_cache_size;
|
return current_sn % s_cache_size;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,36 @@
|
||||||
// SrsUniquePtr<MyClass> ptr(new MyClass());
|
// SrsUniquePtr<MyClass> ptr(new MyClass());
|
||||||
// ptr->do_something();
|
// ptr->do_something();
|
||||||
//
|
//
|
||||||
// Note that the ptr should be initialized before use it, or it will crash if not set, for example:
|
// Note that the p should be initialized before use it, or it will crash if not set, for example:
|
||||||
// Myclass* p;
|
// Myclass* p;
|
||||||
// SrsUniquePtr<MyClass> ptr(p); // crash because p is an invalid pointer.
|
// SrsUniquePtr<MyClass> ptr(p); // crash because p is an invalid pointer.
|
||||||
//
|
//
|
||||||
// Note that do not support array or object created by malloc, because we only use delete to dispose
|
// Note that do not support array or object created by malloc, because we only use delete to dispose
|
||||||
// the resource.
|
// the resource. You can use a custom function to free the memory allocated by malloc or other
|
||||||
|
// allocators.
|
||||||
|
// char* p = (char*)malloc(1024);
|
||||||
|
// SrsUniquePtr<char> ptr(p, your_free_chars);
|
||||||
|
// Or to free a specific object:
|
||||||
|
// addrinfo* r = NULL;
|
||||||
|
// getaddrinfo("127.0.0.1", NULL, &hints, &r);
|
||||||
|
// SrsUniquePtr<addrinfo> ptr(r, freeaddrinfo);
|
||||||
template<class T>
|
template<class T>
|
||||||
class SrsUniquePtr
|
class SrsUniquePtr
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
T* ptr_;
|
T* ptr_;
|
||||||
|
void (*deleter_)(T*);
|
||||||
public:
|
public:
|
||||||
SrsUniquePtr(T* ptr = NULL) {
|
SrsUniquePtr(T* ptr = NULL, void (*deleter)(T*) = NULL) {
|
||||||
ptr_ = ptr;
|
ptr_ = ptr;
|
||||||
|
deleter_ = deleter;
|
||||||
}
|
}
|
||||||
virtual ~SrsUniquePtr() {
|
virtual ~SrsUniquePtr() {
|
||||||
delete ptr_;
|
if (!deleter_) {
|
||||||
|
delete ptr_;
|
||||||
|
} else {
|
||||||
|
deleter_(ptr_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// Get the object.
|
// Get the object.
|
||||||
|
|
@ -68,6 +81,10 @@ private:
|
||||||
// Usage:
|
// Usage:
|
||||||
// SrsUniquePtr<MyClass[]> ptr(new MyClass[10]);
|
// SrsUniquePtr<MyClass[]> ptr(new MyClass[10]);
|
||||||
// ptr[0]->do_something();
|
// ptr[0]->do_something();
|
||||||
|
//
|
||||||
|
// Note that the p 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.
|
||||||
template<class T>
|
template<class T>
|
||||||
class SrsUniquePtr<T[]>
|
class SrsUniquePtr<T[]>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,85 +11,93 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
// Note that the SrsAutoFree is deprecated, please use SrsUniquePtr instead.
|
// Note that the SrsAutoFree is deprecated, please use SrsUniquePtr instead. For example:
|
||||||
|
// MyClass* p = new MyClass();
|
||||||
|
// SrsAutoFree(MyClass, p);
|
||||||
|
// This can be replaced by:
|
||||||
|
// SrsUniquePtr<MyClass> p(new MyClass());
|
||||||
//
|
//
|
||||||
// Note: Please use SrsUniquePtr if possible. Please aware that there is a slight difference between SrsAutoFree
|
// Note: Please aware that there is a slight difference between SrsAutoFree and SrsUniquePtr.
|
||||||
// and SrsUniquePtr. SrsAutoFree will track the address of pointer, while SrsUniquePtr will not.
|
// SrsAutoFree will track the address of pointer, while SrsUniquePtr will not.
|
||||||
// MyClass* p;
|
// MyClass* p;
|
||||||
// SrsAutoFree(MyClass, p); // p will be freed even p is changed later.
|
// SrsAutoFree(MyClass, p); // p will be freed even p is changed later.
|
||||||
// SrsUniquePtr ptr(p); // crash because p is an invalid pointer.
|
// 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 for more details.
|
||||||
// see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
|
//#define SrsAutoFree(className, instance) \
|
||||||
//
|
// impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, NULL)
|
||||||
// To free the instance in the current scope, for instance, MyClass* ptr,
|
// To delete array. Please use SrsUniquePtr instead. For example:
|
||||||
// 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];
|
// MyClass** pa = new MyClass*[size];
|
||||||
// // ....... use pa
|
|
||||||
// SrsAutoFreeA(MyClass*, pa);
|
// SrsAutoFreeA(MyClass*, pa);
|
||||||
|
// This can be replaced by:
|
||||||
|
// SrsUniquePtr<MyClass[]> pa(new MyClass[10]);
|
||||||
//
|
//
|
||||||
// @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
|
// Note: Please aware that there is a slight difference between SrsAutoFreeA and SrsUniquePtr.
|
||||||
// where the char* pstr = new char[size].
|
// SrsAutoFreeA will track the address of pointer, while SrsUniquePtr will not.
|
||||||
// To delete object.
|
// MyClass** pa;
|
||||||
#define SrsAutoFree(className, instance) \
|
// SrsAutoFreeA(MyClass*, pa); // pa will be freed even pa is changed later.
|
||||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, NULL)
|
// SrsUniquePtr<MyClass[]> ptr(pa); // crash because pa is an invalid pointer.
|
||||||
// To delete array.
|
//
|
||||||
#define SrsAutoFreeA(className, instance) \
|
// See https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107 for more details.
|
||||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false, NULL)
|
//#define SrsAutoFreeA(className, instance) \
|
||||||
// Use free instead of delete.
|
// impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false, NULL)
|
||||||
#define SrsAutoFreeF(className, instance) \
|
// Use hook instead of delete. Please use SrsUniquePtr instead. For example:
|
||||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true, NULL)
|
// addrinfo* r = NULL;
|
||||||
// Use hook instead of delete.
|
// SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
||||||
#define SrsAutoFreeH(className, instance, hook) \
|
// getaddrinfo("127.0.0.1", NULL, &hints, &r);
|
||||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, hook)
|
// This can be replaced by:
|
||||||
|
// addrinfo* r = NULL;
|
||||||
|
// getaddrinfo("127.0.0.1", NULL, &hints, &r);
|
||||||
|
// SrsUniquePtr<addrinfo> ptr(r, freeaddrinfo);
|
||||||
|
//
|
||||||
|
// Note: Please aware that there is a slight difference between SrsAutoFreeH and SrsUniquePtr.
|
||||||
|
// SrsAutoFreeH will track the address of pointer, while SrsUniquePtr will not.
|
||||||
|
// addrinfo* r = NULL;
|
||||||
|
// SrsAutoFreeH(addrinfo, r, freeaddrinfo); // r will be freed even r is changed later.
|
||||||
|
// SrsUniquePtr<addrinfo> ptr(r, freeaddrinfo); // crash because r is an invalid pointer.
|
||||||
|
//
|
||||||
|
// See https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107 for more details.
|
||||||
|
//#define SrsAutoFreeH(className, instance, hook) \
|
||||||
|
// impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, hook)
|
||||||
// The template implementation.
|
// The template implementation.
|
||||||
template<class T>
|
//template<class T>
|
||||||
class impl_SrsAutoFree
|
//class impl_SrsAutoFree
|
||||||
{
|
//{
|
||||||
private:
|
//private:
|
||||||
T** ptr;
|
// T** ptr;
|
||||||
bool is_array;
|
// bool is_array;
|
||||||
bool _use_free;
|
// bool _use_free;
|
||||||
void (*_hook)(T*);
|
// void (*_hook)(T*);
|
||||||
public:
|
//public:
|
||||||
// If use_free, use free(void*) to release the p.
|
// // If use_free, use free(void*) to release the p.
|
||||||
// If specified hook, use hook(p) to release it.
|
// // If specified hook, use hook(p) to release it.
|
||||||
// Use delete to release p, or delete[] if p is an array.
|
// // Use delete to release p, or delete[] if p is an array.
|
||||||
impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) {
|
// impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) {
|
||||||
ptr = p;
|
// ptr = p;
|
||||||
is_array = array;
|
// is_array = array;
|
||||||
_use_free = use_free;
|
// _use_free = use_free;
|
||||||
_hook = hook;
|
// _hook = hook;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
virtual ~impl_SrsAutoFree() {
|
// virtual ~impl_SrsAutoFree() {
|
||||||
if (ptr == NULL || *ptr == NULL) {
|
// if (ptr == NULL || *ptr == NULL) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (_use_free) {
|
// if (_use_free) {
|
||||||
free(*ptr);
|
// free(*ptr);
|
||||||
} else if (_hook) {
|
// } else if (_hook) {
|
||||||
_hook(*ptr);
|
// _hook(*ptr);
|
||||||
} else {
|
// } else {
|
||||||
if (is_array) {
|
// if (is_array) {
|
||||||
delete[] *ptr;
|
// delete[] *ptr;
|
||||||
} else {
|
// } else {
|
||||||
delete *ptr;
|
// delete *ptr;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
*ptr = NULL;
|
// *ptr = NULL;
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5315,9 +5315,21 @@ srs_error_t SrsMp4BoxReader::read(SrsSimpleStream* stream, SrsMp4Box** ppbox)
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
SrsMp4Box* box = NULL;
|
SrsMp4Box* box = NULL;
|
||||||
// Note that we should use SrsAutoFree to free the ptr which is set later.
|
if ((err = do_read(stream, box)) == srs_success) {
|
||||||
SrsAutoFree(SrsMp4Box, box);
|
*ppbox = box;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When error, free the created box.
|
||||||
|
srs_freep(box);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t SrsMp4BoxReader::do_read(SrsSimpleStream* stream, SrsMp4Box*& box)
|
||||||
|
{
|
||||||
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// For the first time to read the box, maybe it's a basic box which is only 4bytes header.
|
// For the first time to read the box, maybe it's a basic box which is only 4bytes header.
|
||||||
// When we disconvery the real box, we know the size of the whole box, then read again and decode it.
|
// When we disconvery the real box, we know the size of the whole box, then read again and decode it.
|
||||||
|
|
@ -5357,11 +5369,6 @@ srs_error_t SrsMp4BoxReader::read(SrsSimpleStream* stream, SrsMp4Box** ppbox)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == srs_success) {
|
|
||||||
*ppbox = box;
|
|
||||||
box = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5651,18 +5658,17 @@ srs_error_t SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox, uint32_t required_bo
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
SrsMp4Box* box = NULL;
|
SrsMp4Box* box = NULL;
|
||||||
// Note that we should use SrsAutoFree to free the ptr which is set later.
|
|
||||||
SrsAutoFree(SrsMp4Box, box);
|
|
||||||
|
|
||||||
if ((err = do_load_next_box(&box, required_box_type)) != srs_success) {
|
if ((err = do_load_next_box(&box, required_box_type)) != srs_success) {
|
||||||
return srs_error_wrap(err, "load box");
|
return srs_error_wrap(err, "load box");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!required_box_type || (uint32_t)box->type == required_box_type) {
|
if (!required_box_type || (uint32_t)box->type == required_box_type) {
|
||||||
*ppbox = box;
|
*ppbox = box;
|
||||||
box = NULL;
|
return err;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the box is not matched the required type.
|
||||||
|
srs_freep(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
|
|
@ -1963,6 +1963,9 @@ public:
|
||||||
public:
|
public:
|
||||||
// Read a MP4 box to pbox, the stream is fill with the bytes of box to decode.
|
// Read a MP4 box to pbox, the stream is fill with the bytes of box to decode.
|
||||||
virtual srs_error_t read(SrsSimpleStream* stream, SrsMp4Box** ppbox);
|
virtual srs_error_t read(SrsSimpleStream* stream, SrsMp4Box** ppbox);
|
||||||
|
private:
|
||||||
|
srs_error_t do_read(SrsSimpleStream* stream, SrsMp4Box*& box);
|
||||||
|
public:
|
||||||
// Skip the box from stream, and skip in file if need.
|
// Skip the box from stream, and skip in file if need.
|
||||||
virtual srs_error_t skip(SrsMp4Box* box, SrsSimpleStream* stream);
|
virtual srs_error_t skip(SrsMp4Box* box, SrsSimpleStream* stream);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -156,11 +156,11 @@ string srs_dns_resolve(string host, int& family)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
if(getaddrinfo(host.c_str(), NULL, &hints, &r_raw)) {
|
||||||
if(getaddrinfo(host.c_str(), NULL, &hints, &r)) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
char shost[64];
|
char shost[64];
|
||||||
memset(shost, 0, sizeof(shost));
|
memset(shost, 0, sizeof(shost));
|
||||||
|
|
|
||||||
|
|
@ -60,23 +60,23 @@ srs_error_t parse(std::string mp4_file, bool verbose)
|
||||||
|
|
||||||
fprintf(stderr, "\n%s\n", mp4_file.c_str());
|
fprintf(stderr, "\n%s\n", mp4_file.c_str());
|
||||||
while (true) {
|
while (true) {
|
||||||
SrsMp4Box* box = NULL;
|
SrsMp4Box* box_raw = NULL;
|
||||||
// Note that we should use SrsAutoFree to free the ptr which is set later.
|
if ((err = br.read(stream.get(), &box_raw)) != srs_success) {
|
||||||
SrsAutoFree(SrsMp4Box, box);
|
|
||||||
|
|
||||||
if ((err = br.read(stream.get(), &box)) != srs_success) {
|
|
||||||
if (srs_error_code(err) == ERROR_SYSTEM_FILE_EOF) {
|
if (srs_error_code(err) == ERROR_SYSTEM_FILE_EOF) {
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
return srs_error_wrap(err, "read box");
|
return srs_error_wrap(err, "read box");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should use unique pointer after box is created.
|
||||||
|
SrsUniquePtr box(box_raw);
|
||||||
|
|
||||||
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(stream->bytes(), stream->length()));
|
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(stream->bytes(), stream->length()));
|
||||||
if ((err = box->decode(buffer.get())) != srs_success) {
|
if ((err = box->decode(buffer.get())) != srs_success) {
|
||||||
return srs_error_wrap(err, "decode box");
|
return srs_error_wrap(err, "decode box");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = br.skip(box, stream.get())) != srs_success) {
|
if ((err = br.skip(box.get(), stream.get())) != srs_success) {
|
||||||
return srs_error_wrap(err, "skip box");
|
return srs_error_wrap(err, "skip box");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,14 +198,14 @@ srs_error_t srs_srt_listen(srs_srt_t srt_fd, std::string ip, int port)
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r_raw)) {
|
||||||
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r)) {
|
|
||||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
||||||
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
||||||
}
|
}
|
||||||
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
if ((err = do_srs_srt_listen(srt_fd, r)) != srs_success) {
|
if ((err = do_srs_srt_listen(srt_fd, r.get())) != srs_success) {
|
||||||
srt_close(srt_fd);
|
srt_close(srt_fd);
|
||||||
return srs_error_wrap(err, "srt_fd=%d", srt_fd);
|
return srs_error_wrap(err, "srt_fd=%d", srt_fd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -213,11 +213,11 @@ srs_error_t srs_tcp_connect(string server, int port, srs_utime_t tm, srs_netfd_t
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
if(getaddrinfo(server.c_str(), sport, (const addrinfo*)&hints, &r_raw)) {
|
||||||
if(getaddrinfo(server.c_str(), sport, (const addrinfo*)&hints, &r)) {
|
|
||||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "get address info");
|
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "get address info");
|
||||||
}
|
}
|
||||||
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
int sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
|
int sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
|
||||||
if(sock == -1){
|
if(sock == -1){
|
||||||
|
|
@ -291,12 +291,12 @@ srs_error_t srs_tcp_listen(std::string ip, int port, srs_netfd_t* pfd)
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r_raw)) {
|
||||||
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r)) {
|
|
||||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
||||||
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
||||||
}
|
}
|
||||||
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
if ((fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
|
if ((fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
|
||||||
|
|
@ -304,7 +304,7 @@ srs_error_t srs_tcp_listen(std::string ip, int port, srs_netfd_t* pfd)
|
||||||
r->ai_family, r->ai_socktype, r->ai_protocol);
|
r->ai_family, r->ai_socktype, r->ai_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = do_srs_tcp_listen(fd, r, pfd)) != srs_success) {
|
if ((err = do_srs_tcp_listen(fd, r.get(), pfd)) != srs_success) {
|
||||||
::close(fd);
|
::close(fd);
|
||||||
return srs_error_wrap(err, "fd=%d", fd);
|
return srs_error_wrap(err, "fd=%d", fd);
|
||||||
}
|
}
|
||||||
|
|
@ -353,12 +353,12 @@ srs_error_t srs_udp_listen(std::string ip, int port, srs_netfd_t* pfd)
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r_raw)) {
|
||||||
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r)) {
|
|
||||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "getaddrinfo hints=(%d,%d,%d)",
|
||||||
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
hints.ai_family, hints.ai_socktype, hints.ai_flags);
|
||||||
}
|
}
|
||||||
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
if ((fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
|
if ((fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
|
||||||
|
|
@ -366,7 +366,7 @@ srs_error_t srs_udp_listen(std::string ip, int port, srs_netfd_t* pfd)
|
||||||
r->ai_family, r->ai_socktype, r->ai_protocol);
|
r->ai_family, r->ai_socktype, r->ai_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = do_srs_udp_listen(fd, r, pfd)) != srs_success) {
|
if ((err = do_srs_udp_listen(fd, r.get(), pfd)) != srs_success) {
|
||||||
::close(fd);
|
::close(fd);
|
||||||
return srs_error_wrap(err, "fd=%d", fd);
|
return srs_error_wrap(err, "fd=%d", fd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,6 @@ VOID TEST(CoreAutoFreeTest, Free)
|
||||||
char* data = new char[32];
|
char* data = new char[32];
|
||||||
srs_freepa(data);
|
srs_freepa(data);
|
||||||
EXPECT_TRUE(data == NULL);
|
EXPECT_TRUE(data == NULL);
|
||||||
|
|
||||||
if (true) {
|
|
||||||
data = new char[32];
|
|
||||||
SrsAutoFreeA(char, data);
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(data == NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TEST(CoreMacroseTest, Check)
|
VOID TEST(CoreMacroseTest, Check)
|
||||||
|
|
@ -489,3 +483,120 @@ VOID TEST(CoreSmartPtr, UniquePtrArray)
|
||||||
EXPECT_EQ(100, *ptr);
|
EXPECT_EQ(100, *ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mock_free_chars(char* p) {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(CoreSmartPtr, UniquePtrDeleterExample)
|
||||||
|
{
|
||||||
|
if (true) {
|
||||||
|
char* p = (char*)malloc(1024);
|
||||||
|
SrsUniquePtr<char> ptr(p, mock_free_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
addrinfo* r = NULL;
|
||||||
|
getaddrinfo("127.0.0.1", NULL, NULL, &r);
|
||||||
|
SrsUniquePtr<addrinfo> ptr(r, freeaddrinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockSlice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char* bytes_;
|
||||||
|
public:
|
||||||
|
MockSlice(const char* bytes) {
|
||||||
|
bytes_ = bytes;
|
||||||
|
}
|
||||||
|
virtual ~MockSlice() {
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
static void deleter(MockSlice* p) {
|
||||||
|
p->bytes_ = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID TEST(CoreSmartPtr, UniquePtrDeleterSlice)
|
||||||
|
{
|
||||||
|
MockSlice p("Hello");
|
||||||
|
EXPECT_TRUE(p.bytes_ != NULL);
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsUniquePtr<MockSlice> ptr(&p, MockSlice::deleter);
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(p.bytes_ == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockSpecialPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char* bytes_;
|
||||||
|
int size_;
|
||||||
|
public:
|
||||||
|
MockSpecialPacket(char* bytes, int size) {
|
||||||
|
bytes_ = bytes;
|
||||||
|
size_ = size;
|
||||||
|
}
|
||||||
|
virtual ~MockSpecialPacket() {
|
||||||
|
srs_freep(bytes_);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
static void deleter(vector<MockSpecialPacket*>* pkts) {
|
||||||
|
vector<MockSpecialPacket*>::iterator it;
|
||||||
|
for (it = pkts->begin(); it != pkts->end(); ++it) {
|
||||||
|
MockSpecialPacket* pkt = *it;
|
||||||
|
srs_freep(pkt);
|
||||||
|
}
|
||||||
|
pkts->clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID TEST(CoreSmartPtr, UniquePtrDeleterVector)
|
||||||
|
{
|
||||||
|
vector<MockSpecialPacket*> pkts;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
char* bytes = new char[1024];
|
||||||
|
MockSpecialPacket* pkt = new MockSpecialPacket(bytes, 1024);
|
||||||
|
pkts.push_back(pkt);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(10, (int)pkts.size());
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsUniquePtr<vector<MockSpecialPacket*>> ptr(&pkts, MockSpecialPacket::deleter);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, (int)pkts.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockMalloc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char* bytes_;
|
||||||
|
public:
|
||||||
|
MockMalloc(int size) {
|
||||||
|
bytes_ = (char*)malloc(size);
|
||||||
|
}
|
||||||
|
virtual ~MockMalloc() {
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
static void deleter(MockMalloc* p) {
|
||||||
|
free((void*)p->bytes_);
|
||||||
|
p->bytes_ = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID TEST(CoreSmartPtr, UniquePtrDeleterMalloc)
|
||||||
|
{
|
||||||
|
MockMalloc p(1024);
|
||||||
|
EXPECT_TRUE(p.bytes_ != NULL);
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsUniquePtr<MockMalloc> ptr(&p, MockMalloc::deleter);
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(p.bytes_ == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -626,7 +626,7 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray)
|
||||||
SrsMessageArray arr(3);
|
SrsMessageArray arr(3);
|
||||||
|
|
||||||
SrsMessageArray* parr = &arr;
|
SrsMessageArray* parr = &arr;
|
||||||
SrsAutoFreeH(SrsMessageArray, parr, srs_utest_free_message_array);
|
SrsUniquePtr<SrsMessageArray> parr2(parr, srs_utest_free_message_array);
|
||||||
|
|
||||||
arr.msgs[0] = msg.copy();
|
arr.msgs[0] = msg.copy();
|
||||||
EXPECT_EQ(1, msg.count());
|
EXPECT_EQ(1, msg.count());
|
||||||
|
|
@ -643,7 +643,7 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray)
|
||||||
SrsMessageArray arr(3);
|
SrsMessageArray arr(3);
|
||||||
|
|
||||||
SrsMessageArray* parr = &arr;
|
SrsMessageArray* parr = &arr;
|
||||||
SrsAutoFreeH(SrsMessageArray, parr, srs_utest_free_message_array);
|
SrsUniquePtr<SrsMessageArray> parr2(parr, srs_utest_free_message_array);
|
||||||
|
|
||||||
arr.msgs[0] = msg.copy();
|
arr.msgs[0] = msg.copy();
|
||||||
EXPECT_EQ(1, msg.count());
|
EXPECT_EQ(1, msg.count());
|
||||||
|
|
|
||||||
|
|
@ -2999,7 +2999,7 @@ VOID TEST(ProtocolRTMPTest, OthersAll)
|
||||||
SrsMessageArray h(10);
|
SrsMessageArray h(10);
|
||||||
|
|
||||||
SrsMessageArray* parr = &h;
|
SrsMessageArray* parr = &h;
|
||||||
SrsAutoFreeH(SrsMessageArray, parr, srs_utest_free_message_array);
|
SrsUniquePtr<SrsMessageArray> parr2(parr, srs_utest_free_message_array);
|
||||||
|
|
||||||
h.msgs[0] = new SrsSharedPtrMessage();
|
h.msgs[0] = new SrsSharedPtrMessage();
|
||||||
h.msgs[1] = new SrsSharedPtrMessage();
|
h.msgs[1] = new SrsSharedPtrMessage();
|
||||||
|
|
|
||||||
|
|
@ -1118,9 +1118,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("127.0.0.1", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("127.0.0.1", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1131,9 +1131,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("192.168.0.1", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("192.168.0.1", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1176,9 +1176,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("2001:da8:6000:291:21f:d0ff:fed4:928c", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("2001:da8:6000:291:21f:d0ff:fed4:928c", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1187,9 +1187,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("3ffe:dead:beef::1", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("3ffe:dead:beef::1", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1200,9 +1200,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("::", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("::", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1213,9 +1213,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("fec0::", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("fec0::", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1226,9 +1226,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("FE80::", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("FE80::", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
@ -1239,9 +1239,9 @@ VOID TEST(TCPServerTest, CoverUtility)
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
|
|
||||||
addrinfo* r = NULL;
|
addrinfo* r_raw = NULL;
|
||||||
SrsAutoFreeH(addrinfo, r, freeaddrinfo);
|
ASSERT_TRUE(!getaddrinfo("::1", NULL, &hints, &r_raw));
|
||||||
ASSERT_TRUE(!getaddrinfo("::1", NULL, &hints, &r));
|
SrsUniquePtr<addrinfo> r(r_raw, freeaddrinfo);
|
||||||
|
|
||||||
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ VOID TEST(StTest, StUtimePerformance)
|
||||||
|
|
||||||
EXPECT_LT(gettimeofday_elapsed_time > st_utime_elapsed_time ?
|
EXPECT_LT(gettimeofday_elapsed_time > st_utime_elapsed_time ?
|
||||||
gettimeofday_elapsed_time - st_utime_elapsed_time :
|
gettimeofday_elapsed_time - st_utime_elapsed_time :
|
||||||
st_utime_elapsed_time - gettimeofday_elapsed_time, 10);
|
st_utime_elapsed_time - gettimeofday_elapsed_time, 30);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user