From dfda5df8fd0544e8a47e3d2aeb486a5ade8aeda1 Mon Sep 17 00:00:00 2001 From: Alexandre Savard <alexandre.savard@savoirfairelinux.com> Date: Thu, 19 Jul 2012 10:11:17 -0400 Subject: [PATCH] #13678: Fix Zrtp thread may hang when hanging up a call --- .../src/audio/audiortp/audio_zrtp_session.cpp | 76 +++++++++---------- .../src/audio/audiortp/audio_zrtp_session.h | 29 ++++++- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp index 5b41a5c4d2..4d50bf1466 100644 --- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp +++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp @@ -47,25 +47,27 @@ namespace sfl { AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string &zidFilename) : - AudioRtpSession(call, *this, *this), - ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(call_.getLocalIp().c_str()), - call_.getLocalAudioPort(), - 0, - ost::MembershipBookkeeping::defaultMembersHashSize, - ost::defaultApplication()), - zidFilename_(zidFilename) + ost::TimerPort() + , ost::SymmetricZRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort()) + , AudioRtpSession(call, *this, *this) + , zidFilename_(zidFilename) + , rtpThread_(*this) { initializeZid(); DEBUG("Setting new RTP session with destination %s:%d", call_.getLocalIp().c_str(), call_.getLocalAudioPort()); + audioRtpRecord_.callId_ = call_.getCallId(); } AudioZrtpSession::~AudioZrtpSession() { - ost::Thread::terminate(); - Manager::instance().getMainBuffer()->unBindAll(call_.getCallId()); + if (rtpThread_.running_) { + rtpThread_.running_ = false; + rtpThread_.join(); + } } + void AudioZrtpSession::initializeZid() { if (zidFilename_.empty()) @@ -120,46 +122,31 @@ void AudioZrtpSession::sendMicData() queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize); } -void AudioZrtpSession::run() +AudioZrtpSession::AudioZrtpThread::AudioZrtpThread(AudioZrtpSession &session) : running_(true), zrtpSession_(session) +{} + +void AudioZrtpSession::AudioZrtpThread::run() { // Set recording sampling rate - call_.setRecordingSmplRate(getCodecSampleRate()); - DEBUG("Entering mainloop for call %s", call_.getCallId().c_str()); + int threadSleep = 20; - uint32 timeout = 0; + DEBUG("Entering Audio zrtp thread main loop %s", running_ ? "running" : "not running"); - while (isActive()) { - if (timeout < 1000) - timeout = getSchedulingTimeout(); + TimerPort::setTimer(threadSleep); + while (running_) { // Send session - if (hasDTMFPending()) - sendDtmfEvent(); + if (zrtpSession_.hasDTMFPending()) + zrtpSession_.sendDtmfEvent(); else - sendMicData(); - - controlReceptionService(); - controlTransmissionService(); - uint32 maxWait = timeval2microtimeout(getRTCPCheckInterval()); - // make sure the scheduling timeout is - // <= the check interval for RTCP - // packets - timeout = (timeout > maxWait) ? maxWait : timeout; - - if (timeout < 1000) { // !(timeout/1000) - // dispatchDataPacket(); - timerTick(); - } else { - if (isPendingData(timeout / 1000)) { - - if (isActive()) - takeInDataPacket(); - } - timeout = 0; - } + zrtpSession_.sendMicData(); + + Thread::sleep(TimerPort::getTimer()); + + TimerPort::incTimer(threadSleep); } - DEBUG("Left main loop for call %s", call_.getCallId().c_str()); + DEBUG("Leaving audio rtp thread loop"); } int AudioZrtpSession::getIncrementForDTMF() const @@ -172,4 +159,13 @@ void AudioZrtpSession::setSessionMedia(AudioCodec &audioCodec) AudioRtpSession::setSessionMedia(audioCodec); } +int AudioZrtpSession::startRtpThread(AudioCodec &audiocodec) +{ + if(isStarted_) + return 0; + + AudioRtpSession::startRtpThread(audiocodec); + return startZrtpThread(); +} + } diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h index d056d021ca..b3bc670b44 100644 --- a/daemon/src/audio/audiortp/audio_zrtp_session.h +++ b/daemon/src/audio/audiortp/audio_zrtp_session.h @@ -54,25 +54,46 @@ class ZrtpZidException : public std::runtime_error { }; class AudioZrtpSession : - public AudioRtpSession, protected ost::Thread, - public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> { + public ost::TimerPort, + // public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> { + public ost::SymmetricZRTPSession, + public AudioRtpSession { public: AudioZrtpSession(SIPCall &call, const std::string& zidFilename); ~AudioZrtpSession(); - // Thread associated method - virtual void run(); + int startZrtpThread() { + rtpThread_.start(); + return 0; + } virtual bool onRTPPacketRecv(ost::IncomingRTPPkt &pkt) { return AudioRtpSession::onRTPPacketRecv(pkt); } private: + NON_COPYABLE(AudioZrtpSession); + + class AudioZrtpThread : public ost::Thread, public ost::TimerPort { + public: + AudioZrtpThread(AudioZrtpSession &session); + + virtual void run(); + + bool running_; + + private: + NON_COPYABLE(AudioZrtpThread); + AudioZrtpSession &zrtpSession_; + }; void sendMicData(); void initializeZid(); std::string zidFilename_; void setSessionMedia(AudioCodec &codec); + int startRtpThread(AudioCodec &audiocodec); virtual int getIncrementForDTMF() const; + + AudioZrtpThread rtpThread_; }; } -- GitLab