nginx-0.0.7-2004-06-27-22:01:57 import

This commit is contained in:
Igor Sysoev 2004-06-27 18:01:57 +00:00
parent b1af9bbcab
commit c02473048c
33 changed files with 462 additions and 194 deletions

38
auto/endianess Normal file
View File

@ -0,0 +1,38 @@
echo $ngx_n "checking for system endianess ..." $ngx_c
echo >> $NGX_ERR
echo "checking for system endianess" >> $NGX_ERR
cat << END > $NGX_AUTOTEST.c
int main() {
int i = 0x11223344;
char *p;
p = (char *) &i;
if (*p == 0x44) return 0;
return 1;
}
END
eval "${CC} -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
if $NGX_AUTOTEST 2>&1 > /dev/null; then
echo " little endianess"
have=HAVE_LITTLE_ENDIAN . auto/have
else
echo " big endianess"
fi
rm $NGX_AUTOTEST*
else
rm $NGX_AUTOTEST*
echo
echo "$0: error: can not detect system endianess"
exit 1
fi

View File

@ -11,15 +11,15 @@ do
cat << END > $NGX_AUTOTEST.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <sys/resource.h>
$NGX_INTTYPES_H
$NGX_AUTO_CONFIG
int main() {
printf("$fmt", ($ngx_type) $ngx_max_size);
printf("$fmt", ($ngx_type) $ngx_max_value);
return 0;
}
@ -28,10 +28,10 @@ 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*\$//"`
max_value=`echo $ngx_max_value | sed -e "s/L*\$//"`
if [ -x $NGX_AUTOTEST ]; then
if [ "`$NGX_AUTOTEST`" = $max_size ]; then
if [ "`$NGX_AUTOTEST`" = $max_value ]; then
if [ $ngx_fmt_collect = yes ]; then
echo $ngx_n "$comma \"${fmt}\" is appropriate" $ngx_c
else
@ -45,7 +45,7 @@ END
if [ $ngx_fmt != no ]; then
if [ $ngx_fmt_collect = yes ]; then
eval "ngx_${ngx_bytes}_fmt=\"\${ngx_${ngx_bytes}_fmt} \$ngx_fmt\""
eval "ngx_${ngx_size}_fmt=\"\${ngx_${ngx_size}_fmt} \$ngx_fmt\""
comma=","
continue
else

View File

@ -13,7 +13,7 @@ do
cat << END > $NGX_AUTOTEST.c
int main() {
printf("$fmt", ($ngx_type) $ngx_max_size);
printf("$fmt", ($ngx_type) $ngx_max_value);
return 0;
}
@ -22,10 +22,10 @@ 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*\$//"`
max_value=`echo $ngx_max_value | sed -e "s/L*\$//"`
if [ -x $NGX_AUTOTEST ]; then
if [ "`$NGX_AUTOTEST`" = $max_size ]; then
if [ "`$NGX_AUTOTEST`" = $max_value ]; then
ngx_fmt=$fmt
fi
fi
@ -49,8 +49,8 @@ if [ $ngx_fmt = no ]; then
fi
if [ $ngx_ptr_bytes = 4 ]; then
fmtX="%0`expr 2 \* $ngx_ptr_bytes`"
if [ $ngx_ptr_size = 4 ]; then
fmtX="%0`expr 2 \* $ngx_ptr_size`"
else
fmtX="%"
fi

View File

@ -1,6 +0,0 @@
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_type_max_value
#define $ngx_type_max_value $ngx_max_size
#endif

View File

