Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-02-24 20:31:46 +0300
committerIgor Sysoev <igor@sysoev.ru>2004-02-24 20:31:46 +0300
commit48fef6654cc90e05004648423cb5dd7c6f7770f0 (patch)
treec61d52b4dddfb64e28de98bf402b96706f0be418
parentb54698b5798b7f1a54226274347ce1faee5a92a4 (diff)
nginx-0.0.2-2004-02-24-20:31:46 import
-rw-r--r--auto/fmt/ptrfmt62
-rw-r--r--auto/make6
-rw-r--r--auto/os/freebsd16
-rw-r--r--auto/sources1
-rw-r--r--auto/threads6
-rwxr-xr-xauto/unix8
-rw-r--r--src/core/nginx.c12
-rw-r--r--src/core/ngx_alloc.c12
-rw-r--r--src/core/ngx_atomic.h38
-rw-r--r--src/core/ngx_config.h4
-rw-r--r--src/os/unix/ngx_freebsd_config.h7
-rw-r--r--src/os/unix/ngx_freebsd_rfork_thread.c100
-rw-r--r--src/os/unix/ngx_thread.h2
-rw-r--r--src/os/unix/rfork_thread.S69
14 files changed, 279 insertions, 64 deletions
diff --git a/auto/fmt/ptrfmt b/auto/fmt/ptrfmt
new file mode 100644
index 000000000..8bbdcd10c
--- /dev/null
+++ b/auto/fmt/ptrfmt
@@ -0,0 +1,62 @@
+
+echo $ngx_n "checking for $ngx_type printf() format ..." $ngx_c
+echo >> $NGX_ERR
+echo "checking for $ngx_type printf() format" >> $NGX_ERR
+
+ngx_fmt=no
+comma=
+fmtX=
+
+for fmt in $ngx_formats
+do
+
+ cat << END > $NGX_AUTOTEST.c
+
+int main() {
+ printf("$fmt", ($ngx_type) $ngx_max_size);
+ return 0;
+}
+
+END
+
+ eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \
+ >> $NGX_ERR 2>&1"
+
+ max_size=`echo $ngx_max_size | sed -e "s/L*\$//"`
+
+ if [ -x $NGX_AUTOTEST ]; then
+ if [ "`$NGX_AUTOTEST`" = $max_size ]; then
+ ngx_fmt=$fmt
+ fi
+ fi
+
+ rm $NGX_AUTOTEST*
+
+ if [ $ngx_fmt != no ]; then
+ break
+ fi
+
+ fmtX=`echo $fmt | sed -e "s/d/X/"`
+
+ echo $ngx_n "$comma \"${fmtX}\" is not appropriate" $ngx_c
+ comma=","
+done
+
+
+if [ $ngx_fmt = no ]; then
+ echo "$0: error: printf() $ngx_type format not found"
+ exit 1
+fi
+
+fmtX="%0`expr 2 \* ${ngx_ptr_bytes}`"
+ngx_fmt=`echo $ngx_fmt | sed -e "s/d/X/" -e "s/^%/$fmtX/"`
+
+echo "$comma \"${ngx_fmt}\" used"
+
+cat << END >> $NGX_AUTO_CONFIG_H
+
+#ifndef $ngx_fmt_name
+#define $ngx_fmt_name "$ngx_fmt"
+#endif
+
+END
diff --git a/auto/make b/auto/make
index 1394a1d21..c486de4f0 100644
--- a/auto/make
+++ b/auto/make
@@ -59,7 +59,7 @@ echo "nginx: \\" >> $MAKEFILE
for src in $CORE_SRCS $HTTP_SRCS
do
- obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+ obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/" -e "s/\.S\$/.$OBJEXT/"`
echo " $OBJS/$obj \\" >> $MAKEFILE
done
@@ -74,7 +74,7 @@ echo " \$(CC) ${BINOUT}nginx \\" >> $MAKEFILE
for src in $CORE_SRCS $HTTP_SRCS
do
- obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+ obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/" -e "s/\.S\$/.$OBJEXT/"`
echo " $OBJS/$obj \\" >> $MAKEFILE
done
@@ -100,7 +100,7 @@ echo >> $MAKEFILE
for src in $CORE_SRCS
do
- obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+ obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/" -e "s/\.S\$/.$OBJEXT/"`
echo "$OBJS/$obj: \\" >> $MAKEFILE
echo " $src $deps" >> $MAKEFILE
diff --git a/auto/os/freebsd b/auto/os/freebsd
index dfe4ea748..a0748f6fc 100644
--- a/auto/os/freebsd
+++ b/auto/os/freebsd
@@ -11,9 +11,21 @@ version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \
| sed -e 's/^.* \(.*\)$/\1/'`
+# setproctitle() in libutil
+
+if [ \( $version -ge 500000 -a $version -lt 500012 \) \
+ -o $version -lt 410002 ]
+then
+ echo " + setproctitle() in libutil"
+
+ CORE_LIBS="$CORE_LIBS -lutil"
+fi
+
# sendfile
if [ $version -gt 300007 ]; then
+ echo " + sendfile() found"
+
have=HAVE_SENDFILE . auto/have
CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
fi
@@ -24,6 +36,8 @@ fi
if [ \( $version -lt 500000 -a $version -ge 410000 \) \
-o $version -ge 500011 ]
then
+ echo " + kqueue found"
+
have=HAVE_KQUEUE . auto/have
have=HAVE_CLEAR_EVENT . auto/have
CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
@@ -37,6 +51,8 @@ fi
if [ \( $version -lt 500000 -a $version -ge 430000 \) \
-o $version -ge 500018 ]
then
+ echo " + kqueue's NOTE_LAWAT found"
+
have=HAVE_LOWAT_EVENT . auto/have
fi
diff --git a/auto/sources b/auto/sources
index 17e6a4abb..e2220766e 100644
--- a/auto/sources
+++ b/auto/sources
@@ -120,6 +120,7 @@ FREEBSD_DEPS=src/os/unix/ngx_freebsd_config.h
FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c
FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c
FREEBSD_RFORK_SRCS="src/os/unix/ngx_freebsd_rfork_thread.c"
+FREEBSD_RFORK_THREAD_SRCS="src/os/unix/rfork_thread.S"
LINUX_DEPS=src/os/unix/ngx_linux_config.h
LINUX_SRCS=src/os/unix/ngx_linux_init.c
diff --git a/auto/threads b/auto/threads
index 71fbcb6ef..0c677f1d6 100644
--- a/auto/threads
+++ b/auto/threads
@@ -1,7 +1,13 @@
if [ $USE_THREADS = "rfork" ]; then
+
have=NGX_THREADS . auto/have
have=USE_RFORK . auto/have
CORE_DEPS="$CORE_DEPS $UNIX_THREADS_DEPS"
CORE_SRCS="$CORE_SRCS $FREEBSD_RFORK_SRCS"
+
+ if [ $version -lt 501000 ]; then
+ CORE_SRCS="$CORE_SRCS $FREEBSD_RFORK_THREAD_SRCS"
+ fi
+
fi
diff --git a/auto/unix b/auto/unix
index d6fc3730e..017f7bf6a 100755
--- a/auto/unix
+++ b/auto/unix
@@ -4,16 +4,18 @@ ngx_fmt_collect=yes
# C types
-ngx_type="int"; . auto/types/sizeof;
+ngx_type="int"; . auto/types/sizeof
ngx_formats="%d"; . auto/fmt/fmt
-ngx_type="long"; . auto/types/sizeof;
+ngx_type="long"; . auto/types/sizeof
ngx_formats="%ld"; . auto/fmt/fmt
-ngx_type="long long"; . auto/types/sizeof;
+ngx_type="long long"; . auto/types/sizeof
ngx_formats="%lld %qd"; . auto/fmt/fmt
ngx_type="void *"; . auto/types/sizeof; ngx_ptr_bytes=$ngx_bytes
+ngx_fmt_name=PTR_FMT;
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/ptrfmt
# POSIX types
diff --git a/src/core/nginx.c b/src/core/nginx.c
index a9418992e..592711522 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -649,10 +649,18 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
#if (NGX_THREADS)
- ngx_init_threads(5, 128 * 1024 * 1024, cycle->log);
+ if (ngx_init_threads(5, 128 * 1024 * 1024, cycle->log) == NGX_ERROR) {
+ /* fatal */
+ exit(1);
+ }
for (i = 0; i < 1; i++) {
- ngx_create_thread(&tid, ngx_worker_thread_cycle, cycle, cycle->log);
+ if (ngx_create_thread(&tid, ngx_worker_thread_cycle,
+ cycle, cycle->log) != 0)
+ {
+ /* fatal */
+ exit(1);
+ }
}
#endif
diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c
index ae96564fc..1cbd4c8c8 100644
--- a/src/core/ngx_alloc.c
+++ b/src/core/ngx_alloc.c
@@ -9,10 +9,11 @@ void *ngx_alloc(size_t size, ngx_log_t *log)
if (!(p = malloc(size))) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "malloc() %d bytes failed", size);
+ "malloc() " SIZE_T_FMT " bytes failed", size);
}
- ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %08x:%d", p, size);
+ ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0,
+ "malloc: " PTR_FMT ":" SIZE_T_FMT, p, size);
return p;
}
@@ -57,7 +58,7 @@ void ngx_destroy_pool(ngx_pool_t *pool)
for (l = pool->large; l; l = l->next) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
- "free: %08x", l->alloc);
+ "free: " PTR_FMT, l->alloc);
if (l->alloc) {
free(l->alloc);
@@ -72,7 +73,8 @@ void ngx_destroy_pool(ngx_pool_t *pool)
*/
for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %08x", p);
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
+ "free: " PTR_FMT, p);
if (n == NULL) {
break;
@@ -179,7 +181,7 @@ void ngx_pfree(ngx_pool_t *pool, void *p)
for (l = pool->large; l; l = l->next) {
if (p == l->alloc) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
- "free: %08x", l->alloc);
+ "free: " PTR_FMT, l->alloc);
free(l->alloc);
l->alloc = NULL;
}
diff --git a/src/core/ngx_atomic.h b/src/core/ngx_atomic.h
index f5edd1966..5f5add9df 100644
--- a/src/core/ngx_atomic.h
+++ b/src/core/ngx_atomic.h
@@ -6,9 +6,9 @@
#include <ngx_core.h>
-#ifdef __i386__
+#if ( __i386__ || __amd64__ )
-typedef uint32_t ngx_atomic_t;
+typedef volatile uint32_t ngx_atomic_t;
#if (NGX_SMP)
#define NGX_SMP_LOCK "lock"
@@ -21,13 +21,13 @@ static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value)
{
uint32_t old;
- __asm__ __volatile ("
+ __asm__ volatile (
- movl $1, %0
- " NGX_SMP_LOCK
- " xaddl %0, %1
+ " movl $1, %0; "
+ NGX_SMP_LOCK
+ " xaddl %0, %1; "
- ": "=a" (old) : "m" (*value));
+ : "=a" (old) : "m" (*value));
return old;
}
@@ -37,13 +37,13 @@ static ngx_inline uint32_t ngx_atomic_dec(ngx_atomic_t *value)
{
uint32_t old;
- __asm__ __volatile ("
+ __asm__ volatile (
- movl $-1, %0
- " NGX_SMP_LOCK
- " xaddl %0, %1
+ " movl $-1, %0; "
+ NGX_SMP_LOCK
+ " xaddl %0, %1; "
- ": "=a" (old) : "m" (*value));
+ : "=a" (old) : "m" (*value));
return old;
}
@@ -55,21 +55,21 @@ static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
{
uint32_t res;
- __asm__ __volatile ("
+ __asm__ volatile (
- " NGX_SMP_LOCK
- " cmpxchgl %3, %1
- setzb %%al
- movzbl %%al, %0
+ NGX_SMP_LOCK
+ " cmpxchgl %3, %1; "
+ " setzb %%al; "
+ " movzbl %%al, %0; "
- ": "=a" (res) : "m" (*lock), "a" (old), "q" (set));
+ : "=a" (res) : "m" (*lock), "a" (old), "q" (set));
return res;
}
#else
-typedef uint32_t ngx_atomic_t;
+typedef volatile uint32_t ngx_atomic_t;
/* STUB */
#define ngx_atomic_inc(x) x++;
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 67e17d0a3..e56edc9ac 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -46,10 +46,6 @@ typedef u_int ngx_uint_t;
typedef int ngx_flag_t;
-/* STUB: autoconf */
-#define PTR_FMT "%08X"
-
-
#ifndef NGX_SERVER_ROOT
#define NGX_SERVER_ROOT "./"
#if 0
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
index e447340a8..f0a8430fe 100644
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -29,6 +29,7 @@
#include <grp.h>
#include <netdb.h>
#include <dirent.h>
+#include <libutil.h> /* setproctitle() brefore 4.1 */
#include <osreldate.h>
#include <ngx_auto_config.h>
@@ -72,6 +73,12 @@
#endif
+#if (__FreeBSD_version < 430000 || __FreeBSD_version < 500012)
+
+pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg);
+
+#endif
+
#ifndef IOV_MAX
#define IOV_MAX 1024
#endif
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c
index ae01851a2..7e28b0da5 100644
--- a/src/os/unix/ngx_freebsd_rfork_thread.c
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -15,12 +15,12 @@
* The condition variable implementation uses the SysV semaphore set of two
* semaphores. The first is used by the CV mutex, and the second is used
* by CV itself.
+ *
+ * This threads implementation currently works on i486 and amd64
+ * platforms only.
*/
-extern int __isthreaded;
-
-
static inline int ngx_gettid();
@@ -36,7 +36,7 @@ static ngx_uint_t max_threads;
static ngx_tid_t *tids; /* the threads tids array */
-/* the thread-safe errno */
+/* the thread-safe libc errno */
static int errno0; /* the main thread's errno */
static int *errnos; /* the threads errno's array */
@@ -51,6 +51,41 @@ int *__error()
}
+/*
+ * __isthreaded enables spinlock() in some libc functions, i.e. in malloc()
+ * and some other places. Nevertheless we protect our malloc()/free() calls
+ * by own mutex that is more efficient than the spinlock.
+ *
+ * We define own _spinlock() because a weak referenced _spinlock() stub in
+ * src/lib/libc/gen/_spinlock_stub.c does nothing.
+ */
+
+extern int __isthreaded;
+
+void _spinlock(ngx_atomic_t *lock)
+{
+ ngx_int_t tries;
+
+ tries = 0;
+ for ( ;; ) {
+
+ if (*lock) {
+ if (ngx_freebsd_hw_ncpu > 1 && tries++ < 1000) {
+ continue;
+ }
+
+ sched_yield();
+ tries = 0;
+
+ } else {
+ if (ngx_atomic_cmp_set(lock, 0, 1)) {
+ return;
+ }
+ }
+ }
+}
+
+
int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
ngx_log_t *log)
{
@@ -70,7 +105,8 @@ int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
if (stack == MAP_FAILED) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "mmap(%08X:%d, MAP_STACK) thread stack failed",
+ "mmap(" PTR_FMT ":" SIZE_T_FMT
+ ", MAP_STACK) thread stack failed",
last_stack, usable_stack_size);
return NGX_ERROR;
}
@@ -82,7 +118,7 @@ int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
stack_top = stack + usable_stack_size;
ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
- "thread stack: %08X-%08X", stack, stack_top);
+ "thread stack: " PTR_FMT "-" PTR_FMT, stack, stack_top);
#if 1
id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
@@ -113,12 +149,12 @@ int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
ngx_int_t ngx_init_threads(int n, size_t size, ngx_log_t *log)
{
- int len;
- char *red_zone, *zone;
+ size_t len;
+ char *red_zone, *zone;
max_threads = n;
- len = 4;
+ len = sizeof(usrstack);
if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"sysctlbyname(kern.usrstack) failed");
@@ -129,12 +165,14 @@ ngx_int_t ngx_init_threads(int n, size_t size, ngx_log_t *log)
red_zone = usrstack - (size + rz_size);
ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
- "usrstack: %08X, red zone: %08X", usrstack, red_zone);
+ "usrstack: " PTR_FMT " red zone: " PTR_FMT,
+ usrstack, red_zone);
zone = mmap(red_zone, rz_size, PROT_NONE, MAP_ANON, -1, 0);
if (zone == MAP_FAILED) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "mmap(%08X:%d, PROT_NONE, MAP_ANON) red zone failed",
+ "mmap(" PTR_FMT ":" SIZE_T_FMT
+ ", PROT_NONE, MAP_ANON) red zone failed",
red_zone, rz_size);
return NGX_ERROR;
}
@@ -177,7 +215,15 @@ static inline int ngx_gettid()
return 0;
}
- __asm__ ("mov %%esp, %0" : "=q" (sp));
+#if ( __i386__ )
+
+ __asm__ volatile ("mov %%esp, %0" : "=q" (sp));
+
+#elif ( __amd64__ )
+
+ __asm__ volatile ("mov %%rsp, %0" : "=q" (sp));
+
+#endif
return (usrstack - sp) / stack_size;
}
@@ -258,7 +304,7 @@ void ngx_mutex_done(ngx_mutex_t *m)
"semctl(IPC_RMID) failed");
}
- ngx_free(m);
+ ngx_free((void *) m);
}
@@ -271,10 +317,10 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
#if (NGX_DEBUG)
if (try) {
ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
- "try lock mutex %08X lock:%X", m, m->lock);
+ "try lock mutex " PTR_FMT " lock:%X", m, m->lock);
} else {
ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
- "lock mutex %08X lock:%X", m, m->lock);
+ "lock mutex " PTR_FMT " lock:%X", m, m->lock);
}
#endif
@@ -305,7 +351,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
}
ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
- "mutex %08X lock:%X", m, m->lock);
+ "mutex " PTR_FMT " lock:%X", m, m->lock);
/*
* The mutex is locked so we increase a number
@@ -316,8 +362,8 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
if ((lock & ~NGX_MUTEX_LOCK_BUSY) > nthreads) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "%d threads wait for mutex %0X, "
- "while only %d threads are available",
+ "%d threads wait for mutex " PTR_FMT
+ ", while only %d threads are available",
lock & ~NGX_MUTEX_LOCK_BUSY, m, nthreads);
return NGX_ERROR;
}
@@ -325,7 +371,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
- "wait mutex %08X lock:%X", m, m->lock);
+ "wait mutex " PTR_FMT " lock:%X", m, m->lock);
/*
* The number of the waiting threads has been increased
@@ -341,7 +387,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
if (semop(m->semid, &op, 1) == -1) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
"semop() failed while waiting "
- "on mutex %08X", m);
+ "on mutex " PTR_FMT, m);
return NGX_ERROR;
}
@@ -368,7 +414,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
if (tries++ > 1000) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
- "mutex %08X is contested", m);
+ "mutex " PTR_FMT " is contested", m);
/* the mutex is probably contested so we are giving up now */
@@ -380,7 +426,7 @@ ngx_int_t ngx_mutex_do_lock(ngx_mutex_t *m, ngx_int_t try)
}
ngx_log_debug2(NGX_LOG_DEBUG_CORE, m->log, 0,
- "mutex %08X is locked, lock:%X", m, m->lock);
+ "mutex " PTR_FMT " is locked, lock:%X", m, m->lock);
return NGX_OK;
}
@@ -395,7 +441,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
if (!(old & NGX_MUTEX_LOCK_BUSY)) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "tring to unlock the free mutex %0X", m);
+ "tring to unlock the free mutex " PTR_FMT, m);
return NGX_ERROR;
}
@@ -413,7 +459,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
if (m->semid == -1) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
- "mutex %08X is unlocked", m);
+ "mutex " PTR_FMT " is unlocked", m);
return NGX_OK;
}
@@ -448,8 +494,8 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
if (semop(m->semid, &op, 1) == -1) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "semop() failed while waking up on mutex %08X",
- m);
+ "semop() failed while waking up on mutex "
+ PTR_FMT, m);
return NGX_ERROR;
}
@@ -460,7 +506,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, m->log, 0,
- "mutex %08X is unlocked", m);
+ "mutex " PTR_FMT " is unlocked", m);
return NGX_OK;
}
diff --git a/src/os/unix/ngx_thread.h b/src/os/unix/ngx_thread.h
index ce305deb7..9637fda85 100644
--- a/src/os/unix/ngx_thread.h
+++ b/src/os/unix/ngx_thread.h
@@ -28,7 +28,7 @@ typedef pid_t ngx_tid_t;
#define NGX_MUTEX_LOCK_BUSY 0x80000000
-typedef struct {
+typedef volatile struct {
ngx_atomic_t lock;
ngx_log_t *log;
int semid;
diff --git a/src/os/unix/rfork_thread.S b/src/os/unix/rfork_thread.S
new file mode 100644
index 000000000..5abb9f831
--- /dev/null
+++ b/src/os/unix/rfork_thread.S
@@ -0,0 +1,69 @@
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+
+/*
+ * rfork_thread(3) - rfork_thread(flags, stack, func, arg);
+ */
+
+#define KERNCALL int $0x80
+
+ENTRY(rfork_thread)
+ push %ebp
+ mov %esp, %ebp
+ push %esi
+
+ mov 12(%ebp), %esi # the stack address
+
+ sub $4, %esi
+ mov 20(%ebp), %eax # the thread argument
+ mov %eax, (%esi)
+
+ sub $4, %esi
+ mov 16(%ebp), %eax # the start thread address
+ mov %eax, (%esi)
+
+ push 8(%ebp) # rfork(2) flags
+ push $0
+ mov $SYS_rfork, %eax
+ KERNCALL
+ jc error
+
+ cmp $0, %edx
+ jne child
+
+parent:
+ add $8, %esp
+ pop %esi
+ mov %ebp, %esp
+ pop %ebp
+ ret
+
+child:
+ mov %esi, %esp
+ pop %eax
+ call *%eax # call a thread start address ...
+ add $4, %esp
+
+ push %eax
+ push $0
+ mov $SYS_exit, %eax # ... and exit(2) after a thread would return
+ KERNCALL
+
+error:
+ add $8, %esp
+ pop %esi
+ mov %ebp, %esp
+ pop %ebp
+ PIC_PROLOGUE
+
+ /* libc's cerror: jmp PIC_PLT(HIDENAME(cerror)) */
+
+ push %eax
+ call PIC_PLT(CNAME(__error))
+ pop %ecx
+ PIC_EPILOGUE
+ mov %ecx, (%eax)
+ mov $-1, %eax
+ mov $-1, %edx
+ ret