Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvstreamlist.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * WvStreamList holds a list of WvStream objects -- and its select() and 00006 * callback() functions know how to handle multiple simultaneous streams. 00007 */ 00008 #include "wvstreamlist.h" 00009 00010 // enable this to add some read/write trace messages (this can be VERY 00011 // verbose) 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 // nothing to do 00032 } 00033 00034 00035 bool WvStreamList::isok() const 00036 { 00037 return WvError::isok(); // only !isok() if we explicitly set an error 00038 } 00039 00040 00041 bool WvStreamList::pre_select(SelectInfo &si) 00042 { 00043 bool one_dead = false; 00044 SelectRequest oldwant; 00045 00046 // usually because of WvTask, we might get here without having finished 00047 // the _last_ set of sure_thing streams... 00048 // 00049 // FIXME: this isn't really a good fix. It doesn't deal properly with 00050 // the case where a continue_selectable callback is called by someone 00051 // *other* than WvStreamList... eg. WvStreamClone calling its cloned 00052 // callback(). 00053 // 00054 // FIXME: this hack makes it so calling select() on this object from 00055 // its own callback always returns true. This is why we can't apply 00056 // this hack inside WvStreamClone. 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; // alarm has rung 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 //if (si.wants.readable && inbuf.used() && inbuf.used() > queue_min) 00082 // sure_thing.append(&s, false, i.link->id); 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 // distribute the callback() request to all children that select 'true' 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 // list might have changed! 00150 i.rewind(); 00151 } 00152 00153 sure_thing.zap(); 00154 00155 level--; 00156 TRACE("[DONE %p]\n", this); 00157 }

Generated on Tue Oct 5 01:09:21 2004 for WvStreams by doxygen 1.3.7