@ -3,14 +3,15 @@ echo $ngx_n "checking for $ngx_type size ..." $ngx_c
echo >> $NGX_ERR
echo "checking for $ngx_type size" >> $NGX_ERR
ngx_bytes=
ngx_size=
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
$NGX_UNISTD_H
#include <signal.h>
#include <sys/resource.h>
$NGX_INTTYPES_H
$NGX_AUTO_CONFIG
@ -24,27 +25,31 @@ END
eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
ngx_bytes=`$NGX_AUTOTEST`
echo " $ngx_bytes bytes"
ngx_size=`$NGX_AUTOTEST`
echo " $ngx_size bytes"
fi
rm $NGX_AUTOTEST*
case $ngx_bytes in
case $ngx_size in
4)
if [ "$ngx_type"="long" ]; then
ngx_max_size=2147483647L
ngx_max_value=2147483647L
else
ngx_max_size=2147483647
ngx_max_value=2147483647
fi
ngx_max_len='sizeof("-2147483648") - 1'
;;
8)
if [ "$ngx_type"="long long" ]; then
ngx_max_size=9223372036854775807LL
ngx_max_value=9223372036854775807LL
else
ngx_max_size=9223372036854775807L
ngx_max_value=9223372036854775807L
fi
ngx_max_len='sizeof("-9223372036854775808") - 1'
;;
*)

View File

@ -10,8 +10,8 @@ do
cat << END > $NGX_AUTOTEST.c
#include <signal.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>

View File

@ -30,7 +30,7 @@ rm $NGX_AUTOTEST*
if [ $found = no ]; then
found="uint`expr 8 \* $ngx_ptr_bytes`_t"
found="uint`expr 8 \* $ngx_ptr_size`_t"
echo ", $found used"
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H

6
auto/types/value Normal file
View File

@ -0,0 +1,6 @@
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_param
#define $ngx_param $ngx_value
#endif

View File

@ -13,32 +13,31 @@ ngx_formats="%ld"; . auto/fmt/fmt
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_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
ngx_fmt_name=PTR_FMT;
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/ptrfmt
eval ngx_formats=\${ngx_${ngx_ptr_size}_fmt}; . auto/fmt/ptrfmt
# POSIX types
NGX_AUTO_CONFIG="#include \"../$NGX_AUTO_CONFIG_H\""
ngx_type="uint64_t"
ngx_types="u_int64_t"; . auto/types/typedef
ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef
ngx_type="sig_atomic_t"
ngx_types="int"; . auto/types/typedef
ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef
. auto/types/sizeof
ngx_param=SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
ngx_type="socklen_t"
ngx_types="uint32_t"; . auto/types/typedef
ngx_type="socklen_t"; ngx_types="uint32_t"; . auto/types/typedef
ngx_type="in_addr_t"
ngx_types="uint32_t"; . auto/types/typedef
ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef
ngx_type="rlim_t"
ngx_types="int"; . auto/types/typedef
ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
. auto/types/uintptr_t
. auto/endianess
# printf() formats
@ -46,22 +45,24 @@ CC_WARN=$CC_STRONG
ngx_fmt_collect=no
ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof
ngx_type_max_value=OFF_T_MAX_VALUE; . auto/types/maxvalue
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
ngx_param=OFF_T_MAX_VALUE; ngx_value=$ngx_max_value; . auto/types/value
eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
ngx_fmt_name=TIME_T_FMT; ngx_type="time_t"; . auto/types/sizeof
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
ngx_param=TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
ngx_param=TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
ngx_fmt_name=SIZE_T_FMT; ngx_type="size_t"; . auto/types/sizeof
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
ngx_fmt_name=SIZE_T_X_FMT; . auto/fmt/xfmt
ngx_fmt_name=PID_T_FMT; ngx_type="pid_t"; . auto/types/sizeof
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
ngx_fmt_name=RLIM_T_FMT; ngx_type="rlim_t"; . auto/types/sizeof
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
# syscalls, libc calls and some features

View File

@ -93,4 +93,18 @@ typedef volatile uint32_t ngx_atomic_t;
#endif
static ngx_inline ngx_int_t ngx_trylock(ngx_atomic_t *lock)
{
if (*lock) {
return NGX_BUSY;
}
if (ngx_atomic_cmp_set(lock, 0, 1)) {
return NGX_OK;
}
return NGX_BUSY;
}
#endif /* _NGX_ATOMIC_H_INCLUDED_ */

