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]

Reply via email to