nginx-0.0.1-2003-12-04-17:53:00 import

This commit is contained in:
Igor Sysoev 2003-12-04 14:53:00 +00:00
parent 7adb8c0e8f
commit f5003d8a66
13 changed files with 498 additions and 31 deletions

View File

@ -16,6 +16,7 @@ CORE_DEPS="src/core/nginx.h \
src/core/ngx_file.h \
src/core/ngx_crc.h \
src/core/ngx_regex.h \
src/core/ngx_rbtree.h \
src/core/ngx_times.h \
src/core/ngx_connection.h \
src/core/ngx_conf_file.h \
@ -32,6 +33,7 @@ CORE_SRCS="src/core/nginx.c \
src/core/ngx_inet.c \
src/core/ngx_file.c \
src/core/ngx_regex.c \
src/core/ngx_rbtree.c \
src/core/ngx_times.c \
src/core/ngx_conf_file.c \
src/core/ngx_garbage_collector.c"

View File

@ -30,6 +30,7 @@ typedef struct ngx_connection_s ngx_connection_t;
#include <ngx_files.h>
#include <ngx_crc.h>
#include <ngx_regex.h>
#include <ngx_rbtree.h>
#include <ngx_times.h>
#include <ngx_inet.h>
#include <ngx_conf_file.h>

296
src/core/ngx_rbtree.c Normal file
View File

