diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index ba1cd9002..d84c08501 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -474,6 +474,7 @@ int SrsEdgeForwarder::cycle() srs_verbose("no packets to forward."); continue; } + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count); // all msgs to forward to origin. // @remark, becareful, all msgs must be free explicitly, @@ -484,23 +485,11 @@ int SrsEdgeForwarder::cycle() srs_assert(msg); msgs[i] = NULL; - // never use free msgs array, for it will memory leak. - // if error, directly free msgs. - if (ret != ERROR_SUCCESS) { - srs_freep(msg); - continue; - } - if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) { srs_error("edge publish forwarder send message to server failed. ret=%d", ret); - continue; + return ret; } } - // free the array itself. - srs_freep(msgs); - if (ret != ERROR_SUCCESS) { - return ret; - } } return ret; diff --git a/trunk/src/app/srs_app_forward.cpp b/trunk/src/app/srs_app_forward.cpp index deae8c178..280622493 100644 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -352,6 +352,7 @@ int SrsForwarder::forward() srs_verbose("no packets to forward."); continue; } + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count); // all msgs to forward. // @remark, becareful, all msgs must be free explicitly, @@ -362,23 +363,11 @@ int SrsForwarder::forward() srs_assert(msg); msgs[i] = NULL; - // never use free msgs array, for it will memory leak. - // if error, directly free msgs. - if (ret != ERROR_SUCCESS) { - srs_freep(msg); - continue; - } - if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) { srs_error("forwarder send message to server failed. ret=%d", ret); - continue; + return ret; } } - // free the array itself. - srs_freep(msgs); - if (ret != ERROR_SUCCESS) { - return ret; - } } return ret; diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 22d863361..5a3628926 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -513,6 +513,7 @@ int SrsRtmpConn::playing(SrsSource* source) srs_verbose("no packets in queue."); continue; } + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count); // sendout messages // @remark, becareful, all msgs must be free explicitly, @@ -526,13 +527,6 @@ int SrsRtmpConn::playing(SrsSource* source) srs_assert(msg); - // never use free msgs array, for it will memory leak. - // if error, directly free msgs. - if (ret != ERROR_SUCCESS) { - srs_freep(msg); - continue; - } - // foreach msg, collect the duration. // @remark: never use msg when sent it, for the protocol sdk will free it. if (starttime < 0 || starttime > msg->header.timestamp) { @@ -543,14 +537,9 @@ int SrsRtmpConn::playing(SrsSource* source) if ((ret = rtmp->send_and_free_message(msg)) != ERROR_SUCCESS) { srs_error("send message to client failed. ret=%d", ret); - continue; + return ret; } } - // free the array itself. - srs_freep(msgs); - if (ret != ERROR_SUCCESS) { - return ret; - } // if duration specified, and exceed it, stop play live. // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 5c4f369a8..8d3a4870a 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "95" +#define VERSION_REVISION "96" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "srs" diff --git a/trunk/src/core/srs_core_autofree.hpp b/trunk/src/core/srs_core_autofree.hpp index 17c9afd63..2de455fd1 100644 --- a/trunk/src/core/srs_core_autofree.hpp +++ b/trunk/src/core/srs_core_autofree.hpp @@ -31,11 +31,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include /** -* auto free the instance in the current scope. +* auto 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); */ #define SrsAutoFree(className, instance) \ - __SrsAutoFree _auto_free_##instance((className**)&instance) - + __SrsAutoFree _auto_free_##instance(&instance) template class __SrsAutoFree { @@ -44,13 +50,12 @@ private: public: /** * auto delete the ptr. - * @is_array a bool value indicates whether the ptr is a array. */ - __SrsAutoFree(T** _ptr){ + __SrsAutoFree(T** _ptr) { ptr = _ptr; } - virtual ~__SrsAutoFree(){ + virtual ~__SrsAutoFree() { if (ptr == NULL || *ptr == NULL) { return; } @@ -64,13 +69,50 @@ public: /** * auto free the array ptrs, for example, MyClass* msgs[10], * which stores 10 MyClass* objects, this class will: -* 1. free each MyClass* in array. -* 2. free the msgs itself. +* 1. free each MyClass* in array. +* 2. free the msgs itself. +* 3. set msgs to NULL. * @remark, MyClass* msgs[] equals to MyClass**, the ptr array equals ptr to ptr. +* Usage: +* MyClass* msgs[10]; +* // ...... use msgs. +* SrsAutoFreeArray(MyClass, msgs, 10); */ +#define SrsAutoFreeArray(className, instance, size) \ + __SrsAutoFreeArray _auto_free_array_##instance(&instance, size) template -class SrsObjectPtrArrayAutoFree +class __SrsAutoFreeArray { +private: + T*** ptr; + int size; +public: + /** + * auto delete the ptr array. + */ + __SrsAutoFreeArray(T*** _ptr, int _size) { + ptr = _ptr; + size = _size; + } + + virtual ~__SrsAutoFreeArray() { + if (ptr == NULL || *ptr == NULL) { + return; + } + + T** arr = *ptr; + for (int i = 0; i < size; i++) { + T* pobj = arr[i]; + if (pobj) { + delete pobj; + arr[i] = NULL; + } + } + + delete arr; + + *ptr = NULL; + } }; #endif \ No newline at end of file