winlin

for bug #194, use play fd poll, create the singleton poll

@@ -388,7 +388,8 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then @@ -388,7 +388,8 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
388 "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" 388 "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
389 "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" 389 "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
390 "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" 390 "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
391 - "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac") 391 + "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac"
  392 + "srs_app_poll")
392 APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh 393 APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
393 APP_OBJS="${MODULE_OBJS[@]}" 394 APP_OBJS="${MODULE_OBJS[@]}"
394 fi 395 fi
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_app_poll.hpp>
  25 +
  26 +#include <srs_kernel_error.hpp>
  27 +
  28 +SrsPoll::SrsPoll()
  29 +{
  30 + pthread = new SrsThread(this, 0, false);
  31 +}
  32 +
  33 +SrsPoll::~SrsPoll()
  34 +{
  35 + srs_freep(pthread);
  36 + fds.clear();
  37 +}
  38 +
  39 +int SrsPoll::start()
  40 +{
  41 + return pthread->start();
  42 +}
  43 +
  44 +int SrsPoll::cycle()
  45 +{
  46 + int ret = ERROR_SUCCESS;
  47 + // TODO: FIXME: implements it.
  48 + return ret;
  49 +}
  50 +
  51 +SrsPoll* SrsPoll::_instance = new SrsPoll();
  52 +
  53 +SrsPoll* SrsPoll::instance()
  54 +{
  55 + return _instance;
  56 +}
  57 +
  58 +SrsPollFD::SrsPollFD()
  59 +{
  60 + _stfd = NULL;
  61 +}
  62 +
  63 +SrsPollFD::~SrsPollFD()
  64 +{
  65 +}
  66 +
  67 +int SrsPollFD::initialize(st_netfd_t stfd)
  68 +{
  69 + int ret = ERROR_SUCCESS;
  70 +
  71 + _stfd = stfd;
  72 +
  73 + return ret;
  74 +}
  75 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_APP_POLL_HPP
  25 +#define SRS_APP_POLL_HPP
  26 +
  27 +/*
  28 +#include <srs_app_poll.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +#include <map>
  34 +
  35 +#include <srs_app_st.hpp>
  36 +#include <srs_app_thread.hpp>
  37 +
  38 +class SrsPollFD;
  39 +
  40 +/**
  41 +* the poll for all play clients to finger the active fd out.
  42 +* for performance issue, @see: https://github.com/winlinvip/simple-rtmp-server/issues/194
  43 +* the poll is shared by all SrsPollFD, and we start an isolate thread to finger the active fds.
  44 +*/
  45 +class SrsPoll : public ISrsThreadHandler
  46 +{
  47 +private:
  48 + SrsThread* pthread;
  49 + std::map<st_netfd_t, SrsPollFD*> fds;
  50 +public:
  51 + SrsPoll();
  52 + virtual ~SrsPoll();
  53 +public:
  54 + /**
  55 + * start the poll thread.
  56 + */
  57 + virtual int start();
  58 + /**
  59 + * start an cycle thread.
  60 + */
  61 + virtual int cycle();
  62 +// singleton
  63 +private:
  64 + static SrsPoll* _instance;
  65 +public:
  66 + static SrsPoll* instance();
  67 +};
  68 +
  69 +/**
  70 +* the poll fd to check whether the specified fd is active.
  71 +*/
  72 +class SrsPollFD
  73 +{
  74 +private:
  75 + st_netfd_t _stfd;
  76 +public:
  77 + SrsPollFD();
  78 + virtual ~SrsPollFD();
  79 +public:
  80 + /**
  81 + * initialize the poll.
  82 + * @param stfd the fd to poll.
  83 + */
  84 + virtual int initialize(st_netfd_t stfd);
  85 +};
  86 +
  87 +#endif
  88 +
@@ -48,6 +48,7 @@ using namespace std; @@ -48,6 +48,7 @@ using namespace std;
48 #include <srs_app_utility.hpp> 48 #include <srs_app_utility.hpp>
49 #include <srs_protocol_msg_array.hpp> 49 #include <srs_protocol_msg_array.hpp>
50 #include <srs_protocol_amf0.hpp> 50 #include <srs_protocol_amf0.hpp>
  51 +#include <srs_app_poll.hpp>
51 52
52 // when stream is busy, for example, streaming is already 53 // when stream is busy, for example, streaming is already
53 // publishing, when a new client to request to publish, 54 // publishing, when a new client to request to publish,
@@ -525,6 +526,11 @@ int SrsRtmpConn::playing(SrsSource* source) @@ -525,6 +526,11 @@ int SrsRtmpConn::playing(SrsSource* source)
525 bool user_specified_duration_to_stop = (req->duration > 0); 526 bool user_specified_duration_to_stop = (req->duration > 0);
526 int64_t starttime = -1; 527 int64_t starttime = -1;
527 528
  529 + SrsPollFD poll;
  530 + if ((ret = poll.initialize(stfd)) != ERROR_SUCCESS) {
  531 + return ret;
  532 + }
  533 +
528 while (true) { 534 while (true) {
529 // collect elapse for pithy print. 535 // collect elapse for pithy print.
530 pithy_print.elapse(); 536 pithy_print.elapse();
@@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 #include <srs_app_source.hpp> 44 #include <srs_app_source.hpp>
45 #include <srs_app_utility.hpp> 45 #include <srs_app_utility.hpp>
46 #include <srs_app_heartbeat.hpp> 46 #include <srs_app_heartbeat.hpp>
  47 +#include <srs_app_poll.hpp>
47 48
48 // signal defines. 49 // signal defines.
49 #define SIGNAL_RELOAD SIGHUP 50 #define SIGNAL_RELOAD SIGHUP
@@ -664,6 +665,14 @@ int SrsServer::do_cycle() @@ -664,6 +665,14 @@ int SrsServer::do_cycle()
664 { 665 {
665 int ret = ERROR_SUCCESS; 666 int ret = ERROR_SUCCESS;
666 667
  668 + // start the poll for play clients.
  669 + // performance issue, @see: https://github.com/winlinvip/simple-rtmp-server/issues/194
  670 + SrsPoll* poll = SrsPoll::instance();
  671 + if ((ret = poll->start()) != ERROR_SUCCESS) {
  672 + srs_error("start poll failed. ret=%d", ret);
  673 + return ret;
  674 + }
  675 +
667 // find the max loop 676 // find the max loop
668 int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); 677 int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
669 678
@@ -92,6 +92,8 @@ file @@ -92,6 +92,8 @@ file
92 ..\app\srs_app_kbps.cpp, 92 ..\app\srs_app_kbps.cpp,
93 ..\app\srs_app_log.hpp, 93 ..\app\srs_app_log.hpp,
94 ..\app\srs_app_log.cpp, 94 ..\app\srs_app_log.cpp,
  95 + ..\app\srs_app_poll.hpp,
  96 + ..\app\srs_app_poll.cpp,
95 ..\app\srs_app_refer.hpp, 97 ..\app\srs_app_refer.hpp,
96 ..\app\srs_app_refer.cpp, 98 ..\app\srs_app_refer.cpp,
97 ..\app\srs_app_reload.hpp, 99 ..\app\srs_app_reload.hpp,