//------------------------------------------------------------ void* CTimerManager::timerThread(void *arg) { CTimerManager *timerManager = (CTimerManager*) arg; bool saveEvents; int wait = ((int)time(NULL)) % 20; // Start at a multiple of 20 sec sleep(wait); while(1) { saveEvents = false; time_t now = time(NULL); dprintf("Timer Thread time: %u\n", (uint) now); // fire events who's time has come CTimerEvent *event; CTimerEventMap::iterator pos = timerManager->events.begin(); for(;pos != timerManager->events.end();pos++) { event = pos->second; if(debug) event->printEvent(); // print all events (debug) if(event->announceTime > 0 && event->eventState == CTimerd::TIMERSTATE_SCHEDULED ) // if event wants to be announced if( event->announceTime <= now ) // check if event announcetime has come { event->setState(CTimerd::TIMERSTATE_PREANNOUNCE); event->announceEvent(); // event specific announce handler saveEvents = true; } if(event->alarmTime > 0 && (event->eventState == CTimerd::TIMERSTATE_SCHEDULED || event->eventState == CTimerd::TIMERSTATE_PREANNOUNCE) ) // if event wants to be fired if( event->alarmTime <= now ) // check if event alarmtime has come { event->setState(CTimerd::TIMERSTATE_ISRUNNING); event->fireEvent(); // fire event specific handler if(event->stopTime == 0) // if event needs no stop event event->setState(CTimerd::TIMERSTATE_HASFINISHED); saveEvents = true; } if(event->stopTime > 0 && event->eventState == CTimerd::TIMERSTATE_ISRUNNING ) // check if stopevent is wanted if( event->stopTime <= now ) // check if event stoptime has come { event->stopEvent(); // event specific stop handler event->setState(CTimerd::TIMERSTATE_HASFINISHED); saveEvents = true; } if(event->eventState == CTimerd::TIMERSTATE_HASFINISHED) { if(event->eventRepeat != CTimerd::TIMERREPEAT_ONCE) event->Reschedule(); else event->setState(CTimerd::TIMERSTATE_TERMINATED); saveEvents = true; } if(event->eventState == CTimerd::TIMERSTATE_TERMINATED) // event is terminated, so delete it { delete pos->second; // delete event timerManager->events.erase(pos); // remove from list saveEvents = true; } } /* minutes = (int) (zeit - time(NULL)) / 60; if (ioctl(fd, FP_IOCTL_SET_WAKEUP_TIMER, &minutes)<0) perror("FP_IOCTL_SET_WAKEUP_TIMER"); */ if(saveEvents) timerManager->saveEventsToConfig(); (debug)?usleep(10 * 1000000):usleep(20 * 1000000); // sleep for 10 / 20 seconds } return 0; }
//------------------------------------------------------------ void* CTimerManager::timerThread(void *arg) { pthread_mutex_t dummy_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t dummy_cond = PTHREAD_COND_INITIALIZER; struct timespec wait; CTimerManager *timerManager = (CTimerManager*) arg; int sleeptime=(timerd_debug)?10:20; while(1) { if(!timerManager->m_isTimeSet) { // time not set yet if (timeset) { dprintf("sectionsd says \"time ok\"\n"); timerManager->m_isTimeSet=true; timerManager->loadEventsFromConfig(); } else { dprintf("waiting for time to be set\n"); wait.tv_sec = time(NULL) + 5 ; wait.tv_nsec = 0; pthread_cond_timedwait(&dummy_cond, &dummy_mutex, &wait); } } else { time_t now = time(NULL); dprintf("Timer Thread time: %u: %s", (uint) now, ctime(&now)); // fire events who's time has come CTimerEvent *event; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); pthread_mutex_lock(&tm_eventsMutex); CTimerEventMap::iterator pos = timerManager->events.begin(); for(;pos != timerManager->events.end();++pos) { event = pos->second; dprintf("checking event: %03d\n",event->eventID); if (timerd_debug) event->printEvent(); if(event->announceTime > 0 && event->eventState == CTimerd::TIMERSTATE_SCHEDULED ) // if event wants to be announced if( event->announceTime <= now ) // check if event announcetime has come { event->setState(CTimerd::TIMERSTATE_PREANNOUNCE); dprintf("announcing event\n"); event->announceEvent(); // event specific announce handler timerManager->m_saveEvents = true; } if(event->alarmTime > 0 && (event->eventState == CTimerd::TIMERSTATE_SCHEDULED || event->eventState == CTimerd::TIMERSTATE_PREANNOUNCE) ) // if event wants to be fired if( event->alarmTime <= now ) // check if event alarmtime has come { event->setState(CTimerd::TIMERSTATE_ISRUNNING); dprintf("firing event\n"); event->fireEvent(); // fire event specific handler if(event->stopTime == 0) // if event needs no stop event event->setState(CTimerd::TIMERSTATE_HASFINISHED); timerManager->m_saveEvents = true; } if(event->stopTime > 0 && event->eventState == CTimerd::TIMERSTATE_ISRUNNING ) // check if stopevent is wanted if( event->stopTime <= now ) // check if event stoptime has come { dprintf("stopping event\n"); event->stopEvent(); // event specific stop handler event->setState(CTimerd::TIMERSTATE_HASFINISHED); timerManager->m_saveEvents = true; } if(event->eventState == CTimerd::TIMERSTATE_HASFINISHED) { if((event->eventRepeat != CTimerd::TIMERREPEAT_ONCE) && (event->repeatCount != 1)) { dprintf("rescheduling event\n"); event->Reschedule(); } else { dprintf("event terminated\n"); event->setState(CTimerd::TIMERSTATE_TERMINATED); } timerManager->m_saveEvents = true; } if(event->eventState == CTimerd::TIMERSTATE_TERMINATED) // event is terminated, so delete it { dprintf("deleting event\n"); if (timerd_debug) pos->second->printEvent(); dprintf("\n"); delete pos->second; // delete event timerManager->events.erase(pos++); // remove from list timerManager->m_saveEvents = true; if(pos == timerManager->events.end()) break; } } pthread_mutex_unlock(&tm_eventsMutex); // save events if requested if(timerManager->m_saveEvents) { timerManager->saveEventsToConfig(); } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); wait.tv_sec = (((time(NULL) / sleeptime) * sleeptime) + sleeptime); wait.tv_nsec = 0; pthread_cond_timedwait(&dummy_cond, &dummy_mutex, &wait); } } return 0; }