View File

@ -75,10 +75,6 @@ typedef long ngx_flag_t;
/* TODO: auto */
#define NGX_INT32_LEN sizeof("-2147483648") - 1
#define NGX_INT64_LEN sizeof("-9223372036854775808") - 1
#if 0
#define NGX_TIME_T_LEN sizeof("-2147483648") - 1
#endif
#define NGX_TIME_T_LEN sizeof("-9223372036854775808") - 1
#define NGX_OFF_T_LEN sizeof("-9223372036854775808") - 1

View File

@ -108,6 +108,10 @@ struct ngx_connection_s {
#if (HAVE_IOCP)
unsigned accept_context_updated:1;
#endif
#if (NGX_THREADS)
ngx_atomic_t lock;
#endif
};

View File

@ -15,6 +15,15 @@ typedef struct ngx_event_s ngx_event_t;
typedef struct ngx_connection_s ngx_connection_t;
#define NGX_OK 0
#define NGX_ERROR -1
#define NGX_AGAIN -2
#define NGX_BUSY -3
#define NGX_DONE -4
#define NGX_DECLINED -5
#define NGX_ABORT -6
#include <ngx_atomic.h>
#include <ngx_time.h>
#include <ngx_socket.h>
@ -49,16 +58,6 @@ typedef struct ngx_connection_s ngx_connection_t;
#include <ngx_connection.h>
#define NGX_OK 0
#define NGX_ERROR -1
#define NGX_AGAIN -2
#define NGX_BUSY -3
#define NGX_DONE -4
#define NGX_DECLINED -5
#define NGX_ABORT -6
#define LF (u_char) 10
#define CR (u_char) 13
#define CRLF "\x0d\x0a"

View File

