00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #ifndef ns_empweb_h
00056 #define ns_empweb_h
00057
00058 #include "ranvar.h"
00059 #include "random.h"
00060 #include "timer-handler.h"
00061
00062 #include "lib/bsd-list.h"
00063 #include "node.h"
00064 #include "tcp.h"
00065 #include "tcp-sink.h"
00066 #include "persconn.h"
00067
00068 const int WEBTRAF_DEFAULT_OBJ_PER_PAGE = 1;
00069
00070 class EmpWebTrafPool;
00071
00072 class EmpWebTrafSession : public TimerHandler {
00073 public:
00074 EmpWebTrafSession(EmpWebTrafPool *mgr, Node *src, int np, int id, int connNum, int cl, int ftcp_) :
00075 rvInterPage_(NULL), rvPageSize_(NULL),
00076 rvInterObj_(NULL), rvObjSize_(NULL),
00077 rvReqSize_(NULL), rvPersistSel_(NULL), rvServerSel_(NULL),
00078 rvServerWin_(NULL), rvClientWin_(NULL),
00079 rvMtu_(NULL),
00080 mgr_(mgr), src_(src), nPage_(np), curPage_(0), donePage_(0),
00081 id_(id), clientIdx_(cl), fulltcp_(0), interPageOption_(1) {
00082 fulltcp_ = ftcp_;
00083 }
00084 virtual ~EmpWebTrafSession();
00085
00086
00087 inline EmpiricalRandomVariable*& interPage() { return rvInterPage_; }
00088 inline EmpiricalRandomVariable*& pageSize() { return rvPageSize_; }
00089 inline EmpiricalRandomVariable*& interObj() { return rvInterObj_; }
00090 inline EmpiricalRandomVariable*& objSize() { return rvObjSize_; }
00091
00092 inline EmpiricalRandomVariable*& reqSize() { return rvReqSize_; }
00093 inline EmpiricalRandomVariable*& persistSel() { return rvPersistSel_; }
00094 inline EmpiricalRandomVariable*& serverSel() { return rvServerSel_; }
00095
00096 inline EmpiricalRandomVariable*& serverWin() { return rvServerWin_; }
00097 inline EmpiricalRandomVariable*& clientWin() { return rvClientWin_; }
00098
00099 inline EmpiricalRandomVariable*& mtu() { return rvMtu_; }
00100
00101 void donePage(void* ClntData);
00102 void launchReq(void* ClntData, int obj, int size, int reqSize, int sid, int p);
00103 inline int id() const { return id_; }
00104 inline EmpWebTrafPool* mgr() { return mgr_; }
00105
00106 inline void set_interPageOption(int option) { interPageOption_ = option; }
00107
00108 static int LASTPAGE_;
00109
00110 private:
00111 virtual void expire(Event *e = 0);
00112 virtual void handle(Event *e);
00113
00114 EmpiricalRandomVariable *rvInterPage_, *rvPageSize_, *rvInterObj_, *rvObjSize_;
00115 EmpiricalRandomVariable *rvReqSize_, *rvPersistSel_, *rvServerSel_;
00116 EmpiricalRandomVariable *rvServerWin_, *rvClientWin_;
00117 EmpiricalRandomVariable *rvMtu_;
00118 EmpWebTrafPool* mgr_;
00119 Node* src_;
00120 int nPage_, curPage_, donePage_;
00121 int id_;
00122
00123
00124 int clientIdx_;
00125
00126 int fulltcp_;
00127
00128 int interPageOption_;
00129
00130 TcpAgent* ctcp_;
00131 TcpAgent* stcp_;
00132 TcpSink* csnk_;
00133 TcpSink* ssnk_;
00134
00135 };
00136
00137 class EmpWebTrafPool : public PagePool {
00138 public:
00139 EmpWebTrafPool();
00140 virtual ~EmpWebTrafPool();
00141
00142 inline void startSession() {
00143 concurrentSess_++;
00144 if (isdebug())
00145 printf("concurrent number of sessions = %d \n", concurrentSess_ );
00146 }
00147 inline void doneSession(int idx) {
00148
00149 assert((idx>=0) && (idx<nSession_) && (session_[idx]!=NULL));
00150 if (concurrentSess_ > 0) concurrentSess_--;
00151 if (isdebug()) {
00152 printf("deleted session %d \n", idx );
00153 printf("concurrent number of sessions = %d \n", concurrentSess_ );
00154 }
00155 delete session_[idx];
00156 session_[idx] = NULL;
00157 }
00158 void recycleTcp(Agent* a);
00159 void recycleSink(Agent* a);
00160 TcpAgent* picktcp(int size, int mtu);
00161 TcpSink* picksink();
00162 inline int nTcp() { return nTcp_; }
00163 inline int nSink() { return nSink_; }
00164 inline int isdebug() { return debug_; }
00165
00166 virtual void delay_bind_init_all();
00167 virtual int delay_bind_dispatch(const char*, const char*, TclObject*);
00168
00169 int nSrcL_;
00170 int nClientL_;
00171
00172 int concurrentSess_;
00173
00174 int color_;
00175
00176 static int LASTFLOW_;
00177 int nSrc_;
00178 Node** server_;
00179
00180 protected:
00181 virtual int command(int argc, const char*const* argv);
00182
00183
00184
00185 int nSession_;
00186 EmpWebTrafSession** session_;
00187
00188 int nClient_;
00189 Node** client_;
00190
00191
00192 struct AgentListElem {
00193 AgentListElem(Agent* a) : agt_(a) {
00194 link.le_next = NULL;
00195 link.le_prev = NULL;
00196 }
00197 Agent* agt_;
00198 LIST_ENTRY(AgentListElem) link;
00199 };
00200 LIST_HEAD(AgentList, AgentListElem);
00201 inline void insertAgent(AgentList* l, Agent *a) {
00202 AgentListElem *e = new AgentListElem(a);
00203 LIST_INSERT_HEAD(l, e, link);
00204 }
00205 inline Agent* detachHead(AgentList* l) {
00206 AgentListElem *e = l->lh_first;
00207 if (e == NULL)
00208 return NULL;
00209 Agent *a = e->agt_;
00210 LIST_REMOVE(e, link);
00211 delete e;
00212 return a;
00213 }
00214 int nTcp_, nSink_;
00215 AgentList tcpPool_;
00216 AgentList sinkPool_;
00217
00218
00219 inline int lookup_rv(EmpiricalRandomVariable*& rv, const char* name) {
00220 if (rv != NULL)
00221 Tcl::instance().evalf("delete %s", rv->name());
00222 rv = (EmpiricalRandomVariable*)lookup_obj(name);
00223 return rv ? (TCL_OK) : (TCL_ERROR);
00224 }
00225
00226 int debug_;
00227
00228 int fulltcp_;
00229 };
00230
00231
00232 #endif // ns_empweb_h