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 cat << END > $NGX_AUTOTEST.c
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h>
#include <sys/resource.h> #include <sys/resource.h>
$NGX_INTTYPES_H $NGX_INTTYPES_H
$NGX_AUTO_CONFIG $NGX_AUTO_CONFIG
int main() { int main() {
printf("$fmt", ($ngx_type) $ngx_max_size); printf("$fmt", ($ngx_type) $ngx_max_value);
return 0; return 0;
} }
@ -28,10 +28,10 @@ END
eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \ eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \
>> $NGX_ERR 2>&1" >> $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 [ -x $NGX_AUTOTEST ]; then
if [ "`$NGX_AUTOTEST`" = $max_size ]; then if [ "`$NGX_AUTOTEST`" = $max_value ]; then
if [ $ngx_fmt_collect = yes ]; then if [ $ngx_fmt_collect = yes ]; then
echo $ngx_n "$comma \"${fmt}\" is appropriate" $ngx_c echo $ngx_n "$comma \"${fmt}\" is appropriate" $ngx_c
else else
@ -45,7 +45,7 @@ END
if [ $ngx_fmt != no ]; then if [ $ngx_fmt != no ]; then
if [ $ngx_fmt_collect = yes ]; 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="," comma=","
continue continue
else else

View File

@ -13,7 +13,7 @@ do
cat << END > $NGX_AUTOTEST.c cat << END > $NGX_AUTOTEST.c
int main() { int main() {
printf("$fmt", ($ngx_type) $ngx_max_size); printf("$fmt", ($ngx_type) $ngx_max_value);
return 0; return 0;
} }
@ -22,10 +22,10 @@ END
eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \ eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \
>> $NGX_ERR 2>&1" >> $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 [ -x $NGX_AUTOTEST ]; then
if [ "`$NGX_AUTOTEST`" = $max_size ]; then if [ "`$NGX_AUTOTEST`" = $max_value ]; then
ngx_fmt=$fmt ngx_fmt=$fmt
fi fi
fi fi
@ -49,8 +49,8 @@ if [ $ngx_fmt = no ]; then
fi fi
if [ $ngx_ptr_bytes = 4 ]; then if [ $ngx_ptr_size = 4 ]; then
fmtX="%0`expr 2 \* $ngx_ptr_bytes`" fmtX="%0`expr 2 \* $ngx_ptr_size`"
else else
fmtX="%" fmtX="%"
fi 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 >> $NGX_ERR
echo "checking for $ngx_type size" >> $NGX_ERR echo "checking for $ngx_type size" >> $NGX_ERR
ngx_bytes= ngx_size=
cat << END > $NGX_AUTOTEST.c cat << END > $NGX_AUTOTEST.c
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h>
$NGX_UNISTD_H $NGX_UNISTD_H
#include <signal.h>
#include <sys/resource.h>
$NGX_INTTYPES_H $NGX_INTTYPES_H
$NGX_AUTO_CONFIG $NGX_AUTO_CONFIG
@ -24,27 +25,31 @@ END
eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1" eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then if [ -x $NGX_AUTOTEST ]; then
ngx_bytes=`$NGX_AUTOTEST` ngx_size=`$NGX_AUTOTEST`
echo " $ngx_bytes bytes" echo " $ngx_size bytes"
fi fi
rm $NGX_AUTOTEST* rm $NGX_AUTOTEST*
case $ngx_bytes in case $ngx_size in
4) 4)
if [ "$ngx_type"="long" ]; then if [ "$ngx_type"="long" ]; then
ngx_max_size=2147483647L ngx_max_value=2147483647L
else else
ngx_max_size=2147483647 ngx_max_value=2147483647
fi fi
ngx_max_len='sizeof("-2147483648") - 1'
;; ;;
8) 8)
if [ "$ngx_type"="long long" ]; then if [ "$ngx_type"="long long" ]; then
ngx_max_size=9223372036854775807LL ngx_max_value=9223372036854775807LL
else else
ngx_max_size=9223372036854775807L ngx_max_value=9223372036854775807L
fi fi
ngx_max_len='sizeof("-9223372036854775808") - 1'
;; ;;
*) *)

View File

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

View File

