winlin

refine the ptr array free, 0.9.96

@@ -474,6 +474,7 @@ int SrsEdgeForwarder::cycle() @@ -474,6 +474,7 @@ int SrsEdgeForwarder::cycle()
474 srs_verbose("no packets to forward."); 474 srs_verbose("no packets to forward.");
475 continue; 475 continue;
476 } 476 }
  477 + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);
477 478
478 // all msgs to forward to origin. 479 // all msgs to forward to origin.
479 // @remark, becareful, all msgs must be free explicitly, 480 // @remark, becareful, all msgs must be free explicitly,
@@ -484,24 +485,12 @@ int SrsEdgeForwarder::cycle() @@ -484,24 +485,12 @@ int SrsEdgeForwarder::cycle()
484 srs_assert(msg); 485 srs_assert(msg);
485 msgs[i] = NULL; 486 msgs[i] = NULL;
486 487
487 - // never use free msgs array, for it will memory leak.  
488 - // if error, directly free msgs.  
489 - if (ret != ERROR_SUCCESS) {  
490 - srs_freep(msg);  
491 - continue;  
492 - }  
493 -  
494 if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) { 488 if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) {
495 srs_error("edge publish forwarder send message to server failed. ret=%d", ret); 489 srs_error("edge publish forwarder send message to server failed. ret=%d", ret);
496 - continue;  
497 - }  
498 - }  
499 - // free the array itself.  
500 - srs_freep(msgs);  
501 - if (ret != ERROR_SUCCESS) {  
502 return ret; 490 return ret;
503 } 491 }
504 } 492 }
  493 + }
505 494
506 return ret; 495 return ret;
507 } 496 }
@@ -352,6 +352,7 @@ int SrsForwarder::forward() @@ -352,6 +352,7 @@ int SrsForwarder::forward()
352 srs_verbose("no packets to forward."); 352 srs_verbose("no packets to forward.");
353 continue; 353 continue;
354 } 354 }
  355 + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);
355 356
356 // all msgs to forward. 357 // all msgs to forward.
357 // @remark, becareful, all msgs must be free explicitly, 358 // @remark, becareful, all msgs must be free explicitly,
@@ -362,24 +363,12 @@ int SrsForwarder::forward() @@ -362,24 +363,12 @@ int SrsForwarder::forward()
362 srs_assert(msg); 363 srs_assert(msg);
363 msgs[i] = NULL; 364 msgs[i] = NULL;
364 365
365 - // never use free msgs array, for it will memory leak.  
366 - // if error, directly free msgs.  
367 - if (ret != ERROR_SUCCESS) {  
368 - srs_freep(msg);  
369 - continue;  
370 - }  
371 -  
372 if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) { 366 if ((ret = client->send_and_free_message(msg)) != ERROR_SUCCESS) {
373 srs_error("forwarder send message to server failed. ret=%d", ret); 367 srs_error("forwarder send message to server failed. ret=%d", ret);
374 - continue;  
375 - }  
376 - }  
377 - // free the array itself.  
378 - srs_freep(msgs);  
379 - if (ret != ERROR_SUCCESS) {  
380 return ret; 368 return ret;
381 } 369 }
382 } 370 }
  371 + }
383 372
384 return ret; 373 return ret;
385 } 374 }
@@ -513,6 +513,7 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -513,6 +513,7 @@ int SrsRtmpConn::playing(SrsSource* source)
513 srs_verbose("no packets in queue."); 513 srs_verbose("no packets in queue.");
514 continue; 514 continue;
515 } 515 }
  516 + SrsAutoFreeArray(SrsSharedPtrMessage, msgs, count);
516 517
517 // sendout messages 518 // sendout messages
518 // @remark, becareful, all msgs must be free explicitly, 519 // @remark, becareful, all msgs must be free explicitly,
@@ -526,13 +527,6 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -526,13 +527,6 @@ int SrsRtmpConn::playing(SrsSource* source)
526 527
527 srs_assert(msg); 528 srs_assert(msg);
528 529
529 - // never use free msgs array, for it will memory leak.  
530 - // if error, directly free msgs.  
531 - if (ret != ERROR_SUCCESS) {  
532 - srs_freep(msg);  
533 - continue;  
534 - }  
535 -  
536 // foreach msg, collect the duration. 530 // foreach msg, collect the duration.
537 // @remark: never use msg when sent it, for the protocol sdk will free it. 531 // @remark: never use msg when sent it, for the protocol sdk will free it.
538 if (starttime < 0 || starttime > msg->header.timestamp) { 532 if (starttime < 0 || starttime > msg->header.timestamp) {
@@ -543,14 +537,9 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -543,14 +537,9 @@ int SrsRtmpConn::playing(SrsSource* source)
543 537
544 if ((ret = rtmp->send_and_free_message(msg)) != ERROR_SUCCESS) { 538 if ((ret = rtmp->send_and_free_message(msg)) != ERROR_SUCCESS) {
545 srs_error("send message to client failed. ret=%d", ret); 539 srs_error("send message to client failed. ret=%d", ret);
546 - continue;  
547 - }  
548 - }  
549 - // free the array itself.  
550 - srs_freep(msgs);  
551 - if (ret != ERROR_SUCCESS) {  
552 return ret; 540 return ret;
553 } 541 }
  542 + }
