diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-05-12 15:52:24 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-05-12 15:52:24 +0000 |
commit | 6b863e353d54420c323d67f86aad0b90ba04e316 (patch) | |
tree | 51d13ab529d2605be3995333d71344c917c5c4f4 /src/os/unix | |
parent | 4fe262b6821a461b3dbb3d6bfd05a8f713157524 (diff) | |
download | nginx-6b863e353d54420c323d67f86aad0b90ba04e316.tar.gz nginx-6b863e353d54420c323d67f86aad0b90ba04e316.zip |
nginx-0.0.1-2003-05-12-19:52:24 import
Diffstat (limited to 'src/os/unix')
-rw-r--r-- | src/os/unix/ngx_daemon.c | 80 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.c | 67 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.h | 18 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_rfork_thread.c | 145 | ||||
-rw-r--r-- | src/os/unix/ngx_init.c | 20 |
5 files changed, 272 insertions, 58 deletions
diff --git a/src/os/unix/ngx_daemon.c b/src/os/unix/ngx_daemon.c new file mode 100644 index 000000000..6faf85b06 --- /dev/null +++ b/src/os/unix/ngx_daemon.c @@ -0,0 +1,80 @@ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_log.h> + +/* daemon in Linux */ + +int ngx_daemon(ngx_log_t *log) +{ + int fd; + + switch (fork()) { + case -1: + ngx_log_error(NGX_LOG_ALERT, log, errno, "fork() failed"); + return NGX_ERROR; + + case 0: + break; + + default: + exit(0); + } + + if (setsid() == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "setsid() failed"); + return NGX_ERROR; + } + +#if (__SVR4 || linux) + + /* need HUP IGN ? check in Solaris and Linux */ + + switch (fork()) { + case -1: + ngx_log_error(NGX_LOG_ALERT, log, errno, "fork() failed"); + return NGX_ERROR; + + case 0: + break; + + default: + exit(0); + } + +#endif + + umask(0); + +#if 0 + fd = open("/dev/null", O_RDWR); + if (fd == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "open(\"/dev/null\") failed"); + return NGX_ERROR; + } + + if (dup2(fd, STDIN_FILENO) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDIN) failed"); + return NGX_ERROR; + } + + if (dup2(fd, STDOUT_FILENO) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDOUT) failed"); + return NGX_ERROR; + } + + if (dup2(fd, STDERR_FILENO) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDERR) failed"); + return NGX_ERROR; + } + + if (fd > STDERR_FILENO) { + if (close(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "close() failed"); + return NGX_ERROR; + } + } +#endif + + return NGX_OK; +} diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c new file mode 100644 index 000000000..a24fc4132 --- /dev/null +++ b/src/os/unix/ngx_freebsd_init.c @@ -0,0 +1,67 @@ + +#include <ngx_freebsd_init.h> + + +int freebsd_kern_osreldate; +int freebsd_hw_ncpu; + +int freebsd_sendfile_nbytes_bug; + + +int ngx_os_init(ngx_log_t *log) +{ + size_t size; + + size = 4; + if (sysctlbyname("kern.osreldate", + &freebsd_kern_osreldate, &size, NULL, 0) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "sysctlbyname(kern.osreldate) failed"); + return NGX_ERROR; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, + "kern.osreldate: %d, built on %d", + freebsd_kern_osreldate, __FreeBSD_version); + + +#if HAVE_FREEBSD_SENDFILE + + /* The determination of the sendfile() nbytes bug is complex enough. + There're two sendfile() syscalls: a new 393 has no bug while + an old 336 has the bug in some versions and has not in others. + libc_r wrapper also emulates the bug in some versions. + There's no way to say exactly if a given FreeBSD version has bug. + Here is the algorithm that work at least for RELEASEs + and for syscalls only (not libc_r wrapper). */ + + /* detect was the new sendfile() version available at the compile time + to allow an old binary to run correctly on an updated FreeBSD system. */ + +#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \ + || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039 + + /* a new syscall without the bug */ + freebsd_sendfile_nbytes_bug = 0; + +#else + + /* an old syscall that can have the bug */ + freebsd_sendfile_nbytes_bug = 1; + +#endif + +#endif /* HAVE_FREEBSD_SENDFILE */ + + + size = 4; + if (sysctlbyname("hw.ncpu", &freebsd_hw_ncpu, &size, NULL, 0) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "sysctlbyname(hw.ncpu) failed"); + return NGX_ERROR; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, "hw.ncpu: %d", freebsd_hw_ncpu); + + return NGX_OK; +} diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h new file mode 100644 index 000000000..d0af10b24 --- /dev/null +++ b/src/os/unix/ngx_freebsd_init.h @@ -0,0 +1,18 @@ +#ifndef _NGX_OS_INIT_H_INCLUDED_ +#define _NGX_OS_INIT_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_log.h> +#include <sys/sysctl.h> + + +int ngx_os_init(ngx_log_t *log); + + +extern int freebsd_kern_osreldate; +extern int freebsd_hw_ncpu; + + +#endif /* _NGX_OS_INIT_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c index 6cbb078b1..88cecedde 100644 --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -11,57 +11,76 @@ extern int __isthreaded; typedef int ngx_tid_t; -#define NGX_MAX_THREADS 10 - static inline int ngx_gettid(); -static char *stacks_start; -static char *stacks_end; +static char *usrstack; +static int red_zone = 4096; + static size_t stack_size; +static size_t usable_stack_size; static char *last_stack; -static int last_thread; - -static ngx_log_t *log; - -static ngx_tid_t tids[NGX_MAX_THREADS]; - -static int red_zone = 4096; +static int threads; +static int nthreads; +static ngx_tid_t *tids; /* the thread-safe errno */ -static int errnos[NGX_MAX_THREADS]; +static int errno0; /* the main thread's errno */ +static int *errnos; int *__error() { - return &errnos[ngx_gettid()]; + int tid; + + tid = ngx_gettid(); + + return tid ? &errnos[tid - 1] : &errno0; } -int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) +int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg, + ngx_log_t *log) { int id, err; - char *stack_top; + char *stack, *stack_top; - last_stack += stack_size; - stack_top = last_stack - red_zone; + if (threads >= nthreads) { + ngx_log_error(NGX_LOG_CRIT, log, 0, + "no more than %d threads can be created", nthreads); + return NGX_ERROR; + } - if (stack_top > stacks_end) { - ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated"); + last_stack -= stack_size; + stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE, + MAP_STACK, -1, 0); + if (stack == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "mmap(%08X:%d, MAP_STACK) thread stack failed", + last_stack, usable_stack_size); return NGX_ERROR; } -#if 0 - id = rfork(RFFDG|RFCFDG); -#elif 0 - id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg); -#elif 0 + if (stack != last_stack) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "stack address was changed"); + } + + stack_top = stack + usable_stack_size; + +printf("stack: %08X-%08X\n", stack, stack_top); + +#if 1 + id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg); +#elif 1 id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg); +#elif 1 + id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg); #else - id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg); + id = rfork(RFFDG|RFCFDG); #endif + err = errno; if (id == -1) { @@ -69,7 +88,8 @@ int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) } else { *tid = id; - tids[last_thread++] = id; + threads = (usrstack - stack_top) / stack_size; + tids[threads] = id; /* allow the spinlock in libc malloc() */ __isthreaded = 1; @@ -79,14 +99,12 @@ int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) } -int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg) +int ngx_init_thread_env(int n, size_t size, ngx_log_t *log) { - int len, i; - char *usrstack, *zone; - - log = lg; + int len; + char *rz, *zone; - /* create the thread stacks */ + nthreads = n; len = 4; if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) { @@ -96,41 +114,37 @@ int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg) } printf("usrstack: %08X\n", usrstack); -printf("red zone: %08X\n", usrstack - (size + red_zone)); -#if 1 /* red zone */ - zone = mmap(usrstack - (size + red_zone), red_zone, - PROT_NONE, MAP_ANON, -1, 0); + rz = usrstack - (size + red_zone); + +printf("red zone: %08X\n", rz); + + zone = mmap(rz, 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); + "mmap(%08X:%d, PROT_NONE, MAP_ANON) red zone failed", + rz, 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; - } + if (zone != rz) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "red zone address was changed"); } - 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 + 1) * sizeof(ngx_tid_t), log), + NGX_ERROR); tids[0] = ngx_getpid(); - last_thread = 1; + threads = 1; + + last_stack = zone + red_zone; + usable_stack_size = size; + stack_size = size + red_zone; return NGX_OK; } @@ -138,7 +152,18 @@ printf("stack: %08X\n", last_stack); ngx_tid_t ngx_thread_self() { - return tids[ngx_gettid()]; + int tid; + ngx_tid_t pid; + + tid = ngx_gettid(); + + if (tids[tid] == 0) { + pid = ngx_getpid(); + tids[tid] = pid; + return pid; + } + + return tids[tid]; } @@ -146,7 +171,11 @@ static inline int ngx_gettid() { char *sp; + if (stack_size == 0) { + return 0; + } + __asm__ ("mov %%esp, %0" : "=q" (sp)); - return (sp > stacks_end) ? 0 : ((sp - stacks_start) / stack_size + 1); + return (usrstack - sp) / stack_size; } diff --git a/src/os/unix/ngx_init.c b/src/os/unix/ngx_init.c new file mode 100644 index 000000000..28af1288d --- /dev/null +++ b/src/os/unix/ngx_init.c @@ -0,0 +1,20 @@ + + +int ngx_unix_init(ngx_log_t *log) +{ + struct rlimit rlmt; + + if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "getrlimit(RLIMIT_NOFILE) failed)"); + return NGX_ERROR; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, + "getrlimit(RLIMIT_NOFILE): %d", rlmt.rlim_cur); + + RLIM_INFINITY + max_connections =< rlmt.rlim_cur; + + return NGX_OK; +} |