winlin

for bug #251, refine the mic algorithm. 2.0.63

@@ -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 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 61 34 +#define VERSION_REVISION 63
35 // server info. 35 // server info.
36 #define RTMP_SIG_SRS_KEY "SRS" 36 #define RTMP_SIG_SRS_KEY "SRS"
37 #define RTMP_SIG_SRS_ROLE "origin/edge server" 37 #define RTMP_SIG_SRS_ROLE "origin/edge server"
@@ -97,13 +97,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -97,13 +97,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
97 // the default config of mw. 97 // the default config of mw.
98 #define SRS_PERF_MW_SLEEP 350 98 #define SRS_PERF_MW_SLEEP 350
99 /** 99 /**
100 -* how many msgs can be send entirely.  
101 -* for play clients to get msgs then totally send out.  
102 -* for the mw sleep set to 1800, the msgs is about 133.  
103 -* @remark, recomment to 128.  
104 -*/  
105 -#define SRS_PERF_MW_MSGS 128  
106 -/**  
107 * use iovs cache in each msg, 100 * use iovs cache in each msg,
108 * for the shared ptr message, we calc once and used for every copy. 101 * for the shared ptr message, we calc once and used for every copy.
109 * @see https://github.com/winlinvip/simple-rtmp-server/issues/251 102 * @see https://github.com/winlinvip/simple-rtmp-server/issues/251
@@ -111,6 +104,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -111,6 +104,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
111 * @remark when reload change the chunk size, previous clients error. 104 * @remark when reload change the chunk size, previous clients error.
112 */ 105 */
113 #undef SRS_PERF_MW_MSG_IOVS_CACHE 106 #undef SRS_PERF_MW_MSG_IOVS_CACHE
  107 +/**
  108 +* how many msgs can be send entirely.
  109 +* for play clients to get msgs then totally send out.
  110 +* for the mw sleep set to 1800, the msgs is about 133.
  111 +* @remark, recomment to 128.
  112 +* @remark, when mic enabled, use larger iovs cache, to 512.
  113 +*/
  114 +#ifndef SRS_PERF_MW_MSG_IOVS_CACHE
  115 + #define SRS_PERF_MW_MSGS 128
  116 +#else
  117 + #define SRS_PERF_MW_MSGS 512
  118 +#endif