@ -254,7 +254,7 @@ int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name,
* Unices have the mount option "noatime".
*/
if (ngx_cached_time - ngx_de_mtime(dir) < 3600) {
if (ngx_time() - ngx_de_mtime(dir) < 3600) {
return NGX_OK;
}

View File

@ -3,32 +3,62 @@
#include <ngx_core.h>
ngx_epoch_msec_t ngx_elapsed_msec;
ngx_epoch_msec_t ngx_old_elapsed_msec;
ngx_epoch_msec_t ngx_start_msec;
static ngx_tm_t ngx_cached_gmtime;
static ngx_int_t ngx_gmtoff;
/*
* In the threaded mode only one thread updates cached time and strings
* and these operations are protected by the mutex. The reading of the cached
* time and strings is not protected by the mutex. To avoid the race
* conditions for non-atomic values we use the NGX_TIME_SLOTS slots to store
* time value and strings. Thus thread may get the corrupted values only
* if it is preempted while copying and then it is not scheduled to run
* more than NGX_TIME_SLOTS seconds.
*/
#if (NGX_THREADS)
static ngx_mutex_t *ngx_time_mutex;
#define NGX_TIME_SLOTS 60
static ngx_uint_t slot = NGX_TIME_SLOTS;
static ngx_mutex_t *ngx_time_mutex;
#else
#define NGX_TIME_SLOTS 1
#define slot 0
#endif
ngx_epoch_msec_t ngx_elapsed_msec;
ngx_epoch_msec_t ngx_old_elapsed_msec;
ngx_epoch_msec_t ngx_start_msec;
#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
volatile time_t ngx_cached_time;
volatile time_t *ngx_cached_time;
static time_t cached_time[NGX_TIME_SLOTS];
volatile ngx_str_t ngx_cached_err_log_time;
volatile ngx_str_t ngx_cached_http_time;
volatile ngx_str_t ngx_cached_http_log_time;
#else
static ngx_tm_t ngx_cached_gmtime;
static ngx_int_t ngx_gmtoff;
volatile time_t ngx_cached_time;
static u_char cached_err_log_time0[] = "1970/09/28 12:00:00";
static u_char cached_err_log_time1[] = "1970/09/28 12:00:00";
#endif
static u_char cached_http_time0[] = "Mon, 28 Sep 1970 06:00:00 GMT";
static u_char cached_http_time1[] = "Mon, 28 Sep 1970 06:00:00 GMT";
static u_char cached_http_log_time0[] = "28/Sep/1970:12:00:00 +0600";
static u_char cached_http_log_time1[] = "28/Sep/1970:12:00:00 +0600";
ngx_thread_volatile ngx_str_t ngx_cached_err_log_time;
ngx_thread_volatile ngx_str_t ngx_cached_http_time;
ngx_thread_volatile ngx_str_t ngx_cached_http_log_time;
static u_char cached_err_log_time[NGX_TIME_SLOTS]
[sizeof("1970/09/28 12:00:00")];
static u_char cached_http_time[NGX_TIME_SLOTS]
[sizeof("Mon, 28 Sep 1970 06:00:00 GMT")];
static u_char cached_http_log_time[NGX_TIME_SLOTS]
[sizeof("28/Sep/1970:12:00:00 +0600")];
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
@ -45,16 +75,13 @@ void ngx_time_init()
ngx_cached_gmtime.ngx_tm_zone = "GMT";
#endif
ngx_cached_err_log_time.len = sizeof(cached_err_log_time0) - 1;
ngx_cached_err_log_time.data = cached_err_log_time0;
ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
ngx_cached_http_time.len = sizeof(cached_http_time0) - 1;
ngx_cached_http_time.data = cached_http_time0;
ngx_cached_http_log_time.len = sizeof(cached_http_log_time0) - 1;
ngx_cached_http_log_time.data = cached_http_log_time0;
ngx_cached_time = 0;
#if (TIME_T_SIZE > SIG_ATOMIC_T_SIZE)
ngx_cached_time = &cached_time[0];
#endif
ngx_gettimeofday(&tv);
@ -89,26 +116,34 @@ void ngx_time_update(time_t s)
u_char *p;
ngx_tm_t tm;
if (ngx_cached_time == s) {
if (ngx_time() == s) {
return;
}
#if (NGX_THREADS)
if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) {
return;
}
if (slot == NGX_TIME_SLOTS) {
slot = 0;
} else {
slot++;
}
#if (TIME_T_SIZE > SIG_ATOMIC_T_SIZE)
ngx_cached_time = &cached_time[slot];
#endif
ngx_cached_time = s;
#endif
ngx_gmtime(ngx_cached_time, &ngx_cached_gmtime);
ngx_time() = s;
ngx_gmtime(s, &ngx_cached_gmtime);
if (ngx_cached_http_time.data == cached_http_time0) {
p = cached_http_time1;
} else {
p = cached_http_time0;
}
p = cached_http_time[slot];
ngx_snprintf((char *) p, sizeof("Mon, 28 Sep 1970 06:00:00 GMT"),
"%s, %02d %s %4d %02d:%02d:%02d GMT",
@ -126,7 +161,7 @@ void ngx_time_update(time_t s)
#if (HAVE_GETTIMEZONE)
ngx_gmtoff = ngx_gettimezone();
ngx_gmtime(ngx_cached_time + ngx_gmtoff * 60, &tm);
ngx_gmtime(s + ngx_gmtoff * 60, &tm);
#elif (HAVE_GMTOFF)
@ -141,11 +176,7 @@ void ngx_time_update(time_t s)
#endif
if (ngx_cached_err_log_time.data == cached_err_log_time0) {
p = cached_err_log_time1;
} else {
p = cached_err_log_time0;
}
p = cached_err_log_time[slot];
ngx_snprintf((char *) p, sizeof("1970/09/28 12:00:00"),
"%4d/%02d/%02d %02d:%02d:%02d",
@ -156,11 +187,7 @@ void ngx_time_update(time_t s)
ngx_cached_err_log_time.data = p;
if (ngx_cached_http_log_time.data == cached_http_log_time0) {
p = cached_http_log_time1;
} else {
p = cached_http_log_time0;
}
p = cached_http_log_time[slot];
ngx_snprintf((char *) p, sizeof("28/Sep/1970:12:00:00 +0600"),
"%02d/%s/%d:%02d:%02d:%02d %c%02d%02d",

View File

@ -7,17 +7,27 @@
void ngx_time_init();
#if (NGX_THREADS)
ngx_int_t ngx_time_mutex_init(ngx_log_t *log);
#endif
void ngx_time_update(time_t s);
size_t ngx_http_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);
#define ngx_time() ngx_cached_time
#if (NGX_THREADS)
ngx_int_t ngx_time_mutex_init(ngx_log_t *log);
#endif
#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
#define ngx_time() *ngx_cached_time
extern volatile time_t *ngx_cached_time;
#else
#define ngx_time() ngx_cached_time
extern volatile time_t ngx_cached_time;
#endif
extern volatile ngx_str_t ngx_cached_err_log_time;
extern volatile ngx_str_t ngx_cached_http_time;
extern volatile ngx_str_t ngx_cached_http_log_time;

View File

@ -582,14 +582,17 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
ngx_mutex_unlock(ngx_posted_events_mutex);
}
/* TODO: wake up worker thread */
if (expire && delta) {
ngx_event_expire_timers((ngx_msec_t) delta);
}
if (!ngx_threaded) {
ngx_event_process_posted(cycle);
if (ngx_posted_events) {
if (ngx_threaded) {
ngx_cv_signal(ngx_posted_events_cv);
} else {
ngx_event_process_posted(cycle);
}
}
return NGX_OK;

View File

@ -265,6 +265,9 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
for (i = 0; i < cycle->connection_n; i++) {
c[i].fd = (ngx_socket_t) -1;
c[i].data = NULL;
#if (NGX_THREADS)
c[i].lock = 0;
#endif
}
cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,

View File

@ -154,6 +154,11 @@ struct ngx_event_s {
#endif
#if (NGX_THREADS)
ngx_atomic_t *lock;
#endif
#if 0
/* the threads support */

View File

@ -278,6 +278,11 @@ void ngx_event_accept(ngx_event_t *ev)
c->number = ngx_atomic_inc(ngx_connection_counter);
#if (NGX_THREADS)
rev->lock = &c->lock;
wev->lock = &c->lock;
#endif
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"accept: fd:%d c:%d", s, c->number);

View File

@ -5,8 +5,10 @@
ngx_thread_volatile ngx_event_t *ngx_posted_events;
#if (NGX_THREADS)
ngx_mutex_t *ngx_posted_events_mutex;
ngx_cv_t *ngx_posted_events_cv;
#endif
@ -55,26 +57,70 @@ void ngx_event_process_posted(ngx_cycle_t *cycle)
#if (NGX_THREADS)
void ngx_event_thread_handler(ngx_event_t *ev)
ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle)
{
if ((!ev->posted && !ev->active)
|| (ev->use_instance && ev->instance != ev->returned_instance))
{
/*
* the stale event from a file descriptor
* that was just closed in this iteration
*/
ngx_event_t *ev, **ep;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent: stale event " PTR_FMT, ev);
return;
for ( ;; ) {
ev = (ngx_event_t *) ngx_posted_events;
ep = (ngx_event_t **) &ngx_posted_events;
for ( ;; ) {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"posted event " PTR_FMT, ev);
if (ev == NULL) {
ngx_mutex_unlock(ngx_posted_events_mutex);
return NGX_OK;
}
if (ngx_trylock(ev->lock) == NGX_BUSY) {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"posted event " PTR_FMT " is busy", ev);
ep = &ev->next;
ev = ev->next;
continue;
}
*ep = ev->next;
if ((!ev->posted && !ev->active)
|| (ev->use_instance && ev->instance != ev->returned_instance))
{
/*
* the stale event from a file descriptor
* that was just closed in this iteration
*/
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent: stale event " PTR_FMT, ev);
ev = ev->next;
continue;
}
ngx_mutex_unlock(ngx_posted_events_mutex);
if (ev->posted) {
ev->posted = 0;
}
ev->event_handler(ev);
*(ev->lock) = 0;
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
return NGX_ERROR;
}
break;
}
}
if (ev->posted) {
ev->posted = 0;
}
ev->event_handler(ev);
}
#endif