@ -30,7 +30,7 @@ rm $NGX_AUTOTEST*
if [ $found = no ]; then if [ $found = no ]; then
found="uint`expr 8 \* $ngx_ptr_bytes`_t" found="uint`expr 8 \* $ngx_ptr_size`_t"
echo ", $found used" echo ", $found used"
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H 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_type="long long"; . auto/types/sizeof
ngx_formats="%lld %qd"; . auto/fmt/fmt 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; 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 # POSIX types
NGX_AUTO_CONFIG="#include \"../$NGX_AUTO_CONFIG_H\"" NGX_AUTO_CONFIG="#include \"../$NGX_AUTO_CONFIG_H\""
ngx_type="uint64_t" ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef
ngx_types="u_int64_t"; . auto/types/typedef
ngx_type="sig_atomic_t" ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef
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_type="socklen_t"; ngx_types="uint32_t"; . auto/types/typedef
ngx_types="uint32_t"; . auto/types/typedef
ngx_type="in_addr_t" ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef
ngx_types="uint32_t"; . auto/types/typedef
ngx_type="rlim_t" ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
ngx_types="int"; . auto/types/typedef
. auto/types/uintptr_t . auto/types/uintptr_t
. auto/endianess
# printf() formats # printf() formats
@ -46,22 +45,24 @@ CC_WARN=$CC_STRONG
ngx_fmt_collect=no ngx_fmt_collect=no
ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof
ngx_type_max_value=OFF_T_MAX_VALUE; . auto/types/maxvalue ngx_param=OFF_T_MAX_VALUE; ngx_value=$ngx_max_value; . auto/types/value
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt eval ngx_formats=\${ngx_${ngx_size}_fmt}; . auto/fmt/fmt
ngx_fmt_name=TIME_T_FMT; ngx_type="time_t"; . auto/types/sizeof 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 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=SIZE_T_X_FMT; . auto/fmt/xfmt
ngx_fmt_name=PID_T_FMT; ngx_type="pid_t"; . auto/types/sizeof 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 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 # syscalls, libc calls and some features

View File

@ -93,4 +93,18 @@ typedef volatile uint32_t ngx_atomic_t;
#endif #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_ */ #endif /* _NGX_ATOMIC_H_INCLUDED_ */

View File

@ -75,10 +75,6 @@ typedef long ngx_flag_t;
/* TODO: auto */ /* TODO: auto */
#define NGX_INT32_LEN sizeof("-2147483648") - 1 #define NGX_INT32_LEN sizeof("-2147483648") - 1
#define NGX_INT64_LEN sizeof("-9223372036854775808") - 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 #define NGX_OFF_T_LEN sizeof("-9223372036854775808") - 1

View File

@ -108,6 +108,10 @@ struct ngx_connection_s {
#if (HAVE_IOCP) #if (HAVE_IOCP)
unsigned accept_context_updated:1; unsigned accept_context_updated:1;
#endif #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; 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_atomic.h>
#include <ngx_time.h> #include <ngx_time.h>
#include <ngx_socket.h> #include <ngx_socket.h>
@ -49,16 +58,6 @@ typedef struct ngx_connection_s ngx_connection_t;
#include <ngx_connection.h> #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 LF (u_char) 10
#define CR (u_char) 13 #define CR (u_char) 13
#define CRLF "\x0d\x0a" #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". * 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; return NGX_OK;
} }

View File

