Skip to content
Snippets Groups Projects
Commit 4666e7a3 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

daemon: poll IAX and SIP events in main thread

This means that clients implementing their own event loops (i.e. not
using DBus) will have to explicitly call ManagerImpl::pollEvents()

Refs #48160
Refs #49119

Change-Id: I0001c68f13c97da54b1d29bce9134161c31dfb82
parent 1bc81905
No related branches found
No related tags found
No related merge requests found
......@@ -78,7 +78,6 @@ libsflphone_la_SOURCES = conference.cpp \
preferences.cpp \
managerimpl.cpp \
manager.cpp \
eventthread.cpp \
call.cpp \
account.cpp \
logger.c \
......@@ -94,7 +93,6 @@ libsflphone_la_SOURCES = conference.cpp \
managerimpl.h \
manager.h \
global.h \
eventthread.h \
account.h \
call.h \
logger.h \
......
......@@ -53,6 +53,9 @@ class VideoManager;
namespace DBus {
class BusDispatcher;
}
#include <functional>
#endif
class Client {
......@@ -74,6 +77,10 @@ class Client {
int event_loop();
int exit();
#ifdef HAVE_DBUS
// DBus provides our event loop
void registerCallback(const std::function<void()> &callback);
#endif
#if HAVE_DBUS
void onLastUnregister();
......
......@@ -53,9 +53,19 @@
#include "videomanager.h"
#endif
struct DummyCallback : DBus::Callback_Base<void, DBus::DefaultTimeout&>
struct EventCallback : DBus::Callback_Base<void, DBus::DefaultTimeout&>
{
void call(DBus::DefaultTimeout &) const {}
EventCallback(const std::function<void()> &func) :
callback_(func)
{}
void call(DBus::DefaultTimeout &) const
{
callback_();
}
private:
std::function<void()> callback_;
};
Client::Client() : callManager_(0)
......@@ -78,13 +88,6 @@ Client::Client() : callManager_(0)
DEBUG("DBUS instantiate default dispatcher");
DBus::default_dispatcher = dispatcher_;
// This timeout is useless except that it shortens DBus' polling
// timeout (the default is 10 seconds).
// timeout and expired are deleted internally by dispatcher_'s
// destructor, so we must NOT delete them ourselves.
DBus::DefaultTimeout *timeout = new DBus::DefaultTimeout(1000, true, dispatcher_);
timeout->expired = new DummyCallback;
DEBUG("DBUS session connection to session bus");
DBus::Connection sessionConnection(DBus::Connection::SessionBus());
DEBUG("DBUS request org.sflphone.SFLphone from session connection");
......@@ -139,6 +142,18 @@ Client::~Client()
delete dispatcher_;
}
void
Client::registerCallback(const std::function<void()> &callback)
{
// timeout and expired are deleted internally by dispatcher_'s
// destructor, so we must NOT delete them ourselves.
DBus::DefaultTimeout *timeout = new DBus::DefaultTimeout(10 /* ms */,
true,
dispatcher_);
timeout->expired = new EventCallback(callback);
}
int Client::event_loop()
{
try {
......
/*
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
* Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include "eventthread.h"
#include "voiplink.h"
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
#define YIELD std::this_thread::yield
#elif __llvm__
#include <sched.h>
#define YIELD sched_yield
#else
#define YIELD pthread_yield
#endif
EventThread::EventThread(VoIPLink &link) : link_(link), thread_()
{}
EventThread::~EventThread()
{
join();
}
void EventThread::join()
{
if (thread_.joinable())
thread_.join();
}
void EventThread::start()
{
thread_ = std::thread(&EventThread::run, this);
}
void EventThread::run()
{
while (link_.getEvent())
YIELD();
}
/*
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
* Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef EVENT_THREAD_H_
#define EVENT_THREAD_H_
#include <thread>
class VoIPLink;
/**
* @file eventthread.h
* @brief Runs thread which listens to VoIP events continuously
*/
class EventThread {
public:
EventThread(VoIPLink& link);
~EventThread();
// spawns thread
void start();
void join();
private:
// VoIPLink is the object being called by getEvents() method
VoIPLink& link_;
std::thread thread_;
void run();
};
#endif // EVENT_THREAD_H__
......@@ -34,7 +34,6 @@
#include <algorithm>
#include "iaxcall.h"
#include "eventthread.h"
#include "iaxaccount.h"
#include "logger.h"
#include "manager.h"
......@@ -56,7 +55,6 @@ IAXVoIPLink::IAXVoIPLink(IAXAccount& account) :
, resampler_(44100)
, initDone_(false)
, account_(account)
, evThread_(*this)
{
srand(time(NULL)); // to get random number for RANDOM_PORT
}
......@@ -80,7 +78,6 @@ IAXVoIPLink::init()
for (int port = IAX_DEFAULT_PORTNO, nbTry = 0; nbTry < 3 ; port = rand() % 64000 + 1024, nbTry++) {
if (iax_init(port) >= 0) {
handlingEvents_ = true;
evThread_.start();
initDone_ = true;
break;
}
......@@ -106,7 +103,6 @@ IAXVoIPLink::terminate()
}
iaxCallMap_.clear();
evThread_.join();
initDone_ = false;
}
......
......@@ -44,7 +44,6 @@
#include "sfl_types.h"
#include "noncopyable.h"
#include "audio/resampler.h"
#include "eventthread.h"
#include <iax-client.h>
......@@ -204,11 +203,6 @@ class IAXVoIPLink : public VoIPLink {
bool initDone_;
IAXAccount& account_;
/**
* Threading object
*/
EventThread evThread_;
};
#endif
......@@ -242,6 +242,9 @@ int
ManagerImpl::run()
{
DEBUG("Starting client event loop");
client_.registerCallback(std::bind(&ManagerImpl::pollEvents, std::ref(*this)));
return client_.event_loop();
}
......@@ -1309,6 +1312,20 @@ ManagerImpl::removeStream(const std::string& call_id)
getMainBuffer().unBindAll(call_id);
}
// Must be invoked periodically by a timer from the main event loop
void ManagerImpl::pollEvents()
{
if (finished_)
return;
SIPVoIPLink::instance().getEvent();
#if HAVE_IAX
for (auto &item : IAXVoIPLink::getAccounts())
item.second->getVoIPLink()->getEvent();
#endif
}
//THREAD=Main
void
ManagerImpl::saveConfig()
......
......@@ -998,6 +998,11 @@ class ManagerImpl {
void
checkAudio();
/**
* Call periodically to poll for VoIP events */
void
pollEvents();
private:
NON_COPYABLE(ManagerImpl);
......
......@@ -267,6 +267,8 @@ SIPAccount::SIPAccount(const std::string& accountID, bool presenceEnabled)
SIPAccount::~SIPAccount()
{
// ensure that no registration callbacks survive past this point
destroyRegistrationInfo();
setTransport();
#ifdef SFL_PRESENCE
......
......@@ -480,7 +480,7 @@ pj_pool_t* SIPVoIPLink::getPool() const
}
SIPVoIPLink::SIPVoIPLink() : sipTransport(), sipAccountMap_(),
sipCallMapMutex_(), sipCallMap_(), evThread_(*this)
sipCallMapMutex_(), sipCallMap_()
#ifdef SFL_VIDEO
, keyframeRequestsMutex_()
, keyframeRequests_()
......@@ -570,7 +570,6 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(), sipAccountMap_(),
#undef TRY
handlingEvents_ = true;
evThread_.start();
}
SIPVoIPLink::~SIPVoIPLink()
......@@ -581,7 +580,6 @@ SIPVoIPLink::~SIPVoIPLink()
sleep(1);
handlingEvents_ = false;
evThread_.join();
const pj_time_val tv = {0, 10};
pjsip_endpt_handle_events(endpt_, &tv);
......
......@@ -44,8 +44,6 @@
#include "sipaccount.h"
#include "siptransport.h"
#include "eventthread.h"
#include <pjsip.h>
#include <pjlib.h>
#include <pjsip_ua.h>
......@@ -206,11 +204,6 @@ class SIPVoIPLink : public VoIPLink {
mutable std::mutex sipCallMapMutex_;
SipCallMap sipCallMap_;
/**
* Threading object
*/
EventThread evThread_;
#ifdef SFL_VIDEO
void dequeKeyframeRequests();
void requestKeyframe(const std::string &callID);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment