WvStreams
|
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * See wvtimestream.h. 00006 */ 00007 #include "wvtimestream.h" 00008 00009 WvTimeStream::WvTimeStream(): 00010 last(wvtime_zero), next(wvtime_zero), ms_per_tick(0) 00011 { 00012 } 00013 00014 00015 void WvTimeStream::set_timer(time_t msec) 00016 { 00017 WvTime now = wvstime(); 00018 00019 ms_per_tick = msec > 0 ? msec : 0; 00020 next = msecadd(now, ms_per_tick); 00021 last = now; 00022 } 00023 00024 00025 bool WvTimeStream::isok() const 00026 { 00027 return true; 00028 } 00029 00030 00031 void WvTimeStream::pre_select(SelectInfo &si) 00032 { 00033 WvTime now; 00034 time_t diff; 00035 WvStream::pre_select(si); 00036 00037 //fprintf(stderr, "%p: timestream pre_select mspt=%ld msto=%ld\n", 00038 // this, ms_per_tick, si.msec_timeout); 00039 00040 if (ms_per_tick) 00041 { 00042 now = wvstime(); 00043 00044 /* Are we going back in time? If so, adjust the due time. */ 00045 if (now < last) 00046 next = tvdiff(next, tvdiff(last, now)); 00047 00048 last = now; 00049 00050 if (next <= now) 00051 { 00052 si.msec_timeout = 0; 00053 return; 00054 } 00055 00056 diff = msecdiff(next, now); 00057 diff = diff < 0 ? 0 : diff; 00058 if (diff < si.msec_timeout || si.msec_timeout < 0) 00059 si.msec_timeout = diff; 00060 } 00061 } 00062 00063 00064 bool WvTimeStream::post_select(SelectInfo &si) 00065 { 00066 WvTime now = wvstime(); 00067 00068 return WvStream::post_select(si) || (ms_per_tick && next <= now); 00069 } 00070 00071 00072 void WvTimeStream::execute() 00073 { 00074 WvStream::execute(); 00075 00076 /* Schedule our next timer event, unless alarm_is_ticking, which 00077 * would mean that we're here because someone used alarm() rather 00078 * than because our timer expired. */ 00079 if (!alarm_was_ticking) 00080 { 00081 WvTime now = wvstime(); 00082 00083 next = msecadd(next, ms_per_tick); 00084 00085 if (msecdiff(next, now) > ms_per_tick * 100 || 00086 msecdiff(now, next) > ms_per_tick * 100) 00087 { 00088 // reset if we fall forward or behind WAY too excessively 00089 // This is usually due to a change in system time 00090 last = now; 00091 next = msecadd(last, ms_per_tick); 00092 } 00093 else if (msecdiff(next, now) > ms_per_tick * 10) 00094 // compensate if we fall behind too excessively 00095 next = msecadd(now, ms_per_tick); 00096 } 00097 }