From 0bc35e093c30ab5f467c4ebc42d29baf00f7f7a1 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 13 Nov 2014 14:30:56 +0800 Subject: [PATCH] for bug #200, deadloop when read/write 0 and ETIME. 2.0.16. --- README.md | 7 +++-- trunk/research/st/srs.c | 4 ++- trunk/src/app/srs_app_rtmp_conn.cpp | 4 --- trunk/src/app/srs_app_st_socket.cpp | 14 ++++++--- trunk/src/core/srs_core.hpp | 2 +- trunk/src/libs/srs_lib_simple_socket.cpp | 37 +++++++++++++++--------- 6 files changed, 42 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index b521f73d5..ada0b150b 100755 --- a/README.md +++ b/README.md @@ -242,9 +242,10 @@ Supported operating systems and hardware: * 2013-10-17, Created.
## History -* v2.0, 2014-11-08, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), writev multiple msgs, support 6k+ 250kbps clients. 2.0.15. -* v2.0, 2014-11-08, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), optmized st for timeout recv. pulse to 500ms. 2.0.14. -* v2.0, 2014-11-08, fix [#195](https://github.com/winlinvip/simple-rtmp-server/issues/195), remove the confuse code st_usleep(0). 2.0.13. +* v2.0, 2014-11-13, fix [#200](https://github.com/winlinvip/simple-rtmp-server/issues/200), deadloop when read/write 0 and ETIME. 2.0.16. +* v2.0, 2014-11-13, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), writev multiple msgs, support 6k+ 250kbps clients. 2.0.15. +* v2.0, 2014-11-12, fix [#194](https://github.com/winlinvip/simple-rtmp-server/issues/194), optmized st for timeout recv. pulse to 500ms. 2.0.14. +* v2.0, 2014-11-11, fix [#195](https://github.com/winlinvip/simple-rtmp-server/issues/195), remove the confuse code st_usleep(0). 2.0.13. * v2.0, 2014-11-08, fix [#191](https://github.com/winlinvip/simple-rtmp-server/issues/191), configure --export-librtmp-project and --export-librtmp-single. 2.0.11. * v2.0, 2014-11-08, fix [#66](https://github.com/winlinvip/simple-rtmp-server/issues/66), srs-librtmp support write h264 raw packet. 2.0.9. * v2.0, 2014-10-25, fix [#185](https://github.com/winlinvip/simple-rtmp-server/issues/185), AMF0 support 0x0B the date type codec. 2.0.7. diff --git a/trunk/research/st/srs.c b/trunk/research/st/srs.c index b1dfdb4ad..09bc5eacc 100644 --- a/trunk/research/st/srs.c +++ b/trunk/research/st/srs.c @@ -101,7 +101,7 @@ int sleep2_test() st_thread_join(trd1, NULL); srs_trace("sleep test: end"); - exit(0); + return 0; } @@ -431,6 +431,8 @@ int pipe_test() int main(int argc, char** argv) { + srs_trace("ETIME=%d", ETIME); + if (st_set_eventsys(ST_EVENTSYS_ALT) < 0) { srs_trace("st_set_eventsys failed"); return -1; diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index f9f6636b6..186760361 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -534,10 +534,6 @@ int SrsRtmpConn::playing(SrsSource* source) // it's ok, do nothing. ret = ERROR_SUCCESS; srs_verbose("recv timeout, ignore. ret=%d", ret); - - // TODO: FIXME: the timeout may caused some dead loop. - // @see: https://github.com/winlinvip/simple-rtmp-server/issues/161 - st_usleep(0); } else if (ret != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("recv client control message failed. ret=%d", ret); diff --git a/trunk/src/app/srs_app_st_socket.cpp b/trunk/src/app/srs_app_st_socket.cpp index e1c8e63cf..6c8d4be97 100644 --- a/trunk/src/app/srs_app_st_socket.cpp +++ b/trunk/src/app/srs_app_st_socket.cpp @@ -82,8 +82,9 @@ int SrsStSocket::read(void* buf, size_t size, ssize_t* nread) // On success a non-negative integer indicating the number of bytes actually read is returned // (a value of 0 means the network connection is closed or end of file is reached). + // Otherwise, a value of -1 is returned and errno is set to indicate the error. if (nb_read <= 0) { - if (errno == ETIME) { + if (nb_read < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } @@ -110,8 +111,9 @@ int SrsStSocket::read_fully(void* buf, size_t size, ssize_t* nread) // On success a non-negative integer indicating the number of bytes actually read is returned // (a value less than nbyte means the network connection is closed or end of file is reached) + // Otherwise, a value of -1 is returned and errno is set to indicate the error. if (nb_read != (ssize_t)size) { - if (errno == ETIME) { + if (nb_read < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } @@ -136,8 +138,10 @@ int SrsStSocket::write(void* buf, size_t size, ssize_t* nwrite) *nwrite = nb_write; } + // On success a non-negative integer equal to nbyte is returned. + // Otherwise, a value of -1 is returned and errno is set to indicate the error. if (nb_write <= 0) { - if (errno == ETIME) { + if (nb_write < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } @@ -158,8 +162,10 @@ int SrsStSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) *nwrite = nb_write; } + // On success a non-negative integer equal to nbyte is returned. + // Otherwise, a value of -1 is returned and errno is set to indicate the error. if (nb_write <= 0) { - if (errno == ETIME) { + if (nb_write < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 78625cbf7..5c2ebd320 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 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 15 +#define VERSION_REVISION 16 // server info. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_ROLE "origin/edge server" diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index 202155503..45e8f5b9e 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -82,23 +82,27 @@ int SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) { int ret = ERROR_SUCCESS; - *nread = ::recv(fd, buf, size, 0); + ssize_t nb_read = ::recv(fd, buf, size, 0); + + if (nread) { + *nread = nb_read; + } // On success a non-negative integer indicating the number of bytes actually read is returned // (a value of 0 means the network connection is closed or end of file is reached). - if (*nread <= 0) { - if (errno == ETIME) { + if (nb_read <= 0) { + if (nb_read < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } - if (*nread == 0) { + if (nb_read == 0) { errno = ECONNRESET; } return ERROR_SOCKET_READ; } - recv_bytes += *nread; + recv_bytes += nb_read; return ret; } @@ -165,21 +169,24 @@ int SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread) int ret = ERROR_SUCCESS; size_t left = size; - *nread = 0; + ssize_t nb_read = 0; while (left > 0) { - char* this_buf = (char*)buf + *nread; + char* this_buf = (char*)buf + nb_read; ssize_t this_nread; if ((ret = this->read(this_buf, left, &this_nread)) != ERROR_SUCCESS) { return ret; } - *nread += this_nread; + nb_read += this_nread; left -= this_nread; } - recv_bytes += *nread; + if (nread) { + *nread = nb_read; + } + recv_bytes += nb_read; return ret; } @@ -188,17 +195,21 @@ int SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite) { int ret = ERROR_SUCCESS; - *nwrite = ::send(fd, (void*)buf, size, 0); + ssize_t nb_write = ::send(fd, (void*)buf, size, 0); - if (*nwrite <= 0) { - if (errno == ETIME) { + if (nwrite) { + *nwrite = nb_write; + } + + if (nb_write <= 0) { + if (nb_write < 0 && errno == ETIME) { return ERROR_SOCKET_TIMEOUT; } return ERROR_SOCKET_WRITE; } - send_bytes += *nwrite; + send_bytes += nb_write; return ret; }