114 119
115 /** 120 /**
116 * whether set the socket send buffer size. 121 * whether set the socket send buffer size.
@@ -135,6 +135,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -135,6 +135,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
135 #define ERROR_OpenSslGetPeerPublicKey 2038 135 #define ERROR_OpenSslGetPeerPublicKey 2038
136 #define ERROR_OpenSslComputeSharedKey 2039 136 #define ERROR_OpenSslComputeSharedKey 2039
137 #define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040 137 #define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040
  138 +#define ERROR_RTMP_MIC_CACHE_OVERFLOW 2041
138 // 139 //
139 // system control message, 140 // system control message,
140 // not an error, but special control logic. 141 // not an error, but special control logic.
@@ -422,7 +422,7 @@ int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate( @@ -422,7 +422,7 @@ int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate(
422 if (mh->payload_length % chunk_size) { 422 if (mh->payload_length % chunk_size) {
423 nb_chunks++; 423 nb_chunks++;
424 } 424 }
425 - nb_iovs = 1/*cid*/ + 1/*size*/ + 1 /*type*/+ 1/*chunk*/; 425 + nb_iovs = 1/*cid*/ + 1/*size*//*type*/+ 1/*chunk*/;
426 // left chunks, always cid+chunk. 426 // left chunks, always cid+chunk.
427 if (nb_chunks > 0) { 427 if (nb_chunks > 0) {
428 nb_iovs += (nb_chunks - 1) * 2; 428 nb_iovs += (nb_chunks - 1) * 2;
@@ -448,19 +448,16 @@ int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate( @@ -448,19 +448,16 @@ int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate(
448 iov[0].iov_len = 1; 448 iov[0].iov_len = 1;
449 449
450 // size(payload length), 3B 450 // size(payload length), 3B
  451 + // type(message type), 1B
451 iov[1].iov_base = mic_c0 + 4; 452 iov[1].iov_base = mic_c0 + 4;
452 - iov[1].iov_len = 3;  
453 -  
454 - // type(message type)  
455 - iov[2].iov_base = mic_c0 + 7;  
456 - iov[2].iov_len = 1; 453 + iov[1].iov_len = 4;
457 454
458 // chunk 455 // chunk
459 - iov[3].iov_base = p;  
460 - iov[3].iov_len = payload_size; 456 + iov[2].iov_base = p;
  457 + iov[2].iov_len = payload_size;
461 458
462 // move to next iovs. 459 // move to next iovs.
463 - iov += 4; 460 + iov += 3;
464 } else { 461 } else {
465 // c3 462 // c3
466 iov[0].iov_base = &mic_c3; 463 iov[0].iov_base = &mic_c3;
@@ -488,8 +485,6 @@ SrsSharedPtrMessage::SrsSharedPtrMessage() @@ -488,8 +485,6 @@ SrsSharedPtrMessage::SrsSharedPtrMessage()
488 485
489 #ifdef SRS_PERF_MW_MSG_IOVS_CACHE 486 #ifdef SRS_PERF_MW_MSG_IOVS_CACHE
490 mic_etime_present = false; 487 mic_etime_present = false;
491 - iovs = NULL;  
492 - nb_iovs = 0;  
493 #endif 488 #endif
494 } 489 }
495 490
@@ -502,10 +497,6 @@ SrsSharedPtrMessage::~SrsSharedPtrMessage() @@ -502,10 +497,6 @@ SrsSharedPtrMessage::~SrsSharedPtrMessage()
502 ptr->shared_count--; 497 ptr->shared_count--;
503 } 498 }
504 } 499 }
505 -  
506 -#ifdef SRS_PERF_MW_MSG_IOVS_CACHE  
507 - srs_freep(iovs);  
508 -#endif  
509 } 500 }
510 501
511 int SrsSharedPtrMessage::create(SrsCommonMessage* msg) 502 int SrsSharedPtrMessage::create(SrsCommonMessage* msg)
@@ -598,9 +589,26 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size) @@ -598,9 +589,26 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size)
598 } 589 }
599 } 590 }
600 591
  592 + return ret;
  593 +}
  594 +
  595 +int SrsSharedPtrMessage::mic_iovs_dump(iovec* iovs, int max_nb_iovs)
  596 +{
601 // calc the private iovs 597 // calc the private iovs
602 char* pp = NULL; 598 char* pp = NULL;
603 599
  600 + // calc number of iovs.
  601 + int nb_iovs = 1/*time*/ + 1/*sid*/;
  602 + // insert etime before all chunks.
  603 + if (mic_etime_present) {
  604 + nb_iovs += ptr->nb_chunks;
  605 + }
  606 +
  607 + // not enough, return nagetive to try another loop.
  608 + if (max_nb_iovs < nb_iovs + ptr->nb_iovs) {
  609 + return -1;
  610 + }
  611 +
604 // timestamp for c0/c3 612 // timestamp for c0/c3
605 u_int32_t timestamp = (u_int32_t)header.timestamp; 613 u_int32_t timestamp = (u_int32_t)header.timestamp;
606 mic_etime_present = timestamp >= RTMP_EXTENDED_TIMESTAMP; 614 mic_etime_present = timestamp >= RTMP_EXTENDED_TIMESTAMP;
@@ -654,72 +662,57 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size) @@ -654,72 +662,57 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size)
654 *p++ = pp[0]; 662 *p++ = pp[0];
655 } 663 }
656 664
657 - // calc number of iovs.  
658 - nb_iovs = 1/*time*/ + 1/*sid*/;  
659 - // insert etime before all chunks.  
660 - if (mic_etime_present) {  
661 - nb_iovs += ptr->nb_chunks;  
662 - }  
663 -  
664 - // create iovs  
665 - srs_freep(iovs);  
666 - iovs = new iovec[nb_iovs]; 665 + // dumps all ovs
  666 + iovec* shared = ptr->iovs;
  667 + iovec* iov = iovs;