@ -0,0 +1,296 @@
#include <ngx_config.h>
#include <ngx_core.h>
/*
* The code is based on the algorithm described in the "Introduction
* to Algorithms" by Cormen, Leiserson and Rivest.
*/
#define ngx_rbt_red(node) ((uintptr_t) (node)->data |= 1)
#define ngx_rbt_black(node) ((uintptr_t) (node)->data &= ~1)
#define ngx_rbt_is_red(node) ((uintptr_t) (node)->data & 1)
#define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node))
#define ngx_rbt_copy_color(n1, n2) \
((uintptr_t) (n1)->data |= (uintptr_t) (n2)->data & 1)
ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_t **root, ngx_rbtree_t *node);
ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_t **root,
ngx_rbtree_t *node);
ngx_rbtree_t sentinel;
void ngx_rbtree_insert(ngx_rbtree_t **root, ngx_rbtree_t *node)
{
ngx_rbtree_t *temp;
/* a binary tree insert */
if (*root == &sentinel) {
node->parent = &sentinel;
node->left = &sentinel;
node->right = &sentinel;
ngx_rbt_black(node);
*root = node;
return;
}
temp = *root;
for ( ;; ) {
if (node->key < temp->key) {
if (temp->left == &sentinel) {
temp->left = node;
break;
}
temp = temp->left;
continue;
}
if (temp->right == &sentinel) {
temp->right = node;
break;
}
temp = temp->right;
continue;
}
node->parent = temp;
node->left = &sentinel;
node->right = &sentinel;
/* re-balance tree */
ngx_rbt_red(node);
while (node->parent && ngx_rbt_is_red(node->parent)) {
if (node->parent == node->parent->parent->left) {
temp = node->parent->parent->right;
if (ngx_rbt_is_red(temp)) {
ngx_rbt_black(node->parent);
ngx_rbt_black(temp);
ngx_rbt_red(node->parent->parent);
node = node->parent->parent;
} else {
if (node == node->parent->right) {
node = node->parent;
ngx_rbtree_left_rotate(root, node);
}
ngx_rbt_black(node->parent);
ngx_rbt_red(node->parent->parent);
ngx_rbtree_right_rotate(root, node->parent->parent);
}
} else {
temp = node->parent->parent->left;
if (ngx_rbt_is_red(temp)) {
ngx_rbt_black(node->parent);
ngx_rbt_black(temp);
ngx_rbt_red(node->parent->parent);
node = node->parent->parent;
} else {
if (node == node->parent->left) {
node = node->parent;
ngx_rbtree_right_rotate(root, node);
}
ngx_rbt_black(node->parent);
ngx_rbt_red(node->parent->parent);
ngx_rbtree_left_rotate(root, node->parent->parent);
}
}
}
ngx_rbt_black(*root);
}
void ngx_rbtree_delete(ngx_rbtree_t **root, ngx_rbtree_t *node)
{
ngx_rbtree_t *subst, *temp, *w;
/* a binary tree delete */
if (node->left == &sentinel || node->right == &sentinel) {
subst = node;
} else {
/* find a node successor */
if (node->right == &sentinel) {
temp = node;
subst = node->parent;
while (subst != &sentinel && temp == subst->right) {
temp = subst;
subst = subst->parent;
}
} else {
subst = ngx_rbtree_min(node->right);
}
}
if (subst->left != &sentinel) {
temp = subst->left;
} else {
temp = subst->right;
}
temp->parent = subst->parent;
if (subst->parent == &sentinel) {
*root = temp;
} else if (subst == subst->parent->left) {
subst->parent->left = temp;
} else {
subst->parent->right = temp;
}
if (subst != node) {
node->key = subst->key;
node->data = subst->data;
}
if (ngx_rbt_is_red(subst)) {
return;
}
/* a delete fixup */
while (temp->parent != &sentinel && ngx_rbt_is_black(temp)) {
if (temp == temp->parent->left) {
w = temp->parent->right;
if (ngx_rbt_is_red(w)) {
ngx_rbt_black(w);
ngx_rbt_red(temp->parent);
ngx_rbtree_left_rotate(root, temp->parent);
w = temp->parent->right;
}
if (ngx_rbt_is_black(w->left) && ngx_rbt_is_black(w->right)) {
ngx_rbt_red(w);
temp = temp->parent;
} else {
if (ngx_rbt_is_black(w->right)) {
ngx_rbt_black(w->left);
ngx_rbt_red(w);
ngx_rbtree_right_rotate(root, w);
w = temp->parent->right;
}
ngx_rbt_copy_color(w, temp->parent);
ngx_rbt_black(temp->parent);
ngx_rbt_black(w->right);
ngx_rbtree_left_rotate(root, temp->parent);
temp = *root;
}
} else {
w = temp->parent->left;
if (ngx_rbt_is_red(w)) {
ngx_rbt_black(w);
ngx_rbt_red(temp->parent);
ngx_rbtree_right_rotate(root, temp->parent);
w = temp->parent->left;
}
if (ngx_rbt_is_black(w->right) && ngx_rbt_is_black(w->left)) {
ngx_rbt_red(w);
temp = temp->parent;
} else {
if (ngx_rbt_is_black(w->left)) {
ngx_rbt_black(w->right);
ngx_rbt_red(w);
ngx_rbtree_left_rotate(root, w);
w = temp->parent->left;
}
ngx_rbt_copy_color(w, temp->parent);
ngx_rbt_black(temp->parent);
ngx_rbt_black(w->left);
ngx_rbtree_right_rotate(root, temp->parent);
temp = *root;
}
}
}
ngx_rbt_black(temp);
}
ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_t **root, ngx_rbtree_t *node)
{
ngx_rbtree_t *temp;
temp = node->right;
node->right = temp->left;
if (temp->left != &sentinel) {
temp->left->parent = node;
}
temp->parent = node->parent;
if (node->parent == &sentinel) {
*root = temp;
} else if (node == node->parent->left) {
node->parent->left = temp;
} else {
node->parent->right = temp;
}
temp->left = node;
node->parent = temp;
}
ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_t **root, ngx_rbtree_t *node)
{
ngx_rbtree_t *temp;
temp = node->left;
node->left = temp->right;
if (temp->right != &sentinel) {
temp->right->parent = node;
}
temp->parent = node->parent;
if (node->parent == &sentinel) {
*root = temp;
} else if (node == node->parent->right) {
node->parent->right = temp;
} else {
node->parent->left = temp;
}
temp->right = node;
node->parent = temp;
}

