From: Roy T. Fielding Date: Thu, 26 Aug 1999 12:54:16 +0000 (+0000) Subject: Replace all alarms and timeouts with a mutex on alloc. X-Git-Tag: PRE_APR_CHANGES~36 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=19bca355c1f428f75e4191cafcd1c2f698c878c2;p=apache Replace all alarms and timeouts with a mutex on alloc. Replace file descriptors with APRFile. Add ap_is_aborted macro. Submitted by: Bill Stoddard, Dean Gaudet git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83766 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/httpd.h b/include/httpd.h index 9a79bf7941..fe736a230a 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1121,6 +1121,8 @@ API_EXPORT(extern const char *) ap_psignature(const char *prefix, request_rec *r #endif #define strtoul strtoul_is_not_a_portable_function_use_strtol_instead +#define ap_is_aborted(abort) (abort->aborted ==1) + #ifdef __cplusplus } #endif diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 0265e87836..0226508270 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -2539,7 +2539,6 @@ static int default_handler(request_rec *r) } #ifdef USE_MMAP_FILES - ap_block_alarms(); if ((r->finfo.st_size >= MMAP_THRESHOLD) && (r->finfo.st_size < MMAP_LIMIT) && (!r->header_only || (d->content_md5 & 1))) { @@ -2557,7 +2556,6 @@ static int default_handler(request_rec *r) } if (mm == (caddr_t)-1) { - ap_unblock_alarms(); #endif #ifdef CHARSET_EBCDIC @@ -2616,7 +2614,6 @@ static int default_handler(request_rec *r) mmd->mm = mm; mmd->length = r->finfo.st_size; ap_register_cleanup(r->pool, (void *)mmd, mmap_cleanup, mmap_cleanup); - ap_unblock_alarms(); if (d->content_md5 & 1) { AP_MD5_CTX context; diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 135621aebc..37605ed0ed 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -1343,15 +1343,15 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r) * It is more expensive to check the User-Agent than it is to just add the * bytes, so we haven't used the BrowserMatch feature here. */ -static void terminate_header(BUFF *client) +static void terminate_header(request_rec *r) { long int bs; - ap_bgetopt(client, BO_BYTECT, &bs); + ap_bgetopt(r->connection->client, BO_BYTECT, &bs); if (bs >= 255 && bs <= 257) - ap_bputs("X-Pad: avoid browser bug\015\012", client); + ap_rputs("X-Pad: avoid browser bug\015\012", r); - ap_bputs("\015\012", client); /* Send the terminating empty line */ + ap_rputs("\015\012", r); /* Send the terminating empty line */ } /* Build the Allow field-value from the request handler method mask. @@ -1389,8 +1389,6 @@ API_EXPORT(int) ap_send_http_trace(request_rec *r) if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY))) return rv; - ap_hard_timeout("send TRACE", r); - r->content_type = "message/http"; ap_send_http_header(r); @@ -1402,7 +1400,6 @@ API_EXPORT(int) ap_send_http_trace(request_rec *r) ap_send_header_field, (void *) r, r->headers_in, NULL); ap_rputs("\015\012", r); - ap_kill_timeout(r); return OK; } @@ -1413,8 +1410,6 @@ int ap_send_http_options(request_rec *r) if (r->assbackwards) return DECLINED; - ap_hard_timeout("send OPTIONS", r); - ap_basic_http_header(r); ap_table_setn(r->headers_out, "Content-Length", "0"); @@ -1424,9 +1419,8 @@ int ap_send_http_options(request_rec *r) ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field, (void *) r, r->headers_out, NULL); - terminate_header(r->connection->client); + terminate_header(r); - ap_kill_timeout(r); ap_bsetopt(r->connection->client, BO_BYTECT, &zero); return OK; @@ -1563,8 +1557,6 @@ API_EXPORT(void) ap_send_http_header(request_rec *r) fixup_vary(r); } - ap_hard_timeout("send headers", r); - ap_basic_http_header(r); #ifdef CHARSET_EBCDIC @@ -1612,9 +1604,8 @@ API_EXPORT(void) ap_send_http_header(request_rec *r) ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field, (void *) r, r->headers_out, NULL); - terminate_header(r->connection->client); + terminate_header(r); - ap_kill_timeout(r); ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; /* Whatever follows is real body stuff... */ @@ -1642,11 +1633,9 @@ API_EXPORT(void) ap_finalize_request_protocol(request_rec *r) r->chunked = 0; ap_bsetflag(r->connection->client, B_CHUNK, 0); - ap_soft_timeout("send ending chunk", r); ap_rputs("0\015\012", r); /* If we had footer "headers", we'd send them now */ ap_rputs("\015\012", r); - ap_kill_timeout(r); } } @@ -1975,10 +1964,9 @@ API_EXPORT(int) ap_discard_request_body(request_rec *r) r->connection->keepalive = -1; return OK; } - ap_hard_timeout("reading request body", r); + while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0) continue; - ap_kill_timeout(r); if (rv < 0) return HTTP_BAD_REQUEST; @@ -1989,47 +1977,45 @@ API_EXPORT(int) ap_discard_request_body(request_rec *r) /* * Send the body of a response to the client. */ -API_EXPORT(long) ap_send_fd(FILE *f, request_rec *r) +API_EXPORT(long) ap_send_fd(APRFile fd, request_rec *r) { - return ap_send_fd_length(f, r, -1); + return ap_send_fd_length(fd, r, -1); } -API_EXPORT(long) ap_send_fd_length(FILE *f, request_rec *r, long length) +API_EXPORT(long) ap_send_fd_length(APRFile fd, request_rec *r, long length) { char buf[IOBUFSIZE]; long total_bytes_sent = 0; - register int n, w, o, len; + register int n, w, o; if (length == 0) return 0; - ap_soft_timeout("send body", r); - - while (!r->connection->aborted) { + while (!ap_is_aborted(r->connection)) { if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length) - len = length - total_bytes_sent; + o = length - total_bytes_sent; else - len = IOBUFSIZE; + o = IOBUFSIZE; - while ((n = fread(buf, sizeof(char), len, f)) < 1 - && ferror(f) && errno == EINTR && !r->connection->aborted) + while ((n = read(fd, buf, o)) < 0 && + (errno == EINTR || errno == EAGAIN) && + !ap_is_aborted(r->connection)) continue; - + if (n < 1) { break; } o = 0; - while (n && !r->connection->aborted) { + while (n && !ap_is_aborted(r->connection)) { w = ap_bwrite(r->connection->client, &buf[o], n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful write */ total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (!r->connection->aborted) { + if (!ap_is_aborted(r->connection)) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); @@ -2040,11 +2026,13 @@ API_EXPORT(long) ap_send_fd_length(FILE *f, request_rec *r, long length) } } - ap_kill_timeout(r); SET_BYTES_SENT(r); return total_bytes_sent; } + +/* TODO: re-implement ap_send_fb */ +#if 0 /* * Send the body of a response to the client. */ @@ -2058,17 +2046,15 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) char buf[IOBUFSIZE]; long total_bytes_sent = 0; register int n, w, o, len, fd; - fd_set fds; + struct pollfd fds; if (length == 0) return 0; /* Make fb unbuffered and non-blocking */ ap_bsetflag(fb, B_RD, 0); -#ifndef TPF - ap_bnonblock(fb, B_RD); -#endif fd = ap_bfileno(fb, B_RD); + ap_bnonblock(fd); #ifdef CHECK_FD_SETSIZE if (fd >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, @@ -2079,10 +2065,10 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) } #endif - ap_soft_timeout("send body", r); + fds.fd = fd; + fds.events = POLLIN; - FD_ZERO(&fds); - while (!r->connection->aborted) { + while (!ap_is_aborted(r->connection)) { #ifdef NDELAY_PIPE_RETURNS_ZERO /* Contributed by dwd@bell-labs.com for UTS 2.1.2, where the fcntl */ /* O_NDELAY flag causes read to return 0 when there's nothing */ @@ -2106,9 +2092,9 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) if (n >= 0) break; #endif - if (r->connection->aborted) + if (ap_is_aborted(r->connection)) break; - if (n < 0 && errno != EAGAIN) + if (n < 0 && errno != EAGAIN /* ZZZ rethink for threaded impl */) break; /* we need to block, so flush the output first */ @@ -2119,32 +2105,31 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) r->connection->aborted = 1; break; } - FD_SET(fd, &fds); /* - * we don't care what select says, we might as well loop back + * we don't care what poll says, we might as well loop back * around and try another read */ - ap_select(fd + 1, &fds, NULL, NULL, NULL); + /* use AP funcs */ + poll(&fds, 1, -1); #ifdef NDELAY_PIPE_RETURNS_ZERO afterselect = 1; #endif - } while (!r->connection->aborted); + } while (!ap_is_aborted(r->connection)); - if (n < 1 || r->connection->aborted) { + if (n < 1 || ap_is_aborted(r->connection)) { break; } o = 0; - while (n && !r->connection->aborted) { + while (n && !ap_is_aborted(r->connection)) { w = ap_bwrite(r->connection->client, &buf[o], n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful write */ total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (!r->connection->aborted) { + if (!ap_is_aborted(r->connection)) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); @@ -2155,10 +2140,10 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) } } - ap_kill_timeout(r); SET_BYTES_SENT(r); return total_bytes_sent; } +#endif @@ -2185,7 +2170,6 @@ API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset, if (length == 0) return 0; - ap_soft_timeout("send mmap", r); length += offset; while (!r->connection->aborted && offset < length) { @@ -2199,24 +2183,26 @@ API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset, while (n && !r->connection->aborted) { w = ap_bwrite(r->connection->client, (char *) mm + offset, n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful write */ total_bytes_sent += w; n -= w; offset += w; } else if (w < 0) { - if (!r->connection->aborted) { + if (r->connection->aborted) + break; + else if (errno == EAGAIN) + continue; + else { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send mmap completed"); + "client stopped connection before send mmap completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; + break; } - break; } } } - ap_kill_timeout(r); SET_BYTES_SENT(r); return total_bytes_sent; } @@ -2265,7 +2251,7 @@ API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) int n; if (r->connection->aborted) - return -1; + return EOF; n = ap_bwrite(r->connection->client, buf, nbyte); if (n < 0) { @@ -2275,7 +2261,7 @@ API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; } - return -1; + return EOF; } SET_BYTES_SENT(r); return n; @@ -2406,8 +2392,6 @@ void ap_send_error_response(request_rec *r, int recursive_error) if (!ap_is_empty_table(r->err_headers_out)) r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out, r->headers_out); - ap_hard_timeout("send 304", r); - ap_basic_http_header(r); ap_set_keepalive(r); @@ -2425,9 +2409,8 @@ void ap_send_error_response(request_rec *r, int recursive_error) "Proxy-Authenticate", NULL); - terminate_header(r->connection->client); + terminate_header(r); - ap_kill_timeout(r); return; } @@ -2476,8 +2459,6 @@ void ap_send_error_response(request_rec *r, int recursive_error) } } - ap_hard_timeout("send error body", r); - if ((custom_response = ap_response_code_string(r, idx))) { /* * We have a custom response output. This should only be @@ -2493,7 +2474,6 @@ void ap_send_error_response(request_rec *r, int recursive_error) */ if (custom_response[0] == '\"') { ap_rputs(custom_response + 1, r); - ap_kill_timeout(r); ap_finalize_request_protocol(r); ap_rflush(r); return; @@ -2757,7 +2737,6 @@ void ap_send_error_response(request_rec *r, int recursive_error) ap_rputs(ap_psignature("
\n", r), r); ap_rputs("\n", r); } - ap_kill_timeout(r); ap_finalize_request_protocol(r); ap_rflush(r); } diff --git a/server/log.c b/server/log.c index 7a1e0ea5d0..c1450a9cf5 100644 --- a/server/log.c +++ b/server/log.c @@ -65,7 +65,6 @@ #define CORE_PRIVATE #include "httpd.h" -#include "http_conf_globals.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" @@ -578,7 +577,6 @@ static int piped_log_spawn(piped_log *pl) { int pid; - ap_block_alarms(); pid = fork(); if (pid == 0) { /* XXX: this needs porting to OS2 and WIN32 */ @@ -602,10 +600,8 @@ static int piped_log_spawn(piped_log *pl) if (pid == -1) { fprintf(stderr, "piped_log_spawn: unable to fork(): %s\n", strerror (errno)); - ap_unblock_alarms(); return -1; } - ap_unblock_alarms(); pl->pid = pid; ap_register_other_child(pid, piped_log_maintenance, pl, pl->fds[1]); return 0; @@ -683,10 +679,8 @@ API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program) pl->p = p; pl->program = ap_pstrdup(p, program); pl->pid = -1; - ap_block_alarms (); if (pipe(pl->fds) == -1) { int save_errno = errno; - ap_unblock_alarms(); errno = save_errno; return NULL; } @@ -696,20 +690,16 @@ API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program) ap_kill_cleanup(p, pl, piped_log_cleanup); close(pl->fds[0]); close(pl->fds[1]); - ap_unblock_alarms(); errno = save_errno; return NULL; } - ap_unblock_alarms(); return pl; } API_EXPORT(void) ap_close_piped_log(piped_log *pl) { - ap_block_alarms(); piped_log_cleanup(pl); ap_kill_cleanup(pl->p, pl, piped_log_cleanup); - ap_unblock_alarms(); } #else diff --git a/server/rfc1413.c b/server/rfc1413.c index 65bc6ef4d0..0ceb7e1bc1 100644 --- a/server/rfc1413.c +++ b/server/rfc1413.c @@ -209,12 +209,6 @@ static int get_rfc1413(int sock, const struct sockaddr_in *our_sin, return 0; } -/* ident_timeout - handle timeouts */ -static void ident_timeout(int sig) -{ - ap_longjmp(timebuf, sig); -} - /* rfc1413 - return remote user name, given socket structures */ char *ap_rfc1413(conn_rec *conn, server_rec *srv) { @@ -235,12 +229,10 @@ char *ap_rfc1413(conn_rec *conn, server_rec *srv) * Set up a timer so we won't get stuck while waiting for the server. */ if (ap_setjmp(timebuf) == 0) { - ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout); if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0) result = user; } - ap_set_callback_and_alarm(NULL, 0); ap_pclosesocket(conn->pool, sock); conn->remote_logname = result; diff --git a/server/util_md5.c b/server/util_md5.c index 368ddf63b2..f1a9564d99 100644 --- a/server/util_md5.c +++ b/server/util_md5.c @@ -189,7 +189,7 @@ API_EXPORT(char *) ap_md5contextTo64(pool *a, AP_MD5_CTX * context) #ifdef CHARSET_EBCDIC -API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert) +API_EXPORT(char *) ap_md5digest(pool *p, APRFile infile, int convert) { AP_MD5_CTX context; unsigned char buf[1000]; @@ -197,33 +197,37 @@ API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert) int nbytes; ap_MD5Init(&context); - while ((nbytes = fread(buf, 1, sizeof(buf), infile))) { - length += nbytes; + /* ZZZ use AP func instead of fread. */ + while ((nbytes = read(infile, buf, sizeof(buf)))) { + length += nbytes; if (!convert) { ascii2ebcdic(buf, buf, nbytes); } - ap_MD5Update(&context, buf, nbytes); + ap_MD5Update(&context, buf, nbytes); } - rewind(infile); + /* ZZZ use AP seek func instead of REWIND. */ + lseek(infile, 0L, SEEK_SET); return ap_md5contextTo64(p, &context); } #else -API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile) +API_EXPORT(char *) ap_md5digest(pool *p, APRFile infile) { AP_MD5_CTX context; unsigned char buf[1000]; long length = 0; - unsigned int nbytes; + int nbytes; ap_MD5Init(&context); - while ((nbytes = fread(buf, 1, sizeof(buf), infile))) { + /* ZZZ use AP func instead of fread. */ + while ((nbytes = read(infile, buf, sizeof(buf)))) { length += nbytes; ap_MD5Update(&context, buf, nbytes); } - rewind(infile); + /* ZZZ use AP seek func instead of REWIND. */ + lseek(infile, 0L, SEEK_SET); return ap_md5contextTo64(p, &context); } -#endif /* CHARSET_EBCDIC */ +#endif diff --git a/server/util_script.c b/server/util_script.c index 2ed6794a69..012896d7c2 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -444,8 +444,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, } w = buffer ? buffer : x; - ap_hard_timeout("read script header", r); - /* temporary place to hold headers to merge in later */ merge = ap_make_table(r->pool, 10); @@ -461,7 +459,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, while (1) { if ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data) == 0) { - ap_kill_timeout(r); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Premature end of script headers: %s", r->filename); return HTTP_INTERNAL_SERVER_ERROR; @@ -494,7 +491,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, if (w[0] == '\0') { int cond_status = OK; - ap_kill_timeout(r); if ((cgi_status == HTTP_OK) && (r->method_number == M_GET)) { cond_status = ap_meets_conditions(r); } @@ -546,7 +542,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, } } - ap_kill_timeout(r); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "%s: %s", malformed, r->filename); return HTTP_INTERNAL_SERVER_ERROR;