/*MT* MediaTomb - http://www.mediatomb.cc/ timer.cc - this file is part of MediaTomb. Copyright (C) 2005 Gena Batyan , Sergey 'Jin' Bostandzhyan Copyright (C) 2006-2007 Gena Batyan , Sergey 'Jin' Bostandzhyan , Leonhard Wimmer MediaTomb is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. MediaTomb 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 version 2 along with MediaTomb; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. $Id: timer.cc 1174 2007-02-25 17:19:44Z lww $ */ /// \file timer.cc #ifdef HAVE_CONFIG_H #include "autoconfig.h" #endif #include "timer.h" using namespace zmm; SINGLETON_MUTEX(Timer, true); template <> Ref > > > Timer::getAppropriateSubscribers >() { if (subscribersSingleton == nil) throw _Exception(_("timer already inactive!")); return subscribersSingleton; } template <> Ref > > Timer::getAppropriateSubscribers() { if (subscribersObject == nil) throw _Exception(_("timer already inactive!")); return subscribersObject; } Timer::Timer() : Singleton() { subscribersSingleton = Ref > > >(new Array > >); subscribersObject = Ref > >(new Array >); cond = Ref(new Cond(mutex)); } void Timer::triggerWait() { log_debug("triggerWait. - %d subscriber(s)\n", subscribersSingleton->size()); AUTOLOCK(mutex); if (subscribersSingleton->size() > 0 || subscribersObject->size() > 0) { struct timespec *timeout = getNextNotifyTime(); struct timespec now; getTimespecNow(&now); if (compareTimespecs(timeout, &now) < 0) { log_debug("sleeping...\n"); int ret = cond->timedwait(timeout); if (ret != 0 && ret != ETIMEDOUT) { log_debug("pthread_cond_timedwait returned errorcode %d\n", ret); throw _Exception(_("pthread_cond_timedwait returned errorcode ") + ret); } if (ret == ETIMEDOUT) { notify >(); notify(); } } else { notify >(); notify(); } } else { log_debug("nothing to do, sleeping...\n"); cond->wait(); } } struct timespec * Timer::getNextNotifyTime() { struct timespec *nextTime = NULL; for(int i = 0; i < subscribersSingleton->size(); i++) { struct timespec *nextNotify = subscribersSingleton->get(i)->getNextNotify(); if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0) { nextTime = nextNotify; } } for(int i = 0; i < subscribersObject->size(); i++) { struct timespec *nextNotify = subscribersObject->get(i)->getNextNotify(); if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0) { nextTime = nextNotify; } } return nextTime; } void Timer::shutdown() { subscribersSingleton = nil; subscribersObject = nil; log_debug("finished.\n"); }