View File

@ -14,14 +14,15 @@
void ngx_event_process_posted(ngx_cycle_t *cycle);
#if (NGX_THREADS)
void ngx_event_thread_handler(ngx_event_t *ev);
#endif
extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
#if (NGX_THREADS)
ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle);
extern ngx_mutex_t *ngx_posted_events_mutex;
extern ngx_cv_t *ngx_posted_events_cv;
#endif

View File

@ -351,7 +351,7 @@ static ngx_int_t ngx_http_gzip_proxied(ngx_http_request_t *r,
}
} else {
date = ngx_cached_time;
date = ngx_time();
}
if (expires < date) {

View File

@ -118,24 +118,22 @@ static ngx_int_t ngx_http_headers_filter(ngx_http_request_t *r)
cc->value.data = (u_char *) "max-age=0";
} else {
ngx_http_time(expires->value.data,
ngx_cached_time + conf->expires);
ngx_http_time(expires->value.data, ngx_time() + conf->expires);
if (conf->expires < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
} else {
cc->value.data = ngx_palloc(r->pool, NGX_TIME_T_LEN + 1);
cc->value.data = ngx_palloc(r->pool, TIME_T_LEN + 1);
if (cc->value.data == NULL) {
return NGX_ERROR;
}
cc->value.len = ngx_snprintf((char *) cc->value.data,
sizeof("max-age=")
+ NGX_TIME_T_LEN,
"max-age=" TIME_T_FMT,
conf->expires);
sizeof("max-age=") + TIME_T_LEN,
"max-age=" TIME_T_FMT,
conf->expires);
}
}
}

