00001 /*MT* 00002 00003 MediaTomb - http://www.mediatomb.cc/ 00004 00005 timer.cc - this file is part of MediaTomb. 00006 00007 Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, 00008 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> 00009 00010 Copyright (C) 2006-2010 Gena Batyan <bgeradz@mediatomb.cc>, 00011 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, 00012 Leonhard Wimmer <leo@mediatomb.cc> 00013 00014 MediaTomb is free software; you can redistribute it and/or modify 00015 it under the terms of the GNU General Public License version 2 00016 as published by the Free Software Foundation. 00017 00018 MediaTomb is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 GNU General Public License for more details. 00022 00023 You should have received a copy of the GNU General Public License 00024 version 2 along with MediaTomb; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00026 00027 $Id: timer.cc 2081 2010-03-23 20:18:00Z lww $ 00028 */ 00029 00031 00032 #ifdef HAVE_CONFIG_H 00033 #include "autoconfig.h" 00034 #endif 00035 00036 #include "timer.h" 00037 00038 using namespace zmm; 00039 00040 SINGLETON_MUTEX(Timer, true); 00041 00042 template <> 00043 Ref<Array<Timer::TimerSubscriberElement<TimerSubscriberSingleton<Object> > > > Timer::getAppropriateSubscribers<TimerSubscriberSingleton<Object> >() 00044 { 00045 if (subscribersSingleton == nil) 00046 throw _Exception(_("timer already inactive!")); 00047 return subscribersSingleton; 00048 } 00049 00050 template <> 00051 Ref<Array<Timer::TimerSubscriberElement<TimerSubscriberObject> > > Timer::getAppropriateSubscribers<TimerSubscriberObject>() 00052 { 00053 if (subscribersObject == nil) 00054 throw _Exception(_("timer already inactive!")); 00055 return subscribersObject; 00056 } 00057 00058 Timer::Timer() : Singleton<Timer>() 00059 { 00060 subscribersSingleton = Ref<Array<TimerSubscriberElement<TimerSubscriberSingleton<Object> > > >(new Array<TimerSubscriberElement<TimerSubscriberSingleton<Object> > >); 00061 subscribersObject = Ref<Array<TimerSubscriberElement<TimerSubscriberObject> > >(new Array<TimerSubscriberElement<TimerSubscriberObject> >); 00062 cond = Ref<Cond>(new Cond(mutex)); 00063 } 00064 00065 void Timer::triggerWait() 00066 { 00067 log_debug("triggerWait. - %d subscriber(s)\n", subscribersSingleton->size()); 00068 00069 AUTOLOCK(mutex); 00070 if (subscribersSingleton->size() > 0 || subscribersObject->size() > 0) 00071 { 00072 struct timespec *timeout = getNextNotifyTime(); 00073 struct timespec now; 00074 getTimespecNow(&now); 00075 if (compareTimespecs(timeout, &now) < 0) 00076 { 00077 log_debug("sleeping...\n"); 00078 int ret = cond->timedwait(timeout); 00079 if (ret != 0 && ret != ETIMEDOUT) 00080 { 00081 log_debug("pthread_cond_timedwait returned errorcode %d\n", ret); 00082 throw _Exception(_("pthread_cond_timedwait returned errorcode ") + ret); 00083 } 00084 if (ret == ETIMEDOUT) 00085 { 00086 notify<TimerSubscriberSingleton<Object> >(); 00087 notify<TimerSubscriberObject>(); 00088 } 00089 } 00090 else 00091 { 00092 notify<TimerSubscriberSingleton<Object> >(); 00093 notify<TimerSubscriberObject>(); 00094 } 00095 } 00096 else 00097 { 00098 log_debug("nothing to do, sleeping...\n"); 00099 cond->wait(); 00100 } 00101 } 00102 00103 struct timespec * Timer::getNextNotifyTime() 00104 { 00105 struct timespec *nextTime = NULL; 00106 for(int i = 0; i < subscribersSingleton->size(); i++) 00107 { 00108 struct timespec *nextNotify = subscribersSingleton->get(i)->getNextNotify(); 00109 if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0) 00110 { 00111 nextTime = nextNotify; 00112 } 00113 } 00114 for(int i = 0; i < subscribersObject->size(); i++) 00115 { 00116 struct timespec *nextNotify = subscribersObject->get(i)->getNextNotify(); 00117 if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0) 00118 { 00119 nextTime = nextNotify; 00120 } 00121 } 00122 return nextTime; 00123 } 00124 00125 void Timer::shutdown() 00126 { 00127 subscribersSingleton = nil; 00128 subscribersObject = nil; 00129 log_debug("finished.\n"); 00130 }
1.6.1