Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | 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 Wed Dec 15 15:08:10 2004 for WvStreams by  doxygen 1.3.9.1