Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvdailyevent.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2004 Net Integration Technologies, Inc. 00004 * 00005 * A simple class that can trigger an event on a timed basis. 00006 * a) if given an hour, triggers once per day, on that hour. 00007 * b) if given a number of times per day, triggers that many times per 00008 * day, evenly, starting at the hour given in (a). (Needed to get a 00009 * Microbackup going every 15 minutes.) 00010 * 00011 * Presently has a one-hour granularity in the first case, but that can be 00012 * extended one day when someone cares. 00013 * 00014 */ 00015 #include "wvstream.h" 00016 #include "wvdailyevent.h" 00017 00018 #include <time.h> 00019 00020 #ifndef _WIN32 00021 #include <sys/time.h> 00022 #include <unistd.h> 00023 #endif 00024 00025 WvDailyEvent::WvDailyEvent(int _first_hour, int _num_per_day) 00026 { 00027 need_reset = false; 00028 prev = time(NULL); 00029 configure(_first_hour, _num_per_day); 00030 } 00031 00032 00033 // we're ready if now is later than the next scheduled event 00034 bool WvDailyEvent::pre_select(SelectInfo &si) 00035 { 00036 if (num_per_day && !need_reset) 00037 { 00038 time_t now = time(NULL), next = next_event(); 00039 assert(prev); 00040 assert(next); 00041 assert(prev > 100000); 00042 assert(next > 100000); 00043 if (now >= next) 00044 { 00045 need_reset = true; 00046 prev = next; 00047 } 00048 } 00049 bool ret = WvStream::pre_select(si) || need_reset; 00050 // printf("%p ret=%d msd=%d\n", this, ret, si.msec_timeout); 00051 return ret; 00052 } 00053 00054 00055 bool WvDailyEvent::post_select(SelectInfo& si) 00056 { 00057 return need_reset; 00058 } 00059 00060 00061 void WvDailyEvent::execute() 00062 { 00063 WvStream::execute(); 00064 reset(); 00065 } 00066 00067 00068 void WvDailyEvent::reset() 00069 { 00070 need_reset = false; 00071 } 00072 00073 00074 bool WvDailyEvent::isok() const 00075 { 00076 return true; 00077 } 00078 00079 00080 void WvDailyEvent::set_num_per_day(int _num_per_day) 00081 { 00082 num_per_day = _num_per_day; 00083 if (num_per_day < 0) 00084 num_per_day = 1; 00085 00086 if (num_per_day > 24*60*60) 00087 num_per_day = 24*60*60; 00088 00089 time_t max = num_per_day ? (24*60*60)/num_per_day : 6*60*60; 00090 if (max > 6*60*60) 00091 max = 6*60*60; // unless that's a very long time, 6 hrs 00092 00093 // don't start until at least one period has gone by 00094 not_until = time(NULL) + max; 00095 prev = time(NULL); 00096 } 00097 00098 00099 void WvDailyEvent::configure(int _first_hour, int _num_per_day) 00100 { 00101 first_hour = _first_hour; 00102 00103 // Don't let WvDailyEvents occur more than once a minute. -- use an alarm 00104 // instead 00105 if (_num_per_day > 24*60) 00106 _num_per_day = 24*60; 00107 00108 set_num_per_day(_num_per_day); 00109 } 00110 00111 00112 // the daily event occurs each day at first_hour on the hour, or at 00113 // some multiple of the interval *after* that hour. 00114 time_t WvDailyEvent::next_event() const 00115 { 00116 if (!num_per_day) // disabled 00117 return 0; 00118 00119 time_t start, next, interval = 24*60*60/num_per_day; 00120 struct tm *tm; 00121 00122 assert(prev); 00123 start = prev + interval; 00124 00125 // find the time to start counting from (up to 24 hours in the past) 00126 tm = localtime(&start); 00127 if (tm->tm_hour < first_hour) 00128 { 00129 start = prev - 24*60*60 + 1; // this time yesterday 00130 tm = localtime(&start); 00131 } 00132 tm->tm_hour = first_hour; // always start at the given hour 00133 tm->tm_min = tm->tm_sec = 0; // right on the hour 00134 start = mktime(tm); // convert back into a time_t 00135 00136 // find the next event after prev that's a multiple of 'interval' 00137 // since 'start' 00138 next = prev + interval; 00139 if ((next - start)%interval != 0) 00140 next = start + (next - start)/interval * interval + interval; 00141 00142 // too soon after configuration - skip the event 00143 assert(next); 00144 assert(next > 100000); 00145 while (next < not_until) 00146 next += interval; 00147 00148 return next; 00149 }

Generated on Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7