36
src/core/ngx_rbtree.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef _NGX_RBTREE_H_INCLUDED_
#define _NGX_RBTREE_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
typedef struct ngx_rbtree_s ngx_rbtree_t;
struct ngx_rbtree_s {
ngx_int_t key;
ngx_rbtree_t *left;
ngx_rbtree_t *right;
ngx_rbtree_t *parent;
void *data;
};
extern ngx_rbtree_t sentinel;
void ngx_rbtree_insert(ngx_rbtree_t **root, ngx_rbtree_t *node);
void ngx_rbtree_delete(ngx_rbtree_t **root, ngx_rbtree_t *node);
ngx_inline static ngx_rbtree_t *ngx_rbtree_min(ngx_rbtree_t *root)
{
while (root->left != &sentinel) {
root = root->left;
}
return root;
}
#endif /* _NGX_RBTREE_H_INCLUDED_ */

View File

@ -4,6 +4,8 @@
time_t ngx_cached_time;
ngx_epoch_msec_t ngx_elapsed_msec;
ngx_epoch_msec_t ngx_start_msec;
ngx_tm_t ngx_cached_gmtime;
@ -37,6 +39,9 @@ void ngx_time_init()
ngx_gettimeofday(&tv);
ngx_cached_time = tv.tv_sec;
ngx_start_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
ngx_elapsed_msec = 0;
ngx_time_update();
}

View File

@ -15,6 +15,9 @@ void ngx_gmtime(time_t t, ngx_tm_t *tp);
extern time_t ngx_cached_time;
extern ngx_epoch_msec_t ngx_elapsed_msec;
extern ngx_epoch_msec_t ngx_start_msec;
extern ngx_str_t ngx_cached_err_log_time;
extern ngx_str_t ngx_cached_http_time;
extern ngx_str_t ngx_cached_http_log_time;

View File

@ -360,8 +360,10 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
ts.tv_nsec = (timer % 1000) * 1000000;
tp = &ts;
#if 0
ngx_gettimeofday(&tv);
delta = tv.tv_sec * 1000 + tv.tv_usec / 1000;
#endif
} else {
delta = 0;
@ -384,28 +386,31 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
ngx_gettimeofday(&tv);
#if 1
delta = ngx_elapsed_msec;
#endif
ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec;
if (ngx_cached_time != tv.tv_sec) {
ngx_cached_time = tv.tv_sec;
ngx_time_update();
}
if (timer) {
delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
#if (NGX_DEBUG_EVENT)
ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta);
#endif
delta = ngx_elapsed_msec - delta;
#if 0
delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
/*
* The expired timers must be handled before a processing of the events
* because the new timers can be added during a processing
*/
ngx_event_expire_timers((ngx_msec_t) delta);
#endif
ngx_event_set_timer_delta((ngx_msec_t) delta);
#endif
} else {
if (events == 0) {
@ -413,11 +418,11 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
"kevent() returned no events without timeout");
return NGX_ERROR;
}
}
#if (NGX_DEBUG_EVENT)
ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta);
#endif
}
if (err) {
ngx_log_error(NGX_LOG_ALERT, log, err, "kevent() failed");
@ -510,9 +515,15 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
}
}
if (timer && delta) {
ngx_event_expire_timers((ngx_msec_t) delta);
}
#if 0
if (timer) {
ngx_event_expire_timers((ngx_msec_t) delta);
}
#endif
return NGX_OK;
}

View File

@ -200,21 +200,10 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ ecf->use);
/* required by iocp in "c->write->active = 1" */
c->write = wev;
#if 0
ngx_test_null(rev->log, ngx_palloc(cycle->pool, sizeof(ngx_log_t)),
NGX_ERROR);
ngx_memcpy(rev->log, c->log, sizeof(ngx_log_t));
#endif
rev->log = c->log;
rev->data = c;
rev->index = NGX_INVALID_INDEX;
#if 0
rev->listening = 1;
#endif
rev->available = 0;
#if (HAVE_DEFERRED_ACCEPT)

View File

