Commit 35b9db54 authored by Tristan Matthews's avatar Tristan Matthews

* #9572: fixed threading issues with ccrtp2

parent 0246b0da
......@@ -121,9 +121,6 @@ PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MS
LIBCCGNU2_MIN_VERSION=1.3.1
PKG_CHECK_MODULES(CCGNU2, commoncpp >= ${LIBCCGNU2_MIN_VERSION},, AC_MSG_ERROR([Missing common cpp development package: libcommoncpp2-dev]))
LIBCCEXT2_MIN_VERSION=1.3.1
PKG_CHECK_MODULES(CCEXT2, libccext2 >= ${LIBCCEXT2_MIN_VERSION})
LIBCCRT_MIN_VERSION=1.3.0
PKG_CHECK_MODULES(CCRTP, libccrtp >= ${LIBCCRT_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev]))
......
......@@ -41,9 +41,7 @@ class AlsaThread : public ost::Thread {
public:
AlsaThread(AlsaLayer *alsa);
~AlsaThread() {
terminate();
}
~AlsaThread() { terminate(); }
virtual void run();
......@@ -53,16 +51,15 @@ class AlsaThread : public ost::Thread {
};
AlsaThread::AlsaThread(AlsaLayer *alsa)
: Thread(), alsa_(alsa)
{
}
: ost::Thread(), alsa_(alsa)
{}
/**
* Reimplementation of run()
*/
void AlsaThread::run()
{
while (1) {
while (alsa_->isStarted_) {
alsa_->audioCallback();
Thread::sleep(20);
}
......@@ -93,6 +90,7 @@ AlsaLayer::AlsaLayer()
// Destructor
AlsaLayer::~AlsaLayer()
{
isStarted_ = false;
delete audioThread_;
/* Then close the audio devices */
......@@ -678,19 +676,17 @@ void AlsaLayer::audioCallback()
if (ringtoneHandle_) {
AudioLoop *file_tone = Manager::instance().getTelephoneFile();
int ringtoneAvailSmpl = snd_pcm_avail_update(ringtoneHandle_);
int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof(SFLDataFormat);
int ringtoneAvailBytes = ringtoneAvailSmpl * sizeof(SFLDataFormat);
SFLDataFormat *out = (SFLDataFormat *) malloc(ringtoneAvailBytes);
std::vector<SFLDataFormat> out(ringtoneAvailSmpl, 0);
if (file_tone) {
DEBUG("playback gain %d", getPlaybackGain());
file_tone->getNext(out, ringtoneAvailSmpl, getPlaybackGain());
file_tone->getNext(&(*out.begin()), ringtoneAvailSmpl,
getPlaybackGain());
}
else
memset(out, 0, ringtoneAvailBytes);
write(out, ringtoneAvailBytes, ringtoneHandle_);
free(out);
write(&(*out.begin()), ringtoneAvailBytes, ringtoneHandle_);
}
// Additionally handle the mic's audio stream
......
......@@ -149,7 +149,7 @@ class AlsaLayer : public AudioLayer {
}
private:
friend class AlsaThread;
/**
* Calls snd_pcm_open and retries if device is busy, since dmix plugin
......@@ -241,7 +241,7 @@ class AlsaLayer : public AudioLayer {
bool is_playback_open_;
bool is_capture_open_;
AlsaThread* audioThread_;
AlsaThread *audioThread_;
};
#endif // _ALSA_LAYER_H_
......@@ -34,7 +34,7 @@
int AudioRecorder::count_ = 0;
AudioRecorder::AudioRecorder(AudioRecord *arec, MainBuffer *mb) : Thread(),
AudioRecorder::AudioRecorder(AudioRecord *arec, MainBuffer *mb) : ost::Thread(),
recorderId_(), mbuffer_(mb), arecord_(arec)
{
assert(mb);
......@@ -60,7 +60,7 @@ void AudioRecorder::run()
int bufferLength = 10000;
SFLDataFormat buffer[bufferLength];
while (true) {
while (isRunning()) {
int availBytes = mbuffer_->availForGet(recorderId_);
int toGet = (availBytes < bufferLength) ? availBytes : bufferLength;
......
......@@ -60,8 +60,6 @@ AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string& zidFilename
{
DEBUG("AudioZrtpSession initialized");
initializeZid();
DEBUG("AudioZrtpSession: Setting new RTP session with destination %s:%d",
call_.getLocalIp().c_str(), call_.getLocalAudioPort());
}
......@@ -72,14 +70,6 @@ AudioZrtpSession::~AudioZrtpSession()
Manager::instance().getMainBuffer()->unBindAll(call_.getCallId());
}
void AudioZrtpSession::final()
{
// tmatth:Oct 25 2011:FIXME:
// This was crashing...seems like it's not necessary. Double check
// with valgrind/helgrind
// delete this;
}
void AudioZrtpSession::initializeZid()
{
if (zidFilename_.empty())
......
......@@ -60,8 +60,6 @@ class AudioZrtpSession :
AudioZrtpSession(SIPCall &call, const std::string& zidFilename);
~AudioZrtpSession();
virtual void final();
// Thread associated method
virtual void run();
......
......@@ -124,7 +124,7 @@ PulseLayer::~PulseLayer()
if (mainloop_)
pa_threaded_mainloop_free(mainloop_);
delete[] mic_buffer_;
delete [] mic_buffer_;
}
void PulseLayer::context_state_callback(pa_context* c, void *user_data)
......@@ -422,7 +422,7 @@ void PulseLayer::readFromMic()
if (bytes > mic_buf_size_) {
mic_buf_size_ = bytes;
delete[] mic_buffer_;
delete [] mic_buffer_;
mic_buffer_ = new SFLDataFormat[samples];
}
......
......@@ -31,12 +31,13 @@
#include "eventthread.h"
#include "voiplink.h"
EventThread::EventThread(VoIPLink *link) : Thread(), link_(link)
EventThread::EventThread(VoIPLink *link) : ost::Thread(), link_(link)
{}
void EventThread::run()
{
while (isRunning())
link_->getEvent();
while (link_->getEvent())
; // noop
ost::Thread::exit();
}
......@@ -44,7 +44,7 @@ class VoIPLink;
class EventThread : public ost::Thread {
public:
EventThread(VoIPLink* link);
virtual void run();
void run();
private:
NON_COPYABLE(EventThread);
......
......@@ -56,6 +56,7 @@ IAXVoIPLink::IAXVoIPLink(const std::string& accountID) :
IAXVoIPLink::~IAXVoIPLink()
{
handlingEvents_ = false;
delete evThread_;
regSession_ = NULL; // shall not delete it // XXX: but why?
......@@ -70,6 +71,7 @@ IAXVoIPLink::init()
for (int port = IAX_DEFAULT_PORTNO, nbTry = 0; nbTry < 3 ; port = rand() % 64000 + 1024, nbTry++) {
if (iax_init(port) >= 0) {
handlingEvents_ = false;
evThread_->start();
initDone_ = true;
break;
......@@ -100,7 +102,7 @@ IAXVoIPLink::terminate()
initDone_ = false;
}
void
bool
IAXVoIPLink::getEvent()
{
mutexIAX_.enter();
......@@ -133,7 +135,8 @@ IAXVoIPLink::getEvent()
sendAudioFromMic();
// thread wait 3 millisecond
evThread_->sleep(3);
ost::Thread::sleep(3);
return handlingEvents_;
}
void
......
......@@ -62,7 +62,7 @@ class IAXVoIPLink : public VoIPLink {
/**
* Listen to events sent by the call manager ( asterisk, etc .. )
*/
void getEvent();
bool getEvent();
/**
* Init the voip link
......
......@@ -55,7 +55,7 @@ ost::CommandOptionNoArg help(
"help", "h", "Print help"
);
*/
int main(int argc, char **argv)
int main(int /*argc*/, char **argv)
{
fileutils::set_program_dir(argv[0]);
// makeCommandOptionParse allocates the object with operator new, so
......
......@@ -86,10 +86,6 @@ ManagerImpl::ManagerImpl() :
srand(time(NULL));
}
// never call if we use only the singleton...
ManagerImpl::~ManagerImpl()
{}
void ManagerImpl::init(const std::string &config_file)
{
path_ = config_file.empty() ? createConfigFile() : config_file;
......@@ -126,13 +122,12 @@ void ManagerImpl::terminate()
std::vector<std::string> callList(getCallList());
DEBUG("Manager: Hangup %zu remaining call", callList.size());
for (std::vector<std::string>::iterator iter = callList.begin(); iter != callList.end(); ++iter)
for (std::vector<std::string>::iterator iter = callList.begin();
iter != callList.end(); ++iter)
hangupCall(*iter);
saveConfig();
delete SIPVoIPLink::instance();
// Unload account map AFTER destroying
// the SIPVoIPLink, the link still needs the accounts for pjsip cleanup
unloadAccountMap();
......
......@@ -93,7 +93,6 @@ static const char * const default_conf = "conf";
class ManagerImpl {
public:
ManagerImpl();
~ManagerImpl();
/**
* General preferences configuration
......
......@@ -89,7 +89,7 @@ static pj_caching_pool pool_cache, *cp_ = &pool_cache;
static pj_pool_t *pool_;
static pjsip_endpoint *endpt_;
static pjsip_module mod_ua_;
static pj_thread_t *thread;
static pj_thread_t *thread_;
void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status);
void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
......@@ -481,15 +481,19 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(this)
TRY(pjsip_replaces_init_module(endpt_));
#undef TRY
evThread_.detach();
handlingEvents_ = true;
evThread_.start();
}
SIPVoIPLink::~SIPVoIPLink()
{
if (evThread_.isRunning())
evThread_.join();
pj_thread_join(thread);
pj_thread_destroy(thread);
handlingEvents_ = false;
if (thread_) {
pj_thread_join(thread_);
pj_thread_destroy(thread_);
DEBUG("PJ thread destroy finished");
thread_ = 0;
}
const pj_time_val tv = {0, 10};
pjsip_endpt_handle_events(endpt_, &tv);
......@@ -503,25 +507,24 @@ SIPVoIPLink::~SIPVoIPLink()
SIPVoIPLink* SIPVoIPLink::instance()
{
static SIPVoIPLink* instance = NULL;
if (!instance)
instance = new SIPVoIPLink;
return instance;
static SIPVoIPLink instance_;
return &instance_;
}
void
SIPVoIPLink::getEvent()
// Called from EventThread::run (not main thread)
bool SIPVoIPLink::getEvent()
{
static pj_thread_desc desc;
// We have to register the external thread so it could access the pjsip frameworks
if (!pj_thread_is_registered())
if (!pj_thread_is_registered()) {
DEBUG("%s: Registering thread", __PRETTY_FUNCTION__);
pj_thread_register(NULL, desc, &thread);
}
static const pj_time_val timeout = {0, 10};
pjsip_endpt_handle_events(endpt_, &timeout);
return handlingEvents_;
}
void SIPVoIPLink::sendRegister(Account *a)
......
......@@ -46,12 +46,11 @@
#include <pjnath.h>
#include <pjnath/stun_config.h>
///////////////////////////////
#include "eventthread.h"
#include "sipaccount.h"
#include "voiplink.h"
#include "siptransport.h"
#include "eventthread.h"
class EventThread;
class SIPCall;
class SIPAccount;
......@@ -75,7 +74,7 @@ class SIPVoIPLink : public VoIPLink {
/**
* Event listener. Each event send by the call manager is received and handled from here
*/
virtual void getEvent();
virtual bool getEvent();
/**
* Build and send SIP registration request
......
......@@ -34,7 +34,7 @@
#include "call.h"
#include "voiplink.h"
VoIPLink::VoIPLink() : callMap_(), callMapMutex_() {}
VoIPLink::VoIPLink() : callMap_(), callMapMutex_(), handlingEvents_(false) {}
VoIPLink::~VoIPLink()
{
......
......@@ -63,7 +63,7 @@ class VoIPLink {
* Virtual method
* Event listener. Each event send by the call manager is received and handled from here
*/
virtual void getEvent() = 0;
virtual bool getEvent() = 0;
/**
* Virtual method
......@@ -183,6 +183,8 @@ class VoIPLink {
/** Mutex to protect call map */
ost::Mutex callMapMutex_;
bool handlingEvents_;
/** Remove a call from the call map (protected by mutex)
* @param id A Call ID
*/
......
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