667 668
  669 + // dump the c0 chunk
  670 + // cid
  671 + iov->iov_len = shared->iov_len;
  672 + iov->iov_base = shared->iov_base;
  673 + iov++; shared++;
668 // time, 3B 674 // time, 3B
669 - iovs[0].iov_base = mic_c0_time;  
670 - iovs[0].iov_len = 3;  
671 - 675 + iov->iov_base = mic_c0_time;
  676 + iov->iov_len = 3;
  677 + iov++;
  678 + // size, type
  679 + iov->iov_len = shared->iov_len;
  680 + iov->iov_base = shared->iov_base;
  681 + iov++; shared++;
672 // sid, 4B 682 // sid, 4B
673 - iovs[1].iov_base = mic_c0_sid;  
674 - iovs[1].iov_len = 4;  
675 -  
676 - // etime, 4B for each chunks.  
677 - for (int i = 2; i < nb_iovs; i++) {  
678 - iovs[i].iov_base = mic_etime;  
679 - iovs[i].iov_len = 4;  
680 - }  
681 -  
682 - return ret;  
683 -}  
684 -  
685 -int SrsSharedPtrMessage::mic_iovs_count()  
686 -{  
687 - return nb_iovs + ptr->nb_iovs;  
688 -}  
689 -  
690 -int SrsSharedPtrMessage::mic_iovs_dump(iovec* _iovs, int _nb_iovs)  
691 -{  
692 - int shared_index = 0;  
693 - int private_index = 0;  
694 - int index = 0;  
695 -  
696 - // dumps all.  
697 - srs_assert(nb_iovs + ptr->nb_iovs <= _nb_iovs);  
698 -  
699 - // dump the c0 chunk  
700 - _iovs[index++] = ptr->iovs[shared_index++]; // cid  
701 - _iovs[index++] = iovs[private_index++]; // time  
702 - _iovs[index++] = ptr->iovs[shared_index++]; // size  
703 - _iovs[index++] = ptr->iovs[shared_index++]; // type  
704 - _iovs[index++] = iovs[private_index++]; // sid 683 + iov->iov_base = mic_c0_sid;
  684 + iov->iov_len = 4;
  685 + iov++;
  686 + // etime, 4B
705 if (mic_etime_present) { 687 if (mic_etime_present) {
706 - _iovs[index++] = iovs[private_index++]; // etime 688 + // etime
  689 + iov->iov_base = mic_etime;
  690 + iov->iov_len = 4;
  691 + iov++;
707 } 692 }
708 - _iovs[index++] = ptr->iovs[shared_index++]; // chunk 693 + // chunk
  694 + iov->iov_len = shared->iov_len;
  695 + iov->iov_base = shared->iov_base;
  696 + iov++; shared++;
709 697
710 // dump left c3 chunks 698 // dump left c3 chunks
711 for (int i = 1; i < ptr->nb_chunks; i++) { 699 for (int i = 1; i < ptr->nb_chunks; i++) {
712 - _iovs[index++] = ptr->iovs[shared_index++]; // cid 700 + // cid
  701 + iov->iov_len = shared->iov_len;
  702 + iov->iov_base = shared->iov_base;
  703 + iov++; shared++;
713 if (mic_etime_present) { 704 if (mic_etime_present) {
714 - _iovs[index++] = iovs[private_index++]; // etime 705 + // etime
  706 + iov->iov_base = mic_etime;
  707 + iov->iov_len = 4;
  708 + iov++;
715 } 709 }
716 - _iovs[index++] = ptr->iovs[shared_index++]; // chunk 710 + // chunk
  711 + iov->iov_len = shared->iov_len;
  712 + iov->iov_base = shared->iov_base;
  713 + iov++; shared++;
717 } 714 }
718 715
719 - srs_assert(index == private_index + shared_index);  
720 - srs_assert(index == nb_iovs + ptr->nb_iovs);  
721 - srs_assert(index <= _nb_iovs);  
722 -  
723 return nb_iovs + ptr->nb_iovs; 716 return nb_iovs + ptr->nb_iovs;
724 } 717 }
725 #endif 718 #endif
@@ -955,7 +948,6 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) @@ -955,7 +948,6 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
955 int ret = ERROR_SUCCESS; 948 int ret = ERROR_SUCCESS;
956 949
957 #ifndef SRS_PERF_MW_MSG_IOVS_CACHE 950 #ifndef SRS_PERF_MW_MSG_IOVS_CACHE
958 - // TODO: FIXME: use cache system instead.  
959 int iov_index = 0; 951 int iov_index = 0;
960 iovec* iov = out_iovs + iov_index; 952 iovec* iov = out_iovs + iov_index;
961 953
@@ -1042,10 +1034,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) @@ -1042,10 +1034,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
1042 1034
1043 // when c0c3 cache dry, 1035 // when c0c3 cache dry,
1044 // sendout all messages and reset the cache, then send again. 1036 // sendout all messages and reset the cache, then send again.
1045 - if ((ret = skt->writev(out_iovs, iov_index, NULL)) != ERROR_SUCCESS) {  
1046 - if (!srs_is_client_gracefully_close(ret)) {  
1047 - srs_error("send msgs with writev failed. ret=%d", ret);  
1048 - } 1037 + if ((ret = do_iovs_send(out_iovs, iov_index)) != ERROR_SUCCESS) {
1049 return ret; 1038 return ret;
1050 } 1039 }
1051 1040
@@ -1059,76 +1048,73 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) @@ -1059,76 +1048,73 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
1059 } 1048 }
1060 } 1049 }
1061 } 1050 }
  1051 +
  1052 + // maybe the iovs already sendout when c0c3 cache dry,
  1053 + // so just ignore when no iovs to send.
  1054 + if (iov_index <= 0) {
  1055 + return ret;
  1056 + }
  1057 + srs_info("mw %d msgs in %d iovs, max_msgs=%d, nb_out_iovs=%d",
  1058 + nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);
  1059 +
  1060 + return do_iovs_send(out_iovs, iov_index);
