00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
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;
00092
00093
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
00104
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
00113
00114 time_t WvDailyEvent::next_event() const
00115 {
00116 if (!num_per_day)
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
00126 tm = localtime(&start);
00127 if (tm->tm_hour < first_hour)
00128 {
00129 start = prev - 24*60*60 + 1;
00130 tm = localtime(&start);
00131 }
00132 tm->tm_hour = first_hour;
00133 tm->tm_min = tm->tm_sec = 0;
00134 start = mktime(tm);
00135
00136
00137
00138 next = prev + interval;
00139 if ((next - start)%interval != 0)
00140 next = start + (next - start)/interval * interval + interval;
00141
00142
00143 assert(next);
00144 assert(next > 100000);
00145 while (next < not_until)
00146 next += interval;
00147
00148 return next;
00149 }