00001
00002
00003
00004
00005
00006
00007
00008 #include "wvstreamlist.h"
00009
00010
00011
00012 #define STREAMTRACE 0
00013 #if STREAMTRACE
00014 # define TRACE(x, y...) fprintf(stderr, x, ## y)
00015 #else
00016 #ifndef _MSC_VER
00017 # define TRACE(x, y...)
00018 #else
00019 # define TRACE
00020 #endif
00021 #endif
00022
00023 WvStreamList::WvStreamList()
00024 {
00025 auto_prune = true;
00026 }
00027
00028
00029 WvStreamList::~WvStreamList()
00030 {
00031
00032 }
00033
00034
00035 bool WvStreamList::isok() const
00036 {
00037 return WvError::isok();
00038 }
00039
00040
00041 bool WvStreamList::pre_select(SelectInfo &si)
00042 {
00043 bool one_dead = false;
00044 SelectRequest oldwant;
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 if (running_callback)
00058 return true;
00059
00060 sure_thing.zap();
00061
00062 time_t alarmleft = alarm_remaining();
00063 if (alarmleft == 0)
00064 return true;
00065
00066 oldwant = si.wants;
00067
00068 Iter i(*this);
00069 for (i.rewind(); i.next(); )
00070 {
00071 WvStream &s(*i);
00072
00073 if (!s.isok())
00074 {
00075 one_dead = true;
00076 if (auto_prune)
00077 i.xunlink();
00078 continue;
00079 }
00080
00081
00082
00083
00084 if (s.isok() && s.pre_select(si))
00085 sure_thing.append(&s, false, i.link->id);
00086 }
00087
00088 if (alarmleft >= 0 && (alarmleft < si.msec_timeout || si.msec_timeout < 0))
00089 si.msec_timeout = alarmleft;
00090
00091 si.wants = oldwant;
00092 return one_dead || !sure_thing.isempty();
00093 }
00094
00095
00096 bool WvStreamList::post_select(SelectInfo &si)
00097 {
00098 bool one_dead = false;
00099 SelectRequest oldwant = si.wants;
00100
00101 Iter i(*this);
00102 for (i.rewind(); i.cur() && i.next(); )
00103 {
00104 WvStream &s(*i);
00105 if (s.isok())
00106 {
00107 if (s.post_select(si))
00108 sure_thing.append(&s, false, i.link->id);
00109 }
00110 else
00111 one_dead = true;
00112 }
00113
00114 si.wants = oldwant;
00115 return one_dead || !sure_thing.isempty();
00116 }
00117
00118
00119
00120 void WvStreamList::execute()
00121 {
00122 static int level = 0;
00123 const char *id;
00124 level++;
00125
00126 WvStream::execute();
00127
00128 TRACE("\n%*sList@%p: (%d sure) ", level, "", this, sure_thing.count());
00129
00130 WvStreamListBase::Iter i(sure_thing);
00131 for (i.rewind(); i.next(); )
00132 {
00133 #if STREAMTRACE
00134 WvStreamListBase::Iter x(*this);
00135 if (!x.find(&i()))
00136 TRACE("Yikes! %p in sure_thing, but not in main list!\n",
00137 i.cur());
00138 #endif
00139 WvStream &s(*i);
00140
00141 id = i.link->id;
00142 TRACE("[%p:%s]", &s, id);
00143
00144 i.xunlink();
00145
00146 if (s.isok())
00147 s.callback();
00148
00149
00150 i.rewind();
00151 }
00152
00153 sure_thing.zap();
00154
00155 level--;
00156 TRACE("[DONE %p]\n", this);
00157 }