1062 #else 1061 #else
1063 // send all iovs for all msgs. 1062 // send all iovs for all msgs.
1064 - int total_iovs = 0;  
1065 - for (int i = 0; i < nb_msgs; i++) { 1063 + int msg_sent = 0;
  1064 + while (msg_sent < nb_msgs) {
  1065 + int iov_index = 0;
  1066 + for (int i = msg_sent; i < nb_msgs; i++) {
1066 SrsSharedPtrMessage* msg = msgs[i]; 1067 SrsSharedPtrMessage* msg = msgs[i];
  1068 +
  1069 + // evaluate
1067 if ((ret = msg->mic_evaluate(out_chunk_size)) != ERROR_SUCCESS) { 1070 if ((ret = msg->mic_evaluate(out_chunk_size)) != ERROR_SUCCESS) {
1068 - srs_error("mic evaluate failed, chunk=%d. ret=%d", out_chunk_size, ret);  
1069 return ret; 1071 return ret;
1070 } 1072 }
1071 - total_iovs += msg->mic_iovs_count();  
1072 - }  
1073 - srs_verbose("mic nb_iovs=%d, max=%d", total_iovs, nb_out_iovs);  
1074 -  
1075 - // realloc the iovs if exceed,  
1076 - // for we donot know how many messges maybe to send entirely,  
1077 - // we just alloc the iovs, it's ok.  
1078 - if (total_iovs > nb_out_iovs) {  
1079 - srs_warn("resize iovs %d => %d, msgs=%d, max_msgs=%d",  
1080 - nb_out_iovs, total_iovs, nb_msgs, SRS_PERF_MW_MSGS);  
1081 -  
1082 - nb_out_iovs = total_iovs;  
1083 - int realloc_size = sizeof(iovec) * nb_out_iovs;  
1084 - out_iovs = (iovec*)realloc(out_iovs, realloc_size);  
1085 - }  
1086 1073
1087 - // dumps iovs  
1088 - int iov_index = 0;  
1089 - for (int i = 0; i < nb_msgs; i++) {  
1090 - SrsSharedPtrMessage* msg = msgs[i];  
1091 - iov_index += msg->mic_iovs_dump( 1074 + // dump msg to iovec.
  1075 + int ok_iovs = msg->mic_iovs_dump(
1092 out_iovs + iov_index, nb_out_iovs - iov_index 1076 out_iovs + iov_index, nb_out_iovs - iov_index
1093 ); 1077 );
  1078 + // protocol iovs cache exceed.
  1079 + if (ok_iovs <= 0) {
  1080 + break;
1094 } 1081 }
1095 -#endif  
1096 1082
1097 - // maybe the iovs already sendout when c0c3 cache dry,  
1098 - // so just ignore when no iovs to send. 1083 + // ok, dump next.
  1084 + msg_sent++;
  1085 + iov_index += ok_iovs;
  1086 + }
  1087 + srs_info("mic nb_iovs=%d, msgs=%d, msg_sent=%d, iovs_sent=%d",
  1088 + nb_out_iovs, nb_msgs, msg_sent, iov_index);
  1089 +
  1090 + // cache not enough.
1099 if (iov_index <= 0) { 1091 if (iov_index <= 0) {
  1092 + ret = ERROR_RTMP_MIC_CACHE_OVERFLOW;
  1093 + srs_warn("mic iovs overflow, nb_iovs=%d, msgs=%d, msg_sent=%d, iovs_sent=%d, ret=%d",
  1094 + nb_out_iovs, nb_msgs, msg_sent, iov_index, ret);
1100 return ret; 1095 return ret;
1101 } 1096 }
1102 -#if 0  
1103 - // calc the bytes of iovs, for debug.  
1104 - int nb_bytes = 0;  
1105 - for (int i = 0; i < iov_index; i++) {  
1106 - iovec* iov = out_iovs + i;  
1107 - nb_bytes += iov->iov_len;  
1108 - }  
1109 - #ifndef SRS_PERF_MW_MSG_IOVS_CACHE  
1110 - srs_info("mw %d msgs %dB in %d iovs, max_msgs=%d, nb_out_iovs=%d",  
1111 - nb_msgs, nb_bytes, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);  
1112 - #else  
1113 - srs_info("mic nb_iovs=%d, max=%d, msgs=%d %dB",  
1114 - total_iovs, nb_out_iovs, nb_msgs, nb_bytes);  
1115 - #endif  
1116 -#else  
1117 - #ifndef SRS_PERF_MW_MSG_IOVS_CACHE  
1118 - srs_info("mw %d msgs in %d iovs, max_msgs=%d, nb_out_iovs=%d",  
1119 - nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);  
1120 - #else  
1121 - srs_info("mic nb_iovs=%d, max=%d, msgs=%d",  
1122 - total_iovs, nb_out_iovs, nb_msgs);  
1123 - #endif 1097 +
  1098 + // send out these iovs.
  1099 + if ((ret = do_iovs_send(out_iovs, iov_index)) != ERROR_SUCCESS) {
  1100 + return ret;
  1101 + }
  1102 + }
  1103 +
  1104 + return ret;
