Valgrind reports a racing condition on _sending because it is accessed by

both TransmitMixer::PrepareDemux() and StartSend()/StopSend().
Put a lock to resolve it.
Review URL: http://webrtc-codereview.appspot.com/293005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1038 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
xians@webrtc.org 2011-11-28 16:31:28 +00:00
parent 1e39bc80dc
commit e07247af8d
2 changed files with 39 additions and 18 deletions

View File

@ -1694,18 +1694,28 @@ Channel::StartSend()
{ {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
"Channel::StartSend()"); "Channel::StartSend()");
if (_sending)
{ {
return 0; // A lock is needed because |_sending| can be accessed or modified by
// another thread at the same time.
CriticalSectionScoped cs(_callbackCritSect);
if (_sending)
{
return 0;
}
_sending = true;
} }
if (_rtpRtcpModule.SetSendingStatus(true) != 0) if (_rtpRtcpModule.SetSendingStatus(true) != 0)
{ {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_RTP_RTCP_MODULE_ERROR, kTraceError, VE_RTP_RTCP_MODULE_ERROR, kTraceError,
"StartSend() RTP/RTCP failed to start sending"); "StartSend() RTP/RTCP failed to start sending");
CriticalSectionScoped cs(_callbackCritSect);
_sending = false;
return -1; return -1;
} }
_sending = true;
return 0; return 0;
} }
@ -1714,10 +1724,18 @@ Channel::StopSend()
{ {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
"Channel::StopSend()"); "Channel::StopSend()");
if (!_sending)
{ {
return 0; // A lock is needed because |_sending| can be accessed or modified by
// another thread at the same time.
CriticalSectionScoped cs(_callbackCritSect);
if (!_sending)
{
return 0;
}
_sending = false;
} }
// Reset sending SSRC and sequence number and triggers direct transmission // Reset sending SSRC and sequence number and triggers direct transmission
// of RTCP BYE // of RTCP BYE
if (_rtpRtcpModule.SetSendingStatus(false) == -1 || if (_rtpRtcpModule.SetSendingStatus(false) == -1 ||
@ -1728,7 +1746,6 @@ Channel::StopSend()
"StartSend() RTP/RTCP failed to stop sending"); "StartSend() RTP/RTCP failed to stop sending");
} }
_sending = false;
return 0; return 0;
} }

View File

@ -464,52 +464,56 @@ public:
WebRtc_UWord32 InstanceId() const WebRtc_UWord32 InstanceId() const
{ {
return _instanceId; return _instanceId;
}; }
WebRtc_Word32 ChannelId() const WebRtc_Word32 ChannelId() const
{ {
return _channelId; return _channelId;
}; }
bool Playing() const bool Playing() const
{ {
return _playing; return _playing;
}; }
bool Sending() const bool Sending() const
{ {
// A lock is needed because |_sending| is accessed by both
// TransmitMixer::PrepareDemux() and StartSend()/StopSend(), which
// are called by different threads.
CriticalSectionScoped cs(_callbackCritSect);
return _sending; return _sending;
}; }
bool Receiving() const bool Receiving() const
{ {
return _receiving; return _receiving;
}; }
bool ExternalTransport() const bool ExternalTransport() const
{ {
return _externalTransport; return _externalTransport;
}; }
bool OutputIsOnHold() const bool OutputIsOnHold() const
{ {
return _outputIsOnHold; return _outputIsOnHold;
}; }
bool InputIsOnHold() const bool InputIsOnHold() const
{ {
return _inputIsOnHold; return _inputIsOnHold;
}; }
RtpRtcp* RtpRtcpModulePtr() const RtpRtcp* RtpRtcpModulePtr() const
{ {
return &_rtpRtcpModule; return &_rtpRtcpModule;
}; }
WebRtc_Word8 OutputEnergyLevel() const WebRtc_Word8 OutputEnergyLevel() const
{ {
return _outputAudioLevel.Level(); return _outputAudioLevel.Level();
}; }
#ifndef WEBRTC_EXTERNAL_TRANSPORT #ifndef WEBRTC_EXTERNAL_TRANSPORT
bool SendSocketsInitialized() const bool SendSocketsInitialized() const
{ {
return _socketTransportModule.SendSocketsInitialized(); return _socketTransportModule.SendSocketsInitialized();
}; }
bool ReceiveSocketsInitialized() const bool ReceiveSocketsInitialized() const
{ {
return _socketTransportModule.ReceiveSocketsInitialized(); return _socketTransportModule.ReceiveSocketsInitialized();
}; }
#endif #endif
WebRtc_UWord32 Demultiplex(const AudioFrame& audioFrame); WebRtc_UWord32 Demultiplex(const AudioFrame& audioFrame);
WebRtc_UWord32 PrepareEncodeAndSend(int mixingFrequency); WebRtc_UWord32 PrepareEncodeAndSend(int mixingFrequency);