diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index c4913ba8ab..0eddb9588f 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -782,6 +782,10 @@ srs_error_t SrsEdgeForwarder::start() url = srs_generate_rtmp_url(server, port, req->host, vhost, req->app, req->stream, req->param); } + + // We must stop the coroutine before disposing the sdk. + srs_freep(trd); + trd = new SrsSTCoroutine("edge-fwr", this, _srs_context->get_id()); // open socket. srs_freep(sdk); @@ -806,10 +810,8 @@ srs_error_t SrsEdgeForwarder::start() if ((err = sdk->publish(_srs_config->get_chunk_size(req->vhost), false, &stream)) != srs_success) { return srs_error_wrap(err, "sdk publish"); } - - srs_freep(trd); - trd = new SrsSTCoroutine("edge-fwr", this, _srs_context->get_id()); - + + // Start the forwarding coroutine. if ((err = trd->start()) != srs_success) { return srs_error_wrap(err, "coroutine"); } @@ -821,9 +823,12 @@ srs_error_t SrsEdgeForwarder::start() void SrsEdgeForwarder::stop() { + // Make sure the coroutine is stopped before disposing the sdk, + // for sdk is used by coroutine. trd->stop(); - queue->clear(); srs_freep(sdk); + + queue->clear(); } // when error, edge ingester sleep for a while and retry. @@ -840,7 +845,13 @@ srs_error_t SrsEdgeForwarder::cycle() return srs_error_wrap(err, "thread pull"); } - if ((err = do_cycle()) != srs_success) { + // If coroutine stopping, we should always set the quit error code. + err = do_cycle(); + if (send_error_code == 0) { + send_error_code = srs_error_code(err); + } + + if (err != srs_success) { return srs_error_wrap(err, "do cycle"); } diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index b08262281c..654660e345 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -959,7 +959,9 @@ srs_error_t SrsRtmpConn::publishing(SrsSharedPtr source) // but failed, so we must cleanup it. // @see https://github.com/ossrs/srs/issues/474 // @remark when stream is busy, should never release it. - if (srs_error_code(err) != ERROR_SYSTEM_STREAM_BUSY) { + // @remark If state is invalid, should not release it because it's not published by this session. + int code = srs_error_code(err); + if (code != ERROR_SYSTEM_STREAM_BUSY && code != ERROR_RTMP_EDGE_PUBLISH_STATE) { release_publish(source); }