View File

@ -708,7 +708,7 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
*buf++ = '-';
} else {
buf += ngx_snprintf((char *) buf, NGX_TIME_T_LEN,
buf += ngx_snprintf((char *) buf, TIME_T_LEN,
TIME_T_FMT, p->state->expired);
}
@ -718,7 +718,7 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
*buf++ = '-';
} else {
buf += ngx_snprintf((char *) buf, NGX_TIME_T_LEN,
buf += ngx_snprintf((char *) buf, TIME_T_LEN,
TIME_T_FMT, p->state->bl_time);
}
@ -752,7 +752,7 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
*buf++ = '-';
} else {
buf += ngx_snprintf((char *) buf, NGX_TIME_T_LEN,
buf += ngx_snprintf((char *) buf, TIME_T_LEN,
TIME_T_FMT, p->state->expires);
}

View File

@ -1463,7 +1463,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r)
rev = c->read;
rev->event_handler = ngx_http_lingering_close_handler;
r->lingering_time = ngx_cached_time + clcf->lingering_time / 1000;
r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
ngx_add_timer(rev, clcf->lingering_timeout);
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
@ -1526,7 +1526,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev)
return;
}
timer = r->lingering_time - ngx_cached_time;
timer = r->lingering_time - ngx_time();
if (timer <= 0) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);

View File

@ -108,14 +108,9 @@ pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg);
#endif
/* STUB: autoconf */
#define ngx_setproctitle setproctitle
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
extern char *malloc_options;

View File