@ -31,11 +31,14 @@ struct ngx_event_s {
ngx_event_t *prev;
ngx_event_t *next;
ngx_rbtree_t rbtree;
#if 0
ngx_event_t *timer_prev;
ngx_event_t *timer_next;
ngx_msec_t timer_delta;
ngx_msec_t timer;
#endif
ngx_log_t *log;

View File

@ -175,6 +175,9 @@ void ngx_event_accept(ngx_event_t *ev)
rev->index = NGX_INVALID_INDEX;
wev->index = NGX_INVALID_INDEX;
rev->rbtree.data = rev;
wev->rbtree.data = wev;
rev->data = c;
wev->data = c;

View File

@ -4,6 +4,81 @@
#include <ngx_event.h>
ngx_rbtree_t *ngx_event_timer_rbtree;
int ngx_event_timer_init(ngx_cycle_t *cycle)
{
ngx_event_timer_rbtree = &sentinel;
sentinel.left = &sentinel;
sentinel.right = &sentinel;
sentinel.parent = &sentinel;
return NGX_OK;
}
void ngx_event_timer_done(ngx_cycle_t *cycle)
{
}
int ngx_event_find_timer(void)
{
ngx_rbtree_t *node;
node = ngx_rbtree_min(ngx_event_timer_rbtree);
if (node == &sentinel) {
return 0;
} else {
return node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec;
}
}
void ngx_event_expire_timers(ngx_msec_t timer)
{
ngx_event_t *ev;
ngx_rbtree_t *node;
for ( ;; ) {
node = ngx_rbtree_min(ngx_event_timer_rbtree);
if (node == &sentinel) {
break;
}
if ((ngx_msec_t) node->key <=
(ngx_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
{
ev = (ngx_event_t *)
((char *) node - offsetof(ngx_event_t, rbtree));
ngx_del_timer(ev);
if (ev->delayed) {
ev->delayed = 0;
if (ev->ready == 0) {
continue;
}
} else {
ev->timedout = 1;
}
ev->event_handler(ev);
continue;
}
break;
}
}
#if 0
/* TODO: in multithreaded enviroment all timer operations must be
protected by the single mutex */
@ -275,3 +350,6 @@ void ngx_event_expire_timers(ngx_msec_t timer)
}
#endif
}
#endif

View File

@ -7,14 +7,58 @@
#include <ngx_event.h>
/*
* 1 msec - 49 days
* 10 msec - 1 years 4 months
* 50 msec - 6 years 10 months
* 100 msec - 13 years 8 months
*/
#define NGX_TIMER_RESOLUTION 50
int ngx_event_timer_init(ngx_cycle_t *cycle);
void ngx_event_timer_done(ngx_cycle_t *cycle);
int ngx_event_find_timer(void);
void ngx_event_expire_timers(ngx_msec_t timer);
#if 0
int ngx_event_timer_init(ngx_cycle_t *cycle);
void ngx_event_timer_done(ngx_cycle_t *cycle);
void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer);
int ngx_event_find_timer(void);
void ngx_event_set_timer_delta(ngx_msec_t timer);
void ngx_event_expire_timers(ngx_msec_t timer);
#endif
extern ngx_rbtree_t *ngx_event_timer_rbtree;
ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
{
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->rbtree);
ev->timer_set = 0;
}
ngx_inline static void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
if (ev->timer_set) {
ngx_del_timer(ev);
}
ev->rbtree.key = (ngx_int_t)
(ngx_elapsed_msec + timer) / NGX_TIMER_RESOLUTION;
ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->rbtree);
ev->timer_set = 1;
}
#if 0
ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
{
@ -45,5 +89,7 @@ ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
ev->timer_set = 0;
}
#endif
#endif /* _NGX_EVENT_TIMER_H_INCLUDED_ */

View File

@ -514,13 +514,7 @@ ngx_log_debug(r->connection->log, "trans: %s: %d" _
}
if (clcf->handler) {
/*
* if the location already has content handler then skip
* the translation phase
*/
r->content_handler = clcf->handler;
r->phase++;
}
return NGX_OK;