
Merge branch 'master' of git://anongit.freedesktop.org/git/dbus/dbus-c++ Conflicts: include/dbus-c++/connection.h include/dbus-c++/dispatcher.h include/dbus-c++/pendingcall.h src/dispatcher.cpp
251 lines
4.5 KiB
C++
251 lines
4.5 KiB
C++
/*
|
|
*
|
|
* D-Bus++ - C++ bindings for D-Bus
|
|
*
|
|
* Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
|
|
*
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include <dbus-c++/dbus-c++-config.h>
|
|
|
|
#include <dbus-c++/eventloop.h>
|
|
#include <dbus-c++/debug.h>
|
|
|
|
#include <sys/poll.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <dbus/dbus.h>
|
|
|
|
using namespace DBus;
|
|
|
|
static double millis(timeval tv)
|
|
{
|
|
return (tv.tv_sec *1000.0 + tv.tv_usec/1000.0);
|
|
}
|
|
|
|
DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
|
|
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
|
|
{
|
|
timeval now;
|
|
gettimeofday(&now, NULL);
|
|
|
|
_expiration = millis(now) + interval;
|
|
|
|
_disp->_mutex_t.lock();
|
|
_disp->_timeouts.push_back(this);
|
|
_disp->_mutex_t.unlock();
|
|
}
|
|
|
|
DefaultTimeout::~DefaultTimeout()
|
|
{
|
|
_disp->_mutex_t.lock();
|
|
_disp->_timeouts.remove(this);
|
|
_disp->_mutex_t.unlock();
|
|
}
|
|
|
|
DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
|
|
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
|
|
{
|
|
_disp->_mutex_w.lock();
|
|
_disp->_watches.push_back(this);
|
|
_disp->_mutex_w.unlock();
|
|
}
|
|
|
|
DefaultWatch::~DefaultWatch()
|
|
{
|
|
_disp->_mutex_w.lock();
|
|
_disp->_watches.remove(this);
|
|
_disp->_mutex_w.unlock();
|
|
}
|
|
|
|
DefaultMutex::DefaultMutex()
|
|
{
|
|
#if defined HAVE_PTHREAD_H
|
|
|
|
pthread_mutex_init(&_mutex, NULL);
|
|
|
|
#elif defined HAVE_WIN32
|
|
#endif
|
|
}
|
|
|
|
DefaultMutex::~DefaultMutex()
|
|
{
|
|
#if defined HAVE_PTHREAD_H
|
|
|
|
pthread_mutex_destroy(&_mutex);
|
|
|
|
#elif defined HAVE_WIN32
|
|
#endif
|
|
}
|
|
|
|
void DefaultMutex::lock()
|
|
{
|
|
#if defined HAVE_PTHREAD_H
|
|
|
|
pthread_mutex_lock(&_mutex);
|
|
|
|
#elif defined HAVE_WIN32
|
|
#endif
|
|
}
|
|
|
|
void DefaultMutex::unlock()
|
|
{
|
|
#if defined HAVE_PTHREAD_H
|
|
|
|
pthread_mutex_unlock(&_mutex);
|
|
|
|
#elif defined HAVE_WIN32
|
|
#endif
|
|
}
|
|
|
|
DefaultMainLoop::DefaultMainLoop()
|
|
{
|
|
}
|
|
|
|
DefaultMainLoop::~DefaultMainLoop()
|
|
{
|
|
_mutex_w.lock();
|
|
|
|
DefaultWatches::iterator wi = _watches.begin();
|
|
while (wi != _watches.end())
|
|
{
|
|
DefaultWatches::iterator wmp = wi;
|
|
++wmp;
|
|
_mutex_w.unlock();
|
|
delete (*wi);
|
|
_mutex_w.lock();
|
|
wi = wmp;
|
|
}
|
|
_mutex_w.unlock();
|
|
|
|
_mutex_t.lock();
|
|
|
|
DefaultTimeouts::iterator ti = _timeouts.begin();
|
|
while (ti != _timeouts.end())
|
|
{
|
|
DefaultTimeouts::iterator tmp = ti;
|
|
++tmp;
|
|
_mutex_t.unlock();
|
|
delete (*ti);
|
|
_mutex_t.lock();
|
|
ti = tmp;
|
|
}
|
|
_mutex_t.unlock();
|
|
}
|
|
|
|
void DefaultMainLoop::dispatch()
|
|
{
|
|
_mutex_w.lock();
|
|
|
|
int nfd = _watches.size();
|
|
|
|
pollfd fds[nfd];
|
|
|
|
DefaultWatches::iterator wi = _watches.begin();
|
|
|
|
for (nfd = 0; wi != _watches.end(); ++wi)
|
|
{
|
|
if ((*wi)->enabled())
|
|
{
|
|
fds[nfd].fd = (*wi)->descriptor();
|
|
fds[nfd].events = (*wi)->flags();
|
|
fds[nfd].revents = 0;
|
|
|
|
++nfd;
|
|
}
|
|
}
|
|
_mutex_w.unlock();
|
|
|
|
int wait_min = 10000;
|
|
|
|
DefaultTimeouts::iterator ti;
|
|
|
|
_mutex_t.lock();
|
|
|
|
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
|
|
{
|
|
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
|
|
wait_min = (*ti)->interval();
|
|
}
|
|
|
|
_mutex_t.unlock();
|
|
|
|
poll(fds, nfd, wait_min);
|
|
|
|
timeval now;
|
|
gettimeofday(&now, NULL);
|
|
|
|
double now_millis = millis(now);
|
|
|
|
_mutex_t.lock();
|
|
|
|
ti = _timeouts.begin();
|
|
|
|
while (ti != _timeouts.end())
|
|
{
|
|
DefaultTimeouts::iterator tmp = ti;
|
|
++tmp;
|
|
|
|
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
|
|
{
|
|
(*ti)->expired(*(*ti));
|
|
|
|
if ((*ti)->_repeat)
|
|
{
|
|
(*ti)->_expiration = now_millis + (*ti)->_interval;
|
|
}
|
|
|
|
}
|
|
|
|
ti = tmp;
|
|
}
|
|
|
|
_mutex_t.unlock();
|
|
|
|
_mutex_w.lock();
|
|
|
|
for (int j = 0; j < nfd; ++j)
|
|
{
|
|
DefaultWatches::iterator wi;
|
|
|
|
for (wi = _watches.begin(); wi != _watches.end();)
|
|
{
|
|
DefaultWatches::iterator tmp = wi;
|
|
++tmp;
|
|
|
|
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
|
|
{
|
|
if (fds[j].revents)
|
|
{
|
|
(*wi)->_state = fds[j].revents;
|
|
|
|
(*wi)->ready(*(*wi));
|
|
|
|
fds[j].revents = 0;
|
|
}
|
|
}
|
|
|
|
wi = tmp;
|
|
}
|
|
}
|
|
_mutex_w.unlock();
|
|
}
|
|
|