You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by David McCreedy <Mc...@us.ibm.com> on 2002/07/29 22:52:36 UTC

Apache 1.3 timeout processing question

I'm struggling with some Apache 1.3 logic and would like some advice in 
order to make changes specific to the TPF operating system.

Various routines call ap_set_callback_and_alarm() to set a timeout 
value, such as ap_keepalive_timeout() and ap_hard_timeout() in http_main.c.
The read in buff.c's ap_read(), which is called by buff_read(), 
presumably gets interrupted by the alarm if no data is received in the 
allotted time.
On TPF, neither select() nor socket reads are interrupted by signals.
So with the initial Apache port to TPF, code was put into buff_read() to 
do a select on the socket with a hardcoded time of one second.
This works OK if the client is quick but otherwise it causes "500 
unexpected EOF before status line seen" or "no data returned" errors on 
the client.
It also bypasses the configurable httpd.conf timeout directives, in 
effect using "Timeout 1" and "KeepAliveTimeout 1".

Win32 has special handling to set and retrieve timeout values.
(The code is in ap_set_callback_and_alarm and ap_check_alarm respectively).
I was thinking along these lines but would like to use more of the main 
line ap_set_callback_and_alarm processing.
I could add this routine to http_main.c to determine the current timeout 
value:

      #ifdef TPF
      API_EXPORT(int) ap_check_alarm(void)
      {
          int i;

          /* determine time left */
          /* the 2 seconds is just an arbitrary amount of time to keep
             the alarm from expiring before it is reset */
          i = ap_set_callback_and_alarm(alarm_fn, 2);

          ap_set_callback_and_alarm(alarm_fn, i); /* restore time left */
          return i;                               /* return time left */
      }
      #endif

And then use it in buff.c to control the select prior to the socket read 
in the TPF-specific code in buff_read:

	...
	/* tv.tv_sec = 1; */          /* <=== old line */
	tv.tv_sec = ap_check_alarm(); /* <=== new line */
	tv.tv_usec = 0;
	rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv);
	if (rv > 0)
	    rv = ap_read(fb, buf, nbyte);
	}
	...

I'm not comfortable with my understanding of Apache timeout processing 
which is why I'm requesting feedback.
Please let me know the pitfalls or merits of taking the above approach.

Thank you,

-David McCreedy