1124 #endif 1105 #endif
  1106 +}
  1107 +
  1108 +int SrsProtocol::do_iovs_send(iovec* iovs, int size)
  1109 +{
  1110 + int ret = ERROR_SUCCESS;
1125 1111
1126 // the limits of writev iovs. 1112 // the limits of writev iovs.
1127 static int limits = sysconf(_SC_IOV_MAX); 1113 static int limits = sysconf(_SC_IOV_MAX);
1128 1114
1129 // send in a time. 1115 // send in a time.
1130 - if (iov_index < limits) {  
1131 - if ((ret = skt->writev(out_iovs, iov_index, NULL)) != ERROR_SUCCESS) { 1116 + if (size < limits) {
  1117 + if ((ret = skt->writev(iovs, size, NULL)) != ERROR_SUCCESS) {
1132 if (!srs_is_client_gracefully_close(ret)) { 1118 if (!srs_is_client_gracefully_close(ret)) {
1133 srs_error("send with writev failed. ret=%d", ret); 1119 srs_error("send with writev failed. ret=%d", ret);
1134 } 1120 }
@@ -1139,9 +1125,9 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) @@ -1139,9 +1125,9 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
1139 1125
1140 // send in multiple times. 1126 // send in multiple times.
1141 int cur_iov = 0; 1127 int cur_iov = 0;
1142 - while (cur_iov < iov_index) {  
1143 - int cur_count = srs_min(limits, iov_index - cur_iov);  
1144 - if ((ret = skt->writev(out_iovs + cur_iov, cur_count, NULL)) != ERROR_SUCCESS) { 1128 + while (cur_iov < size) {
  1129 + int cur_count = srs_min(limits, size - cur_iov);
  1130 + if ((ret = skt->writev(iovs + cur_iov, cur_count, NULL)) != ERROR_SUCCESS) {
1145 if (!srs_is_client_gracefully_close(ret)) { 1131 if (!srs_is_client_gracefully_close(ret)) {
1146 srs_error("send with writev failed. ret=%d", ret); 1132 srs_error("send with writev failed. ret=%d", ret);
1147 } 1133 }
@@ -286,9 +286,6 @@ private: @@ -286,9 +286,6 @@ private:
286 char mic_etime[4]; 286 char mic_etime[4];
287 // whether etime present. 287 // whether etime present.
288 bool mic_etime_present; 288 bool mic_etime_present;
289 - // the calced private iovs for this msg  
290 - iovec* iovs;  
291 - int nb_iovs;  
292 #endif 289 #endif
293 public: 290 public:
294 SrsSharedPtrMessage(); 291 SrsSharedPtrMessage();
@@ -329,14 +326,10 @@ public: @@ -329,14 +326,10 @@ public:
329 */ 326 */
330 virtual int mic_evaluate(int chunk_size); 327 virtual int mic_evaluate(int chunk_size);
331 /** 328 /**
332 - * count the total iovs needed.  
333 - */  
334 - virtual int mic_iovs_count();  
335 - /**  
336 * dump all iovs, the _nb_iovs must equals to mic_iovs_count(). 329 * dump all iovs, the _nb_iovs must equals to mic_iovs_count().
337 - * @return the dumped count. 330 + * @return the dumped count. -1 if not enough iovs.
338 */ 331 */
339 - virtual int mic_iovs_dump(iovec* _iovs, int _nb_iovs); 332 + virtual int mic_iovs_dump(iovec* iovs, int max_nb_iovs);
340 #endif 333 #endif
341 }; 334 };
342 335
@@ -594,6 +587,10 @@ private: @@ -594,6 +587,10 @@ private:
594 */ 587 */
595 virtual int do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs); 588 virtual int do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs);
596 /** 589 /**
  590 + * send iovs. send multiple times if exceed limits.
  591 + */
  592 + virtual int do_iovs_send(iovec* iovs, int size);
  593 + /**
597 * underlayer api for send and free packet. 594 * underlayer api for send and free packet.
598 */ 595 */
599 virtual int do_send_and_free_packet(SrsPacket* packet, int stream_id); 596 virtual int do_send_and_free_packet(SrsPacket* packet, int stream_id);