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