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

wvistreamlist.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * WvIStreamList holds a list of IWvStream objects -- and its select() and 00006 * callback() functions know how to handle multiple simultaneous streams. 00007 */ 00008 #include "wvistreamlist.h" 00009 00010 #ifndef _WIN32 00011 #include "wvfork.h" 00012 #endif 00013 00014 // enable this to add some read/write trace messages (this can be VERY 00015 // verbose) 00016 #define STREAMTRACE 0 00017 #if STREAMTRACE 00018 # define TRACE(x, y...) fprintf(stderr, x, ## y) 00019 #else 00020 #ifndef _MSC_VER 00021 # define TRACE(x, y...) 00022 #else 00023 # define TRACE 00024 #endif 00025 #endif 00026 00027 WvIStreamList WvIStreamList::globallist; 00028 00029 WvIStreamList::WvIStreamList() 00030 { 00031 auto_prune = true; 00032 if (this == &globallist) 00033 { 00034 globalstream = this; 00035 #ifndef _WIN32 00036 add_wvfork_callback(WvIStreamList::onfork); 00037 #endif 00038 } 00039 } 00040 00041 00042 WvIStreamList::~WvIStreamList() 00043 { 00044 // nothing to do 00045 } 00046 00047 00048 bool WvIStreamList::isok() const 00049 { 00050 return true; // "error" condition on a list is undefined 00051 } 00052 00053 00054 bool WvIStreamList::pre_select(SelectInfo &si) 00055 { 00056 bool one_dead = false; 00057 SelectRequest oldwant; 00058 00059 // usually because of WvTask, we might get here without having finished 00060 // the _last_ set of sure_thing streams... 00061 if (running_callback) 00062 return true; 00063 00064 sure_thing.zap(); 00065 00066 time_t alarmleft = alarm_remaining(); 00067 if (alarmleft == 0) 00068 return true; // alarm has rung 00069 00070 oldwant = si.wants; 00071 00072 Iter i(*this); 00073 for (i.rewind(); i.next(); ) 00074 { 00075 IWvStream &s(*i); 00076 00077 if (!s.isok()) 00078 { 00079 one_dead = true; 00080 if (auto_prune) 00081 i.xunlink(); 00082 continue; 00083 } 00084 00085 //if (si.wants.readable && inbuf.used() && inbuf.used() > queue_min) 00086 // sure_thing.append(&s, false, i.link->id); 00087 00088 if (s.isok() && s.pre_select(si)) 00089 sure_thing.append(&s, false, i.link->id); 00090 } 00091 00092 if (alarmleft >= 0 && (alarmleft < si.msec_timeout || si.msec_timeout < 0)) 00093 si.msec_timeout = alarmleft; 00094 00095 si.wants = oldwant; 00096 return one_dead || !sure_thing.isempty(); 00097 } 00098 00099 00100 bool WvIStreamList::post_select(SelectInfo &si) 00101 { 00102 bool one_dead = false; 00103 SelectRequest oldwant = si.wants; 00104 00105 Iter i(*this); 00106 for (i.rewind(); i.cur() && i.next(); ) 00107 { 00108 IWvStream &s(*i); 00109 if (s.isok()) 00110 { 00111 if (s.post_select(si)) 00112 sure_thing.append(&s, false); 00113 } 00114 else 00115 one_dead = true; 00116 } 00117 00118 si.wants = oldwant; 00119 return one_dead || !sure_thing.isempty(); 00120 } 00121 00122 00123 // distribute the callback() request to all children that select 'true' 00124 void WvIStreamList::execute() 00125 { 00126 static int level = 0; 00127 const char *id; 00128 level++; 00129 00130 WvStream::execute(); 00131 00132 TRACE("\n%*sList@%p: (%d sure) ", level, "", this, sure_thing.count()); 00133 00134 WvIStreamListBase::Iter i(sure_thing); 00135 for (i.rewind(); i.next(); ) 00136 { 00137 #if STREAMTRACE 00138 WvIStreamListBase::Iter x(*this); 00139 if (!x.find(&i())) 00140 TRACE("Yikes! %p in sure_thing, but not in main list!\n", 00141 i.cur()); 00142 #endif 00143 IWvStream &s(*i); 00144 00145 id = i.link->id; 00146 TRACE("[%p:%s]", s, id); 00147 00148 i.xunlink(); 00149 00150 if (s.isok()) 00151 s.callback(); 00152 00153 // list might have changed! 00154 i.rewind(); 00155 } 00156 00157 sure_thing.zap(); 00158 00159 level--; 00160 TRACE("[DONE %p]\n", this); 00161 } 00162 00163 #ifndef _WIN32 00164 void WvIStreamList::onfork(pid_t p) 00165 { 00166 if (p == 0) 00167 { 00168 // this is a child process: don't inherit the global streamlist 00169 globallist.zap(false); 00170 } 00171 } 00172 #endif

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