@ -3,32 +3,62 @@
#include <ngx_core.h> #include <ngx_core.h>
#if (NGX_THREADS)
static ngx_mutex_t *ngx_time_mutex;
#endif
ngx_epoch_msec_t ngx_elapsed_msec; ngx_epoch_msec_t ngx_elapsed_msec;
ngx_epoch_msec_t ngx_old_elapsed_msec; ngx_epoch_msec_t ngx_old_elapsed_msec;
ngx_epoch_msec_t ngx_start_msec; ngx_epoch_msec_t ngx_start_msec;
volatile time_t ngx_cached_time;
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;
static ngx_tm_t ngx_cached_gmtime; static ngx_tm_t ngx_cached_gmtime;
static ngx_int_t ngx_gmtoff; static ngx_int_t ngx_gmtoff;
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";
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"; * 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.
*/
static u_char cached_http_log_time0[] = "28/Sep/1970:12:00:00 +0600"; #if (NGX_THREADS)
static u_char cached_http_log_time1[] = "28/Sep/1970:12:00:00 +0600";
#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
#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
volatile time_t *ngx_cached_time;
static time_t cached_time[NGX_TIME_SLOTS];
#else
volatile time_t ngx_cached_time;
#endif
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" }; 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"; ngx_cached_gmtime.ngx_tm_zone = "GMT";
#endif #endif
ngx_cached_err_log_time.len = sizeof(cached_err_log_time0) - 1; ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
ngx_cached_err_log_time.data = cached_err_log_time0; 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; #if (TIME_T_SIZE > SIG_ATOMIC_T_SIZE)
ngx_cached_http_time.data = cached_http_time0; ngx_cached_time = &cached_time[0];
#endif
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;
ngx_gettimeofday(&tv); ngx_gettimeofday(&tv);
@ -89,26 +116,34 @@ void ngx_time_update(time_t s)
u_char *p; u_char *p;
ngx_tm_t tm; ngx_tm_t tm;
if (ngx_cached_time == s) { if (ngx_time() == s) {
return; return;
} }
#if (NGX_THREADS) #if (NGX_THREADS)
if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) { if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) {
return; 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 #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_time[slot];
p = cached_http_time1;
} else {
p = cached_http_time0;
}
ngx_snprintf((char *) p, sizeof("Mon, 28 Sep 1970 06:00:00 GMT"), ngx_snprintf((char *) p, sizeof("Mon, 28 Sep 1970 06:00:00 GMT"),
"%s, %02d %s %4d %02d:%02d:%02d GMT", "%s, %02d %s %4d %02d:%02d:%02d GMT",
@ -126,7 +161,7 @@ void ngx_time_update(time_t s)
#if (HAVE_GETTIMEZONE) #if (HAVE_GETTIMEZONE)
ngx_gmtoff = ngx_gettimezone(); ngx_gmtoff = ngx_gettimezone();
ngx_gmtime(ngx_cached_time + ngx_gmtoff * 60, &tm); ngx_gmtime(s + ngx_gmtoff * 60, &tm);
#elif (HAVE_GMTOFF) #elif (HAVE_GMTOFF)
@ -141,11 +176,7 @@ void ngx_time_update(time_t s)
#endif #endif
if (ngx_cached_err_log_time.data == cached_err_log_time0) { p = cached_err_log_time[slot];
p = cached_err_log_time1;
} else {
p = cached_err_log_time0;
}
ngx_snprintf((char *) p, sizeof("1970/09/28 12:00:00"), ngx_snprintf((char *) p, sizeof("1970/09/28 12:00:00"),
"%4d/%02d/%02d %02d:%02d:%02d", "%4d/%02d/%02d %02d:%02d:%02d",
@ -156,11 +187,7 @@ void ngx_time_update(time_t s)
ngx_cached_err_log_time.data = p; ngx_cached_err_log_time.data = p;
if (ngx_cached_http_log_time.data == cached_http_log_time0) { p = cached_http_log_time[slot];
p = cached_http_log_time1;
} else {
p = cached_http_log_time0;
}
ngx_snprintf((char *) p, sizeof("28/Sep/1970:12:00:00 +0600"), ngx_snprintf((char *) p, sizeof("28/Sep/1970:12:00:00 +0600"),
"%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d",

View File

@ -7,17 +7,27 @@
void ngx_time_init(); 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); void ngx_time_update(time_t s);
size_t ngx_http_time(u_char *buf, time_t t); size_t ngx_http_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp); void ngx_gmtime(time_t t, ngx_tm_t *tp);
#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 #define ngx_time() ngx_cached_time
extern volatile time_t 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_err_log_time;
extern volatile ngx_str_t ngx_cached_http_time; extern volatile ngx_str_t ngx_cached_http_time;
extern volatile ngx_str_t ngx_cached_http_log_time; extern volatile ngx_str_t ngx_cached_http_log_time;

View File

@ -582,15 +582,18 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
ngx_mutex_unlock(ngx_posted_events_mutex); ngx_mutex_unlock(ngx_posted_events_mutex);
} }
/* TODO: wake up worker thread */
if (expire && delta) { if (expire && delta) {
ngx_event_expire_timers((ngx_msec_t) delta); ngx_event_expire_timers((ngx_msec_t) delta);
} }
if (!ngx_threaded) { if (ngx_posted_events) {
if (ngx_threaded) {
ngx_cv_signal(ngx_posted_events_cv);
} else {
ngx_event_process_posted(cycle); ngx_event_process_posted(cycle);
} }
}
return NGX_OK; 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++) { for (i = 0; i < cycle->connection_n; i++) {
c[i].fd = (ngx_socket_t) -1; c[i].fd = (ngx_socket_t) -1;
c[i].data = NULL; c[i].data = NULL;
#if (NGX_THREADS)
c[i].lock = 0;
#endif
} }
cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,

View File

@ -154,6 +154,11 @@ struct ngx_event_s {
#endif #endif
#if (NGX_THREADS)
ngx_atomic_t *lock;
#endif
#if 0 #if 0
/* the threads support */ /* 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); 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, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"accept: fd:%d c:%d", s, c->number); "accept: fd:%d c:%d", s, c->number);

View File

@ -5,8 +5,10 @@
ngx_thread_volatile ngx_event_t *ngx_posted_events; ngx_thread_volatile ngx_event_t *ngx_posted_events;
#if (NGX_THREADS) #if (NGX_THREADS)
ngx_mutex_t *ngx_posted_events_mutex; ngx_mutex_t *ngx_posted_events_mutex;
ngx_cv_t *ngx_posted_events_cv;
#endif #endif
@ -55,8 +57,37 @@ void ngx_event_process_posted(ngx_cycle_t *cycle)
#if (NGX_THREADS) #if (NGX_THREADS)
void ngx_event_thread_handler(ngx_event_t *ev) ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle)
{ {
ngx_event_t *ev, **ep;
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) if ((!ev->posted && !ev->active)
|| (ev->use_instance && ev->instance != ev->returned_instance)) || (ev->use_instance && ev->instance != ev->returned_instance))
{ {
@ -67,14 +98,29 @@ void ngx_event_thread_handler(ngx_event_t *ev)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent: stale event " PTR_FMT, ev); "kevent: stale event " PTR_FMT, ev);
return;
ev = ev->next;
continue;
} }
ngx_mutex_unlock(ngx_posted_events_mutex);
if (ev->posted) { if (ev->posted) {
ev->posted = 0; ev->posted = 0;
} }
ev->event_handler(ev); ev->event_handler(ev);
*(ev->lock) = 0;
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
return NGX_ERROR;
}
break;
}
}
} }
#endif #endif

View File

@ -14,14 +14,15 @@
void ngx_event_process_posted(ngx_cycle_t *cycle); 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; extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
#if (NGX_THREADS) #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_mutex_t *ngx_posted_events_mutex;
extern ngx_cv_t *ngx_posted_events_cv;
#endif #endif

View File

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

View File

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

View File

@ -708,7 +708,7 @@ static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
*buf++ = '-'; *buf++ = '-';
} else { } else {
buf += ngx_snprintf((char *) buf, NGX_TIME_T_LEN, buf += ngx_snprintf((char *) buf, TIME_T_LEN,
TIME_T_FMT, p->state->expired); 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++ = '-'; *buf++ = '-';
} else { } 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); 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++ = '-'; *buf++ = '-';
} else { } else {
buf += ngx_snprintf((char *) buf, NGX_TIME_T_LEN, buf += ngx_snprintf((char *) buf, TIME_T_LEN,
TIME_T_FMT, p->state->expires); 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 = c->read;
rev->event_handler = ngx_http_lingering_close_handler; 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); ngx_add_timer(rev, clcf->lingering_timeout);
if (ngx_handle_level_read_event(rev) == NGX_ERROR) { 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; return;
} }
timer = r->lingering_time - ngx_cached_time; timer = r->lingering_time - ngx_time();
if (timer <= 0) { if (timer <= 0) {
ngx_http_close_request(r, 0); ngx_http_close_request(r, 0);
ngx_http_close_connection(c); 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 #endif
/* STUB: autoconf */
#define ngx_setproctitle setproctitle #define ngx_setproctitle setproctitle
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
extern char *malloc_options; extern char *malloc_options;

View File

@ -8,20 +8,22 @@
#include <ngx_core.h> #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 * 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 * below the main stack. Thus the current thread id is determinated through
* the current thread id. * the stack pointer.
* *
* The mutex implementation uses the ngx_atomic_cmp_set() operation * 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 * to acquire a mutex and the SysV semaphore to wait on a mutex or to wake up
* the waiting threads. * 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 * 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 * 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. * platforms only.
*/ */
@ -261,7 +263,6 @@ ngx_tid_t ngx_thread_self()
ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags) ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags)
{ {
int nsem, i;
ngx_mutex_t *m; ngx_mutex_t *m;
union semun op; union semun op;
@ -277,28 +278,24 @@ ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, uint flags)
return m; return m;
} }
nsem = flags & NGX_MUTEX_CV ? 2 : 1; m->semid = semget(IPC_PRIVATE, 1, SEM_R|SEM_A);
m->semid = semget(IPC_PRIVATE, nsem, SEM_R|SEM_A);
if (m->semid == -1) { if (m->semid == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed"); ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed");
return NULL; return NULL;
} }
op.val = 0; 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, ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semctl(SETVAL) failed");
"semctl(SETVAL) failed");
if (semctl(m->semid, 0, IPC_RMID) == -1) { if (semctl(m->semid, 0, IPC_RMID) == -1) {
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno, ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"semctl(IPC_RMID) failed"); "semctl(IPC_RMID) failed");
} }
return NULL; return NULL;
} }
}
return m; 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 * The number of the waiting threads has been increased
* and we would wait on the SysV semaphore. * and we would wait on the SysV semaphore.
* A semaphore should wake up us more efficiently than * A semaphore should wake up us more efficiently than
* a simple usleep(). * a simple sched_yield() or usleep().
*/ */
op.sem_num = 0; op.sem_num = 0;
@ -456,7 +453,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
if (!(old & NGX_MUTEX_LOCK_BUSY)) { if (!(old & NGX_MUTEX_LOCK_BUSY)) {
ngx_log_error(NGX_LOG_ALERT, m->log, 0, 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; return NGX_ERROR;
} }
@ -479,7 +476,7 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
return NGX_OK; 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; old = m->lock;
@ -525,3 +522,108 @@ ngx_int_t ngx_mutex_unlock(ngx_mutex_t *m)
return NGX_OK; 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) #define ngx_setproctitle(title)
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */ #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); 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++) { for (i = 0; i < 1; i++) {
if (ngx_create_thread(&tid, ngx_worker_thread_cycle, if (ngx_create_thread(&tid, ngx_worker_thread_cycle,
cycle, cycle->log) != 0) cycle, cycle->log) != 0)
@ -767,23 +774,25 @@ int ngx_worker_thread_cycle(void *data)
return 1; return 1;
} }
/* STUB */
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno, ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
"thread %d started", ngx_thread_self()); "thread %d started", ngx_thread_self());
ngx_setproctitle("worker thread"); ngx_setproctitle("worker thread");
sleep(5); for ( ;; ) {
if (ngx_cv_wait(ngx_posted_events_cv) == NGX_ERROR) {
return 1;
}
ngx_gettimeofday(&tv); if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
ngx_time_update(tv.tv_sec); return 1;
}
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno, ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, ngx_errno,
"thread %d done", ngx_thread_self()); "thread %d done", ngx_thread_self());
return 1; return 0;
} }
#endif #endif

View File

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

View File

@ -36,6 +36,11 @@ typedef volatile struct {
} ngx_mutex_t; } ngx_mutex_t;
typedef struct {
ngx_mutex_t mutex;
} ngx_cv_t;
#define ngx_thread_sigmask(how, set, oset) \ #define ngx_thread_sigmask(how, set, oset) \
(sigprocmask(how, set, oset) == -1) ? ngx_errno : 0 (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_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 */ #else /* !NGX_THREADS */
#define ngx_thread_volatile #define ngx_thread_volatile

View File

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