Commit dbbbc4f5 authored by gejun's avatar gejun

patch svn r34926

Change-Id: Id2f0ed5939650dbf968ad4a3c19378d8fe73a976
parent c6c700b6
...@@ -1489,6 +1489,13 @@ void RtmpClientStream::CleanupSocketForStream( ...@@ -1489,6 +1489,13 @@ void RtmpClientStream::CleanupSocketForStream(
void RtmpClientStream::ReplaceSocketForStream( void RtmpClientStream::ReplaceSocketForStream(
SocketUniquePtr* inout, Controller* cntl) { SocketUniquePtr* inout, Controller* cntl) {
{
std::unique_lock<pthread_mutex_t> mu(_state_mutex);
if (_state == STATE_ERROR || _state == STATE_DESTROYING) {
cntl->SetFailed(EINVAL, "Fail to replace socket for stream, _state is error or destroying");
return;
}
}
SocketId esid; SocketId esid;
if (cntl->connection_type() == CONNECTION_TYPE_SHORT) { if (cntl->connection_type() == CONNECTION_TYPE_SHORT) {
if (_client_impl->CreateSocket((*inout)->remote_side(), &esid) != 0) { if (_client_impl->CreateSocket((*inout)->remote_side(), &esid) != 0) {
...@@ -1581,28 +1588,23 @@ void RtmpClientStream::OnStreamCreationDone(SocketUniquePtr& sending_sock, ...@@ -1581,28 +1588,23 @@ void RtmpClientStream::OnStreamCreationDone(SocketUniquePtr& sending_sock,
return OnFailedToCreateStream(); return OnFailedToCreateStream();
} }
// NOTE: set _rtmpsock before any error checking to make sure that int rc = 0;
// deleteStream command will be sent over _rtmpsock to release the bthread_id_t onfail_id = INVALID_BTHREAD_ID;
// server-side stream on this stream's stop. {
std::unique_lock<pthread_mutex_t> mu(_state_mutex);
switch (_state) {
case STATE_CREATING:
CHECK(_rtmpsock); CHECK(_rtmpsock);
rc = bthread_id_create(&onfail_id, this, RunOnFailed);
const int rc = bthread_id_create(&_onfail_id, this, RunOnFailed);
if (rc) { if (rc) {
cntl->SetFailed(ENOMEM, "Fail to create _onfail_id: %s", berror(rc)); cntl->SetFailed(ENOMEM, "Fail to create _onfail_id: %s", berror(rc));
// no need to care about management of socket_map or setting mu.unlock();
// sending_sock to be failed. The socket is OK to be kept in socket_map
// or let Controller::Call::OnComplete close it.
return OnFailedToCreateStream(); return OnFailedToCreateStream();
} }
// Add a ref for RunOnFailed. // Add a ref for RunOnFailed.
base::intrusive_ptr<RtmpClientStream>(this).detach(); base::intrusive_ptr<RtmpClientStream>(this).detach();
// Check _state
{
std::unique_lock<pthread_mutex_t> mu(_state_mutex);
switch (_state) {
case STATE_CREATING:
_state = STATE_CREATED; _state = STATE_CREATED;
_onfail_id = onfail_id;
break; break;
case STATE_UNINITIALIZED: case STATE_UNINITIALIZED:
case STATE_CREATED: case STATE_CREATED:
...@@ -1616,7 +1618,9 @@ void RtmpClientStream::OnStreamCreationDone(SocketUniquePtr& sending_sock, ...@@ -1616,7 +1618,9 @@ void RtmpClientStream::OnStreamCreationDone(SocketUniquePtr& sending_sock,
return OnStopInternal(); return OnStopInternal();
} }
} }
_rtmpsock->NotifyOnFailed(_onfail_id); if (onfail_id != INVALID_BTHREAD_ID) {
_rtmpsock->NotifyOnFailed(onfail_id);
}
} }
void RtmpClientStream::OnStopInternal() { void RtmpClientStream::OnStopInternal() {
...@@ -1913,12 +1917,15 @@ void RtmpClientStream::Init(const RtmpClient* client, ...@@ -1913,12 +1917,15 @@ void RtmpClientStream::Init(const RtmpClient* client,
LOG(FATAL) << "RtmpClient is not initialized"; LOG(FATAL) << "RtmpClient is not initialized";
return OnStopInternal(); return OnStopInternal();
} }
{
std::unique_lock<pthread_mutex_t> mu(_state_mutex);
if (_state == STATE_DESTROYING || _state == STATE_ERROR) { if (_state == STATE_DESTROYING || _state == STATE_ERROR) {
// already Destroy()-ed or SignalError()-ed // already Destroy()-ed or SignalError()-ed
LOG(WARNING) << "RtmpClientStream=" << this << " was already " LOG(WARNING) << "RtmpClientStream=" << this << " was already "
"Destroy()-ed, stop Init()"; "Destroy()-ed, stop Init()";
return; return;
} }
}
_client_impl = client->_impl; _client_impl = client->_impl;
_options = options; _options = options;
OnClientStreamCreated* done = new OnClientStreamCreated; OnClientStreamCreated* done = new OnClientStreamCreated;
...@@ -2105,6 +2112,7 @@ void InitSubStream::Run(const RtmpClient* client) { ...@@ -2105,6 +2112,7 @@ void InitSubStream::Run(const RtmpClient* client) {
void RtmpRetryingClientStream::Recreate() { void RtmpRetryingClientStream::Recreate() {
base::intrusive_ptr<SubStream> sub_stream(new SubStream(this)); base::intrusive_ptr<SubStream> sub_stream(new SubStream(this));
base::intrusive_ptr<SubStream> old_sub_stream;
bool destroying = false; bool destroying = false;
{ {
BAIDU_SCOPED_LOCK(_stream_mutex); BAIDU_SCOPED_LOCK(_stream_mutex);
...@@ -2115,10 +2123,14 @@ void RtmpRetryingClientStream::Recreate() { ...@@ -2115,10 +2123,14 @@ void RtmpRetryingClientStream::Recreate() {
// and Destroy() may be called, making new sub_stream leaked. // and Destroy() may be called, making new sub_stream leaked.
destroying = _destroying.load(base::memory_order_relaxed); destroying = _destroying.load(base::memory_order_relaxed);
if (!destroying) { if (!destroying) {
_using_sub_stream.swap(old_sub_stream);
_using_sub_stream = sub_stream; _using_sub_stream = sub_stream;
_changed_stream = true; _changed_stream = true;
} }
} }
if (old_sub_stream) {
old_sub_stream->Destroy();
}
if (destroying) { if (destroying) {
sub_stream->Destroy(); sub_stream->Destroy();
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment