00001 /* 00002 openisis - an open implementation of the CDS/ISIS database 00003 Version 0.8.x (patchlevel see file Version) 00004 Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with this library; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 see README for more information 00021 EOH */ 00022 #ifndef LSV_H 00023 00024 /* 00025 $Id: lsv.h,v 1.11 2003/06/03 17:09:20 kripke Exp $ 00026 OpenIsis server 00027 */ 00028 00029 #ifdef _REENTRANT /* it's really the wrong flag, but *sigh* */ 00030 #define LSVTHR 00031 #endif 00032 00033 #ifdef LSVTHR 00034 #include <pthread.h> /* else the work is done by the receiver */ 00035 #endif 00036 00037 00038 #include "loi.h" 00039 #include "lio.h" 00040 #include "lses.h" 00041 00042 00099 /* common header tags -- actually negative tags are used */ 00100 enum { 00101 /* nonstandard */ 00102 LSV_TEXT, /* +- 0: a small, inlined untyped or text/plain body */ 00103 LSV_RID, /* row id, a.k.a MFN */ 00104 LSV_SID, /* session id */ 00105 LSV_PEER, /* network peer ("remote host") */ 00106 LSV_TIME, /* GTF + millis */ 00107 LSV_ATTACH, /* wrapped-up attachment, TBD */ 00108 /* MIME basics */ 00109 LSV_CTYPE, 00110 /* HTTP: CGI/servlet */ 00111 LSV_URI, 00112 LSV_QUERY 00113 }; 00114 00115 enum { 00116 #ifdef LSVTHR 00117 LSV_NUMWRK = 8, 00118 #else 00119 LSV_NUMWRK = 1, 00120 #endif 00121 LSV_BUFSIZ = 0x04000, /* 16384 a.k.a. 16K */ 00122 LSV_BUFMSK = 0x03fff /* mask buf lengths */ 00123 }; 00124 00125 typedef struct Que { 00126 struct Con *head; 00127 struct Con *tail; 00128 int len; 00129 } Que; 00130 00131 /* queue with pool of workers waiting */ 00132 typedef struct Pool { 00133 Que que; 00134 #ifdef LSVTHR 00135 struct Wrk *wait; /* stack */ 00136 #endif 00137 } Pool; 00138 00139 typedef struct Wrk { 00140 #ifdef LSVTHR 00141 pthread_t thr; 00142 #endif 00143 unsigned id; 00144 struct Srv *srv; 00145 struct Wrk *nxt; 00146 Session ses; 00147 #ifdef LSVTHR 00148 pthread_cond_t todo; /* work condition waited for by workers */ 00149 #endif 00150 /* stats */ 00151 struct Con *cur; /* current job */ 00152 int jobs; 00153 int waits; 00154 } Wrk; 00155 00156 typedef struct Srv { 00157 /* 00158 the protocol stream method 00159 - with LIO_SPUSH, input is pushed to request (len 0 indicates EOF) 00160 return 0=more, >0=done, <0=error 00161 - on LIO_SFLUSH, prt must convert output buffer to flt 00162 - on LIO_SCLOSE, prt must flush and close answer 00163 */ 00164 int (*prt) ( Ios*, int op ); 00165 /* 00166 the application 00167 - with task APPARG (called by prt for each field): 00168 check (and typically modify) last field extracted by prt 00169 return 0=more, >0=done, <0=error 00170 - with task APPGOT (after request is complete): 00171 check request, add -LSV_SID field, if needed 00172 (e.g. to extract from an URL or cookie) 00173 - with task APPRUN (0): 00174 process request 00175 */ 00176 int (*app) ( struct Con*, int task ); 00177 Fdt *fdt; /* field def */ 00178 int flg; /* flags */ 00179 unsigned sto; /* config: session timeout (seconds) */ 00180 unsigned nwr; /* config: #workers (<= LSV_NUMWRK) */ 00181 Session ses; /* usually the default session */ 00182 Tm tim; /* tim of last turn */ 00183 char gtm[20]; /* generalized time (actually 18 digits) */ 00184 Wrk wrk[LSV_NUMWRK]; 00185 /* 00186 single receiver model 00187 */ 00188 int lsn; /* listening socket */ 00189 Que recv; /* enq by worker, deq by receiver */ 00190 Pool main; /* enq by dispatcher, deq by workers */ 00191 #ifdef LSVTHR 00192 Pool pool; /* enq by dispatcher, deq by workers */ 00193 pthread_t rcv; /* the receiver thread */ 00194 pthread_mutex_t mut; /* single mutex held by recv/disp while not in select */ 00195 int pip[2]; /* pipe for pending events */ 00196 #endif 00197 /* stats */ 00198 int plen; /* length of pool */ 00199 int jobs; /* total #jobs */ 00200 int conn; /* total #conn */ 00201 int turn; /* total #turn */ 00202 float wlen; /* cumulated length of work queue (on each turn) */ 00203 float busy; /* cumulated # of active workers (on each turn) */ 00204 } Srv; 00205 00206 enum { /* server flags */ 00207 LSV_CONSES = 0x01, /* session bound to connection */ 00208 LSV_WRKSES = 0x02, /* session bound to worker */ 00209 LSV_SHUTDN = 0x100 /* server is shutting down */ 00210 }; 00211 enum { 00212 /* called in worker thread: */ 00213 LSV_APPRUN, /* app called to process request */ 00214 LSV_APPINI, /* app called to initialise non-main thread (no con) */ 00215 LSV_APPFIN, /* app called to finalize non-main thread (no con) */ 00216 /* called in receiver thread: */ 00217 LSV_APPARG, /* app called to check parameter */ 00218 LSV_APPGOT, /* app called after all input */ 00219 LSV_APPSES /* app called on new session */ 00220 }; 00221 enum { /* connection pending state */ 00222 LSV_PDGNON, /* new connection pending */ 00223 LSV_PDGNEW, /* new connection pending */ 00224 LSV_PDGRED, /* ready to read pending */ 00225 LSV_PDGEOF /* EOF pending */ 00226 /* when adding, keep array of names in sync */ 00227 }; 00228 enum { /* connection processing stage */ 00229 LSV_STGNEW, /* connection needs to be setup */ 00230 LSV_STGCON, /* connected, no request on the way */ 00231 LSV_STGINP, /* reading input */ 00232 LSV_STGSES, /* waiting for session */ 00233 LSV_STGWRK, /* queued for work */ 00234 /* set by worker: */ 00235 LSV_STGRUN, /* dequeued */ 00236 LSV_STGCOM, /* commited (output has started) */ 00237 LSV_STGDON, /* done processing, flushing output */ 00238 LSV_STGRET /* returning (queued to recv) */ 00239 /* when adding, keep array of names in sync */ 00240 }; 00241 00242 typedef struct Con { 00243 Ios ios; /* raw output */ 00244 Buf flt; /* protocol filtered output */ 00245 const Srv *srv; 00246 struct Con *nxt; 00247 unsigned char stg; /* processing stage (guarded by mutex) */ 00248 unsigned char pdg; /* pending flags set by receiver only */ 00249 unsigned char grp; /* thread group (0=main) set by receiver app calls */ 00250 unsigned char bin; /* client requested binary mode */ 00251 int prt; /* for free use by prt, 0 init */ 00252 int app; /* for free use by app, 0 init */ 00253 int host; 00254 char nam[64]; /* 123.123.123.123:123456 for IPv4 */ 00255 Session ses; 00256 Rec *req; /* request -- owned by srv->ses */ 00257 Tm tim; /* time when the request was scheduled */ 00258 /* Rec *res; response -- owned by ses */ 00259 int con; /* connection counter */ 00260 } Con; 00261 00262 extern Wrk *svCur (); 00263 extern int svRun ( Srv *srv, const char *addr ); 00264 /* the plain protocol */ 00265 extern int svPlain ( Ios *s, int op ); 00266 extern int svEcho ( Con *c, int task ); 00267 00268 #define LSV_H 00269 #endif /* LSV_H */