@ -8,26 +8,28 @@
#include <ngx_core.h>
/*
* The threads implementation uses the rfork(RFPROC|RFTHREAD|RFMEM)
* The threads implementation uses the rfork(RFPROC|RFTHREAD|RFMEM) syscall
* to create threads. All threads use the stacks of the same size mmap()ed
* below the main stack. Thus the stack pointer is used to determine
* the current thread id.
* below the main stack. Thus the current thread id is determinated through
* the stack pointer.
*
* The mutex implementation uses the ngx_atomic_cmp_set() operation
* to acquire mutex and the SysV semaphore to wait on a mutex or to wake up
* the waiting threads.
* to acquire a mutex and the SysV semaphore to wait on a mutex or to wake up
* the waiting threads. The light mutex does not use semaphore, so after
* spinning in the lock the thread calls sched_yield(). However the light
* mutecies are intended to be used with the "trylock" operation only.
*
* 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.
* by the CV to signal.
*
* This threads implementation currently works on i486 and amd64
* This threads implementation currently works on i386 (486+) and amd64
* platforms only.
*/
char *ngx_freebsd_kern_usrstack;
size_t ngx_thread_stack_size;
char *ngx_freebsd_kern_usrstack;
size_t ngx_thread_stack_size;
static size_t rz_size;
@ -261,7 +263,6 @@ ngx_tid_t ngx_thread_self()
ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags)
{
int nsem, i;
ngx_mutex_t *m;
union semun op;
@ -277,27 +278,23 @@ ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags)
return m;
}
nsem = flags & NGX_MUTEX_CV ? 2 : 1;
m->semid = semget(IPC_PRIVATE, nsem, SEM_R|SEM_A);
m->semid = semget(IPC_PRIVATE, 1, SEM_R|SEM_A);
if (m->semid == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed");
return NULL;
}
op.val = 0;
for (i = 0; i < nsem; i++) {
if (semctl(m->semid, i, SETVAL, op) == -1) {
if (semctl(m->semid, 0, SETVAL, op) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semctl(SETVAL) failed");
if (semctl(m->semid, 0, IPC_RMID) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"semctl(SETVAL) failed");
if (semctl(m->semid, 0, IPC_RMID) == -1) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
"semctl(IPC_RMID) failed");
}
return NULL;
"semctl(IPC_RMID) failed");
}
return NULL;
}
return m;
@ -388,7 +385,7 @@ ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try)
* The number of the waiting threads has been increased
* and we would wait on the SysV semaphore.
* A semaphore should wake up us more efficiently than
* a simple usleep().
* a simple sched_yield() or usleep().
*/
op.sem_num = 0;
@ -456,7 +453,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, 0,
"tring to unlock the free mutex " PTR_FMT, m);
"trying to unlock the free mutex " PTR_FMT, m);
return NGX_ERROR;
}
@ -479,7 +476,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
return NGX_OK;
}
/* check weather we need to wake up a waiting thread */
/* check whether we need to wake up a waiting thread */
old = m->lock;
@ -525,3 +522,108 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
return NGX_OK;
}
ngx_cv_t *ngx_cv_init(ngx_log_t *log)
{
ngx_cv_t *cv;
u_short val[2];
union semun op;
if (!(cv = ngx_alloc(sizeof(ngx_cv_t), log))) {
return NULL;
}
cv->mutex.lock = 0;
cv->mutex.log = log;
cv->mutex.semid = semget(IPC_PRIVATE, 2, SEM_R|SEM_A);
if (cv->mutex.semid == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed");
return NULL;
}
val[0] = 0;
val[1] = 0;
op.array = val;
if (semctl(cv->mutex.semid, 0, SETALL, op) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semctl(SETALL) failed");
if (semctl(cv->mutex.semid, 0, IPC_RMID) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"semctl(IPC_RMID) failed");
}
return NULL;
}
return cv;
}
void ngx_cv_done(ngx_cv_t *cv)
{
if (semctl(cv->mutex.semid, 0, IPC_RMID) == -1) {
ngx_log_error(NGX_LOG_ALERT, cv->mutex.log, ngx_errno,
"semctl(IPC_RMID) failed");
}
ngx_free(cv);
}
ngx_int_t ngx_cv_wait(ngx_cv_t *cv)
{
struct sembuf op[2];
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->mutex.log, 0,
"cv " PTR_FMT " wait", cv);
op[0].sem_num = 0;
op[0].sem_op = -1;
op[0].sem_flg = SEM_UNDO;
op[1].sem_num = 1;
op[1].sem_op = -1;
op[1].sem_flg = SEM_UNDO;
if (semop(cv->mutex.semid, op, 2) == -1) {
ngx_log_error(NGX_LOG_ALERT, cv->mutex.log, ngx_errno,
"semop() failed while waiting on cv " PTR_FMT, cv);
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->mutex.log, 0,
"cv " PTR_FMT " is waked up", cv);
return NGX_OK;
}
ngx_int_t ngx_cv_signal(ngx_cv_t *cv)
{
struct sembuf op[2];
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->mutex.log, 0,
"cv " PTR_FMT " to signal", cv);
op[0].sem_num = 0;
op[0].sem_op = 1;
op[0].sem_flg = SEM_UNDO;
op[1].sem_num = 1;
op[1].sem_op = 1;
op[1].sem_flg = SEM_UNDO;
if (semop(cv->mutex.semid, op, 2) == -1) {
ngx_log_error(NGX_LOG_ALERT, cv->mutex.log, ngx_errno,
"semop() failed while signaling cv " PTR_FMT, cv);
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->mutex.log, 0,
"cv " PTR_FMT " is signaled", cv);
return NGX_OK;
}

