00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wvdailyevent.h"
00016 #include "wvstream.h"
00017 #include "wvtimeutils.h"
00018
00019 #include <time.h>
00020
00021 #ifndef _WIN32
00022 #include <sys/time.h>
00023 #include <unistd.h>
00024 #endif
00025
00026 #define NUM_MINS_IN_DAY (24*60)
00027 #define NUM_SECS_IN_DAY (60*NUM_MINS_IN_DAY)
00028
00029 WvDailyEvent::WvDailyEvent(int _first_hour, int _num_per_day, bool _skip_first)
00030 : prev(time(NULL))
00031 {
00032 configure(_first_hour, _num_per_day, _skip_first);
00033 }
00034
00035
00036
00037 bool WvDailyEvent::pre_select(SelectInfo &si)
00038 {
00039 WvTime next(next_event(), 0);
00040 if (next)
00041 si.msec_timeout = msecdiff(next, wvtime());
00042 return WvStream::pre_select(si);
00043 }
00044
00045
00046
00047 bool WvDailyEvent::post_select(SelectInfo& si)
00048 {
00049 bool timer_rang = false;
00050 WvTime next(next_event(), 0);
00051 if (next < wvtime())
00052 {
00053 timer_rang = true;
00054 prev = next;
00055 }
00056
00057 return WvStream::post_select(si) || timer_rang;
00058 }
00059
00060
00061 void WvDailyEvent::set_num_per_day(int _num_per_day)
00062 {
00063 num_per_day = _num_per_day;
00064 if (num_per_day < 0)
00065 num_per_day = 1;
00066
00067 if (num_per_day > NUM_SECS_IN_DAY)
00068 num_per_day = NUM_SECS_IN_DAY;
00069
00070 time_t max = num_per_day ? NUM_SECS_IN_DAY/num_per_day : 6*60*60;
00071 if (max > 6*60*60)
00072 max = 6*60*60;
00073
00074
00075 prev = time(NULL);
00076 not_until = prev + max;
00077 }
00078
00079
00080 void WvDailyEvent::configure(int _first_hour, int _num_per_day, bool _skip_first)
00081 {
00082 first_hour = _first_hour;
00083 skip_first = _skip_first;
00084
00085
00086
00087 if (_num_per_day > NUM_MINS_IN_DAY)
00088 _num_per_day = NUM_MINS_IN_DAY;
00089
00090 set_num_per_day(_num_per_day);
00091 }
00092
00093
00094
00095 time_t WvDailyEvent::next_event() const
00096 {
00097 if (!num_per_day)
00098 return 0;
00099
00100 assert(prev);
00101
00102 time_t interval = NUM_SECS_IN_DAY/num_per_day;
00103 time_t start = prev + interval;
00104
00105
00106 struct tm *tm = localtime(&start);
00107 if (tm->tm_hour < first_hour)
00108 {
00109 start = prev - NUM_SECS_IN_DAY + 1;
00110 tm = localtime(&start);
00111 }
00112 tm->tm_hour = first_hour;
00113 tm->tm_min = tm->tm_sec = 0;
00114 start = mktime(tm);
00115
00116
00117
00118 time_t next = prev + interval;
00119 if ((next - start)%interval != 0)
00120 next = start + (next - start)/interval * interval;
00121
00122 assert(next);
00123 assert(next > 100000);
00124
00125 while (skip_first && next < not_until)
00126 next += interval;
00127
00128 return next;
00129 }