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 }