View File

@ -91,8 +91,4 @@ extern ssize_t sendfile(int s, int fd, int32_t *offset, size_t size);
#define ngx_setproctitle(title)
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */

View File

@ -625,6 +625,13 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
exit(2);
}
if (!(ngx_posted_events_cv = ngx_cv_init(cycle->log))) {
/* fatal */
exit(2);
}
ngx_posted_events_mutex = &ngx_posted_events_cv->mutex;
for (i = 0; i < 1; i++) {
if (ngx_create_thread(&tid, ngx_worker_thread_cycle,
cycle, cycle->log) != 0)
@ -767,23 +774,25 @@ int ngx_worker_thread_cycle(void *data)
return 1;
}
/* STUB */
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
"thread %d started", ngx_thread_self());
ngx_setproctitle("worker thread");
sleep(5);
for ( ;; ) {
if (ngx_cv_wait(ngx_posted_events_cv) == NGX_ERROR) {
return 1;
}
ngx_gettimeofday(&tv);
ngx_time_update(tv.tv_sec);
if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
return 1;
}
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
"thread %d done", ngx_thread_self());
return 1;
return 0;
}
#endif

View File

@ -76,8 +76,4 @@
#define ngx_setproctitle(title)
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
#endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */

View File

@ -36,6 +36,11 @@ typedef volatile struct {
} ngx_mutex_t;
typedef struct {
ngx_mutex_t mutex;
} ngx_cv_t;
#define ngx_thread_sigmask(how, set, oset) \
(sigprocmask(how, set, oset) == -1) ? ngx_errno : 0
@ -102,6 +107,12 @@ ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try);
ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m);
ngx_cv_t *ngx_cv_init(ngx_log_t *log);
void ngx_cv_done(ngx_cv_t *cv);
ngx_int_t ngx_cv_wait(ngx_cv_t *cv);
ngx_int_t ngx_cv_signal(ngx_cv_t *cv);
#else /* !NGX_THREADS */
#define ngx_thread_volatile

View File

@ -6,13 +6,17 @@
void ngx_localtime(ngx_tm_t *tm)
{
#if (HAVE_LOCALTIME_R)
time_t now;
localtime_r((time_t *) &ngx_cached_time, tm);
now = ngx_time();
localtime_r(&now, tm);
#else
time_t now;
ngx_tm_t *t;
t = localtime((time_t *) &ngx_cached_time);
now = ngx_time();
t = localtime(&now);
*tm = *t;
#endif