I wrote a http server using pth, but it has a problem when the request rate is high (say 200 request per second), and the client closes the socket. (or bad connection). For debugging purpose, I made it w/o spawning thread. i.e. the server handles the request in main thread. Only other thread is the pth scheduler. (the original version of the server spawns a thread per request or use pre-spawned thread for handling the request). Followings are the problem and possible solutions. Any fix?
1. the server is writing to a socket, say fd. fd is default (or equivalently BLOCKING mode). 2. in the middle of writing to fd, the client closed the connection. 3. When write to socket, ---------------------+----------- fd \ func : write | pth_write(or pth_send) ...........----------+----------- BLOCK : works | BAD(i.e. stops) NONBLOCK : works | works ---------------------+----------- in pthlib, pth_write calls pth_write_ev calls for(;;) { // polling mode ... ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE|PTH_MODE_STATIC, &ev_key, fd); pth_wait(ev); ... } pth_wait first initialze ev_ring, then calls pth_yield(NULL); pth_yield calls pth_mctx_switch(&pth_current->mctx, &pth_sched->mctx); ... // here pth_p.h says "#define cpp 0", so pth_mctx_switch in // "if cpp" block is not used? if so, where it's defined? // Anyhow, gdb bt showed (gdb) bt #0 0x4010690e in __select () from /lib/i686/libc.so.6 #1 0x08072c3c in ?? () #2 0x08052475 in __pth_scheduler () #3 0x080508d3 in pth_spawn_trampoline () #4 0x08051545 in pth_mctx_set_bootstrap () #5 <signal handler called> #6 0x400538a5 in __sigsuspend (set=0xbfffc210) at ../sysdeps/unix/sysv/linux/sigsuspend.c:45 #7 0x400d6233 in __tzfile_read (file=0x0, extra=0, extrap=0x0) at tzfile.c:309 (gdb) --------------- In short, pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE, .. will never happen. Then pthlib stops at select(). Forever. --------------- Possible solutions: 1. Use pth_write_ev with timeout. This causes another problem. e.g. when sending a big file over slow and unstable connection, if timeout occurs before finishing transmission but after sending one or more of chunk, then client(e.g. lynx) makes another request; the server replies to this new request while the client appends the new portion to the old file. Then one might ask why set the timeout very long? If it's long, and another requests came, the server spawn a new thread (for each request) to handle them. If many such clients closes the connection before pth_write completes, then the server keep spawning the request handler causing pth scheduler to slowdown. (loss of QoS). 2. Check the fd before pth_event(....WRITEABLE...). fstat won't help. fcntl won't help. any other file stat functions? 3. make sure to make the fd NONBLOCKING before pth_write or use regular write. -- this does not solve the original problem. -- Takashi Ishihara http://wwwcsif.cs.ucdavis.edu/~ishihara ;; The first precept was never to accept a thing as true until I knew it ;; as such without a single doubt. (Rene Descartes, 1637) ______________________________________________________________________ GNU Portable Threads (Pth) http://www.gnu.org/software/pth/ User Support Mailing List [EMAIL PROTECTED] Automated List Manager (Majordomo) [EMAIL PROTECTED]