changeset 84:fab4cb00fe5b

nginx-0.0.1-2003-05-06-21:03:16 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 06 May 2003 17:03:16 +0000
parents a7e45c45a95c
children 3549c2bf9eaf
files src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/core/ngx_config.h src/core/ngx_string.c src/core/ngx_string.h src/http/modules/proxy/ngx_http_event_proxy_handler.c src/http/ngx_http_core_module.c src/os/unix/freebsd/ngx_rfork_thread.c src/os/unix/freebsd/ngx_rfork_thread.h src/os/unix/ngx_freebsd_rfork_thread.c
diffstat 9 files changed, 367 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- 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";
--- 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);
 
 
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -87,6 +87,7 @@
 #include <signal.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/socket.h>
@@ -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
 
--- 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;
--- 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);
 
 
--- 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;
 
--- 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;
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_ */
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 <ngx_os_thread.h>
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_process.h>
+#include <ngx_log.h>
+#include <ngx_alloc.h>
+
 
-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);
 }