# HG changeset patch # User Igor Sysoev # Date 1052240596 0 # Node ID fab4cb00fe5b4d65dc8c33f50f49620c040d70c1 # Parent a7e45c45a95c12ae7be011fb906ae75af6d87996 nginx-0.0.1-2003-05-06-21:03:16 import diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -441,21 +441,26 @@ char *ngx_conf_set_size_slot(ngx_conf_t len = value[1].len; last = value[1].data[len - 1]; - if (last == 'K' || last == 'k') { + switch (last) { + case 'K': + case 'k': len--; scale = 1024; + break; - } else if (last == 'M' || last == 'm') { + case 'M': + case 'm': len--; scale = 1024 * 1024; + break; - } else { + default: scale = 1; } size = ngx_atoi(value[1].data, len); if (size == NGX_ERROR) { - return "value must be greater or equal to zero"; + return "invalid value"; } size *= scale; @@ -466,71 +471,200 @@ char *ngx_conf_set_size_slot(ngx_conf_t } -char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { - int size, len, scale; - char last; + int size, total, len, scale, i; + u_int max; + char last, *start; ngx_str_t *value; value = (ngx_str_t *) cf->args->elts; + start = value[1].data; + len = 0; + total = 0; - len = value[1].len; - last = value[1].data[len - 1]; + for (i = 0; /* void */ ; i++) { - if (last == 'm') { - len--; - scale = 1000 * 60; + if (i < value[1].len) { + if (value[1].data[i] != ' ') { + len++; + continue; + } - } else if (last == 'h') { - len--; - scale = 1000 * 60 * 60; + if (value[1].data[i] == ' ' && len == 0) { + start = &value[1].data[i + 1]; + continue; + } + } - } else if (last == 'd') { - len--; - scale = 1000 * 60 * 60 * 24; + if (len == 0) { + break; + } - } else if (last == 'w') { - len--; - scale = 1000 * 60 * 60 * 24 * 7; + last = value[1].data[i - 1]; -#if 0 /* overflow */ + switch (last) { + case 'm': + len--; + max = 35791; + scale = 1000 * 60; + break; - } else if (last == 'M') { - len--; - scale = 1000 * 60 * 60 * 24 * 30; - - } else if (last == 'y') { - len--; - scale = 1000 * 60 * 60 * 24 * 365; + case 'h': + len--; + max = 596; + scale = 1000 * 60 * 60; + break; -#endif + case 'd': + len--; + max = 24; + scale = 1000 * 60 * 60 * 24; + break; - } else if (last == 's') { - len--; - if (value[1].data[len - 1] == 'm') { + case 's': len--; - scale = 1; + if (value[1].data[i - 2] == 'm') { + len--; + max = 2147483647; + scale = 1; + break; + } + /* fall thru */ - } else { + default: + max = 2147483; scale = 1000; } - } else { - scale = 1000; + size = ngx_atoi(start, len); + if (size < 0) { + return "invalid value"; + } + + if ((u_int) size > max) { + return "value must be less than 597 hours"; + } + + total += size * scale; + + if (i >= value[1].len) { + break; + } + + len = 0; + start = &value[1].data[i + 1]; } - size = ngx_atoi(value[1].data, len); - if (size < 0) { - return "value must be greater or equal to zero"; - } - - size *= scale; - - *(int *) (conf + cmd->offset) = size; + *(int *) (conf + cmd->offset) = total; return NGX_CONF_OK; } + +char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +{ + int size, total, len, scale, i; + u_int max; + char last, *start; + ngx_str_t *value; + + value = (ngx_str_t *) cf->args->elts; + start = value[1].data; + len = 0; + total = 0; + + for (i = 0; /* void */ ; i++) { + + if (i < value[1].len) { + if (value[1].data[i] != ' ') { + len++; + continue; + } + + if (value[1].data[i] == ' ' && len == 0) { + start = &value[1].data[i + 1]; + continue; + } + } + + if (len == 0) { + break; + } + + last = value[1].data[i - 1]; + + switch (last) { + case 'm': + len--; + max = 35791394; + scale = 60; + break; + + case 'h': + len--; + max = 596523; + scale = 60 * 60; + break; + + case 'd': + len--; + max = 24855; + scale = 60 * 60 * 24; + break; + + case 'w': + len--; + max = 3550; + scale = 60 * 60 * 24 * 7; + break; + + case 'M': + len--; + max = 828; + scale = 60 * 60 * 24 * 30; + break; + + case 'y': + len--; + max = 68; + scale = 60 * 60 * 24 * 365; + break; + + case 's': + len--; + /* fall thru */ + + default: + max = 2147483647; + scale = 1; + } + + size = ngx_atoi(start, len); + if (size < 0) { + return "invalid value"; + } + + if ((u_int) size > max) { + return "value must be less than 68 years"; + } + + total += size * scale; + + if (i >= value[1].len) { + break; + } + + len = 0; + start = &value[1].data[i + 1]; + } + + *(int *) (conf + cmd->offset) = total; + + return NGX_CONF_OK; +} + + char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { return "unsupported on this platform"; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -100,6 +100,7 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); +char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -87,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -167,10 +168,11 @@ /* FreeBSD sendfile nbytes bug */ #if (__FreeBSD__ == 4 && __FreeBSD_version >= 460100) \ - || __FreeBSD_version == 460001 + || __FreeBSD_version == 460001 \ || __FreeBSD_version >= 500029 #if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG == 2) +#undef HAVE_FREEBSD_SENDFILE_NBYTES_BUG #define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 0 #endif diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -6,14 +6,16 @@ char *ngx_cpystrn(char *dst, char *src, size_t n) { - if (n == 0) + if (n == 0) { return dst; + } for (/* void */; --n; dst++, src++) { *dst = *src; - if (*dst == '\0') + if (*dst == '\0') { return dst; + } } *dst = '\0'; @@ -22,10 +24,36 @@ char *ngx_cpystrn(char *dst, char *src, } +int ngx_rstrncmp(char *s1, char *s2, size_t n) +{ + if (n == 0) { + return 0; + } + + n--; + + for ( ;; ) { + if (s1[n] != s2[n]) { + return (u_char) s1[n] - (u_char) s2[n]; + } + + if (n == 0) { + return 0; + } + + n--; + } +} + + int ngx_atoi(char *line, size_t n) { int value; + if (n == 0) { + return NGX_ERROR; + } + for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -49,6 +49,7 @@ typedef struct { #define ngx_cpymem(dst, src, n) memcpy(dst, src, n) + n char *ngx_cpystrn(char *dst, char *src, size_t n); +int ngx_rstrncmp(char *s1, char *s2, size_t n); int ngx_atoi(char *line, size_t n); diff --git a/src/http/modules/proxy/ngx_http_event_proxy_handler.c b/src/http/modules/proxy/ngx_http_event_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_event_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c @@ -298,41 +298,36 @@ static ngx_chain_t *ngx_http_proxy_creat /* the request line */ - ngx_memcpy(hunk->last, http_methods[p->method - 1].data, - http_methods[p->method - 1].len); - hunk->last += http_methods[p->method - 1].len; + hunk->last = ngx_cpymem(hunk->last, http_methods[p->method - 1].data, + http_methods[p->method - 1].len); - ngx_memcpy(hunk->last, p->upstream_url->uri.data, p->upstream_url->uri.len); - hunk->last += p->upstream_url->uri.len; + hunk->last = ngx_cpymem(hunk->last, p->upstream_url->uri.data, + p->upstream_url->uri.len); - ngx_memcpy(hunk->last, r->uri.data + p->upstream_url->location->len, - r->uri.len - p->upstream_url->location->len); - hunk->last += r->uri.len - p->upstream_url->location->len; + hunk->last = ngx_cpymem(hunk->last, + r->uri.data + p->upstream_url->location->len, + r->uri.len - p->upstream_url->location->len); if (r->args.len > 0) { *(hunk->last++) = '?'; - ngx_memcpy(hunk->last, r->args.data, r->args.len); - hunk->last += r->args.len; + hunk->last = ngx_cpymem(hunk->last, r->args.data, r->args.len); } - ngx_memcpy(hunk->last, http_version, sizeof(http_version) - 1); - hunk->last += sizeof(http_version) - 1; + hunk->last = ngx_cpymem(hunk->last, http_version, sizeof(http_version) - 1); /* the "Host" header */ - ngx_memcpy(hunk->last, host_header, sizeof(host_header) - 1); - hunk->last += sizeof(host_header) - 1; + hunk->last = ngx_cpymem(hunk->last, host_header, sizeof(host_header) - 1); - ngx_memcpy(hunk->last, p->upstream_url->host.data, - p->upstream_url->host.len); - hunk->last += p->upstream_url->host.len; + hunk->last = ngx_cpymem(hunk->last, p->upstream_url->host.data, + p->upstream_url->host.len); *(hunk->last++) = CR; *(hunk->last++) = LF; /* the "Connection: close" header */ - ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1); - hunk->last += sizeof(conn_close_header) - 1; + hunk->last = ngx_cpymem(hunk->last, conn_close_header, + sizeof(conn_close_header) - 1); for (i = 0; i < r->headers_in.headers->nelts; i++) { @@ -344,13 +339,13 @@ static ngx_chain_t *ngx_http_proxy_creat continue; } - ngx_memcpy(hunk->last, header[i].key.data, header[i].key.len); - hunk->last += header[i].key.len; + hunk->last = ngx_cpymem(hunk->last, header[i].key.data, + header[i].key.len); *(hunk->last++) = ':'; *(hunk->last++) = ' '; - ngx_memcpy(hunk->last, header[i].value.data, header[i].value.len); - hunk->last += header[i].value.len; + hunk->last = ngx_cpymem(hunk->last, header[i].value.data, + header[i].value.len); *(hunk->last++) = CR; *(hunk->last++) = LF; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -43,7 +43,7 @@ static ngx_command_t ngx_http_core_comm {ngx_string("post_accept_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_time_slot, + ngx_conf_set_msec_slot, 0, addressof(ngx_http_post_accept_timeout)}, @@ -61,7 +61,7 @@ static ngx_command_t ngx_http_core_comm {ngx_string("client_header_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_time_slot, + ngx_conf_set_msec_slot, 0, addressof(ngx_http_client_header_timeout)}, @@ -103,19 +103,19 @@ static ngx_command_t ngx_http_core_comm {ngx_string("send_timeout"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_time_slot, + ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, send_timeout)}, {ngx_string("lingering_time"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_time_slot, + ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, lingering_time)}, {ngx_string("lingering_timeout"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_time_slot, + ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, lingering_timeout)}, @@ -239,7 +239,7 @@ ngx_log_debug(r->connection->log, "trans continue; } - rc = ngx_strncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len); + rc = ngx_rstrncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len); if (rc < 0) { break; diff --git a/src/os/unix/freebsd/ngx_rfork_thread.h b/src/os/unix/freebsd/ngx_rfork_thread.h deleted file mode 100644 --- a/src/os/unix/freebsd/ngx_rfork_thread.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _NGX_OS_THREAD_H_INCLUDED_ -#define _NGX_OS_THREAD_H_INCLUDED_ - - -typedef int ngx_os_tid_t; -typedef int ngx_tid_t; - - -extern char *ngx_stacks_start; -extern char *ngx_stacks_end; -extern size_t ngx_stack_size; - - -static inline ngx_tid_t ngx_gettid() -{ - char *sp; - - __asm__ ("mov %%esp,%0" : "=r" (sp)); - - return (sp > ngx_stacks_end) ? 0: - (sp - ngx_stacks_start) / ngx_stack_size + 1; -} - - -#endif /* _NGX_OS_THREAD_H_INCLUDED_ */ diff --git a/src/os/unix/freebsd/ngx_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c rename from src/os/unix/freebsd/ngx_rfork_thread.c rename to src/os/unix/ngx_freebsd_rfork_thread.c --- a/src/os/unix/freebsd/ngx_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -1,64 +1,158 @@ -#include +#include +#include +#include +#include +#include + -char *ngx_stacks_start; -char *ngx_stacks_end; -size_t ngx_stack_size; +extern int __isthreaded; + + +typedef int ngx_tid_t; + + +static inline int ngx_gettid(); -/* handle thread-safe errno */ -static int errno0; /* errno for main thread */ +static char *stacks_start; +static char *stacks_end; +static size_t stack_size; +static char *last_stack; +static int last_thread; + +static ngx_log_t *log; + +static ngx_tid_t *tids; + +static int red_zone = 4096; + + +/* the thread-safe errno */ + +static int errno0; /* the main thread's errno */ static int *errnos; int *__error() { - ngx_tid_t tid = ngx_gettid(); - return tid ? &(errnos[ngx_gettid()]) : &errno0; + int tid; + + tid = ngx_gettid(); + return tid ? &errnos[tid] : &errno0; } -int ngx_create_thread(ngx_os_tid_t *tid, void *stack, - int (*func)(void *arg), void *arg, ngx_log_t log) +int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) { - int id, err; + int id, err; + char *stack_top; + + last_stack += stack_size; + stack_top = last_stack - red_zone; + + if (stack_top > stacks_end) { + ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated"); + return NGX_ERROR; + } - id = rfork_thread(RFPROC|RFMEM, stack, func, arg); - err = ngx_errno; +#if 0 + id = rfork_thread(RFPROC|RFMEM|RFFDG|RFCFDG, stack_top, func, arg); +#elif 1 + id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg); +#else + id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg); +#endif + err = errno; - if (id == -1) - ngx_log_error(NGX_LOG_ERR, log, err, - "ngx_create_os_thread: rfork failed"); - else + if (id == -1) { + ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed"); + + } else { *tid = id; + tids[last_thread++] = id; + + /* allow the spinlock in libc malloc() */ + __isthreaded = 1; + } return err; } -int ngx_create_thread_env(int n, size_t size, ngx_log_t log) +int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg) { - char *addr; + int len, i; + char *usrstack, *zone; + + log = lg; - /* create thread stacks */ - addr = mmap(NULL, n * size, PROT_READ|PROT_WRITE, MAP_ANON, -1, NULL); - if (addr == MAP_FAILED) { - ngx_log_error(NGX_LOG_ERR, log, ngx_errno, - "ngx_create_os_thread_stacks: mmap failed"); - return -1; + /* create the thread stacks */ + + len = 4; + if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "sysctlbyname(kern.usrstack) failed"); + return NGX_ERROR; } - nxg_stacks_start = addr; - nxg_stacks_end = addr + n * size; - nxg_stack_size = size; +printf("usrstack: %08X\n", usrstack); +printf("red zone: %08X\n", usrstack - (size + red_zone)); - /* create thread errno array */ - ngx_test_null(errnos, ngx_calloc(n * sizeof(int)), -1); +#if 1 + /* red zone */ + zone = mmap(usrstack - (size + red_zone), red_zone, + PROT_NONE, MAP_ANON, -1, 0); + if (zone == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "mmap(%d, PROT_NONE, MAP_ANON) failed", red_zone); + return NGX_ERROR; + } +#else + zone = usrstack - (size + red_zone); +#endif + + last_stack = zone + red_zone; + + for (i = 0; i < n; i++) { + last_stack -= size + red_zone; +printf("stack: %08X\n", last_stack); + last_stack = mmap(last_stack, size, PROT_READ|PROT_WRITE, + MAP_STACK, -1, 0); + if (last_stack == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "mmap(%d, MAP_STACK) failed", size); + return NGX_ERROR; + } + } - /* create thread tid array */ - ngx_test_null(ngx_os_tids, ngx_calloc(n * sizeof(ngx_os_tid_t)), -1); + stacks_start = last_stack; + stack_size = size + red_zone; + stacks_end = stacks_start + n * stack_size; + + /* create the thread errno array */ + ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR); + + /* create the thread tid array */ + ngx_test_null(tids, ngx_calloc(n * sizeof(ngx_tid_t), log), NGX_ERROR); + + tids[0] = ngx_getpid(); + last_thread = 1; + + return NGX_OK; +} - /* allow spinlock in malloc() */ - __isthreaded = 1; + +ngx_tid_t ngx_thread_self() +{ + return tids[ngx_gettid()]; +} + - return 0; +static inline int ngx_gettid() +{ + char *sp; + + __asm__ ("mov %%esp, %0" : "=q" (sp)); + + return (sp > stacks_end) ? 0: ((sp - stacks_start) / stack_size + 1); }