554 543
555 // if duration specified, and exceed it, stop play live. 544 // if duration specified, and exceed it, stop play live.
556 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45 545 // @see: https://github.com/winlinvip/simple-rtmp-server/issues/45
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "95" 34 +#define VERSION_REVISION "96"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "srs" 37 #define RTMP_SIG_SRS_KEY "srs"
@@ -31,11 +31,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,11 +31,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 /** 33 /**
34 -* auto free the instance in the current scope. 34 +* auto free the instance in the current scope, for instance, MyClass* ptr,
  35 +* which is a ptr and this class will:
  36 +* 1. free the ptr.
  37 +* 2. set ptr to NULL.
  38 +* Usage:
  39 +* MyClass* po = new MyClass();
  40 +* // ...... use po
  41 +* SrsAutoFree(MyClass, po);
35 */ 42 */
36 #define SrsAutoFree(className, instance) \ 43 #define SrsAutoFree(className, instance) \
37 - __SrsAutoFree<className> _auto_free_##instance((className**)&instance)  
38 - 44 + __SrsAutoFree<className> _auto_free_##instance(&instance)
39 template<class T> 45 template<class T>
40 class __SrsAutoFree 46 class __SrsAutoFree
41 { 47 {
@@ -44,13 +50,12 @@ private: @@ -44,13 +50,12 @@ private:
44 public: 50 public:
45 /** 51 /**
46 * auto delete the ptr. 52 * auto delete the ptr.
47 - * @is_array a bool value indicates whether the ptr is a array.  
48 */ 53 */
49 - __SrsAutoFree(T** _ptr){ 54 + __SrsAutoFree(T** _ptr) {
50 ptr = _ptr; 55 ptr = _ptr;
51 } 56 }
52 57
53 - virtual ~__SrsAutoFree(){ 58 + virtual ~__SrsAutoFree() {
54 if (ptr == NULL || *ptr == NULL) { 59 if (ptr == NULL || *ptr == NULL) {
55 return; 60 return;
56 } 61 }
@@ -66,11 +71,48 @@ public: @@ -66,11 +71,48 @@ public:
66 * which stores 10 MyClass* objects, this class will: 71 * which stores 10 MyClass* objects, this class will:
67 * 1. free each MyClass* in array. 72 * 1. free each MyClass* in array.
68 * 2. free the msgs itself. 73 * 2. free the msgs itself.
  74 +* 3. set msgs to NULL.
69 * @remark, MyClass* msgs[] equals to MyClass**, the ptr array equals ptr to ptr. 75 * @remark, MyClass* msgs[] equals to MyClass**, the ptr array equals ptr to ptr.
  76 +* Usage:
  77 +* MyClass* msgs[10];
  78 +* // ...... use msgs.
  79 +* SrsAutoFreeArray(MyClass, msgs, 10);
70 */ 80 */
  81 +#define SrsAutoFreeArray(className, instance, size) \
  82 + __SrsAutoFreeArray<className> _auto_free_array_##instance(&instance, size)
71 template<class T> 83 template<class T>
72 -class SrsObjectPtrArrayAutoFree 84 +class __SrsAutoFreeArray
73 { 85 {
  86 +private:
  87 + T*** ptr;
  88 + int size;
  89 +public:
  90 + /**
  91 + * auto delete the ptr array.
  92 + */
  93 + __SrsAutoFreeArray(T*** _ptr, int _size) {
  94 + ptr = _ptr;
  95 + size = _size;
  96 + }
  97 +
  98 + virtual ~__SrsAutoFreeArray() {
  99 + if (ptr == NULL || *ptr == NULL) {
  100 + return;
  101 + }
  102 +
  103 + T** arr = *ptr;
  104 + for (int i = 0; i < size; i++) {
  105 + T* pobj = arr[i];
  106 + if (pobj) {
  107 + delete pobj;
  108 + arr[i] = NULL;
  109 + }
  110 + }
  111 +
  112 + delete arr;
  113 +
  114 + *ptr = NULL;
  115 + }
74 }; 116 };
75 117
76 #endif 118 #endif