nginx-0.1.28-RELEASE import
*) Bugfix: nginx hogs CPU while proxying the huge files.
*) Bugfix: nginx could not be built by gcc 4.0 on Linux.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index d097cf7..9fa141a 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.1.27"
+#define NGINX_VER "nginx/0.1.28"
#define NGINX_VAR "NGINX"
#define NGX_NEWPID_EXT ".newbin"
diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c
index 2f0356f..4c1b1d5 100644
--- a/src/core/ngx_buf.c
+++ b/src/core/ngx_buf.c
@@ -44,6 +44,27 @@
ngx_chain_t *
+ngx_alloc_chain_link(ngx_pool_t *pool)
+{
+ ngx_chain_t *cl;
+
+ cl = pool->chain;
+
+ if (cl) {
+ pool->chain = cl->next;
+ return cl;
+ }
+
+ cl = ngx_palloc(pool, sizeof(ngx_chain_t));
+ if (cl == NULL) {
+ return NULL;
+ }
+
+ return cl;
+}
+
+
+ngx_chain_t *
ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
{
u_char *p;
diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h
index 721b9c2..96394f9 100644
--- a/src/core/ngx_buf.h
+++ b/src/core/ngx_buf.h
@@ -55,8 +55,6 @@
};
-typedef struct ngx_chain_s ngx_chain_t;
-
struct ngx_chain_s {
ngx_buf_t *buf;
ngx_chain_t *next;
@@ -119,7 +117,11 @@
#define ngx_alloc_buf(pool) ngx_palloc(pool, sizeof(ngx_buf_t))
#define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))
-#define ngx_alloc_chain_link(pool) ngx_palloc(pool, sizeof(ngx_chain_t))
+ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
+#define ngx_free_chain(pool, cl) \
+ cl->next = pool->chain; \
+ pool->chain = cl
+
ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in);
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index e8119fc..35ee8b8 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -137,7 +137,7 @@
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "%s in %s:%d",
+ "%s in %s:%ui",
rv, cf->conf_file->file.name.data,
cf->conf_file->line);
rc = NGX_ERROR;
@@ -207,7 +207,7 @@
if (!(cmd->type & cf->cmd_type)) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%d "
+ "directive \"%s\" in %s:%ui "
"is not allowed here",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -216,7 +216,7 @@
if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%d "
+ "directive \"%s\" in %s:%ui "
"is not terminated by \";\"",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -227,7 +227,7 @@
&& last != NGX_CONF_BLOCK_START)
{
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%d "
+ "directive \"%s\" in %s:%ui "
"has not the opening \"{\"",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -276,7 +276,7 @@
if (!valid) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid number arguments in "
- "directive \"%s\" in %s:%d",
+ "directive \"%s\" in %s:%ui",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
return NGX_ERROR;
@@ -311,7 +311,7 @@
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "the \"%s\" directive %s in %s:%d",
+ "the \"%s\" directive %s in %s:%ui",
name->data, rv, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -323,7 +323,7 @@
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unknown directive \"%s\" in %s:%d",
+ "unknown directive \"%s\" in %s:%ui",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -360,7 +360,7 @@
{
if (cf->args->nelts > 0) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unexpected end of file in %s:%d, "
+ "unexpected end of file in %s:%ui, "
"expecting \";\" or \"}\"",
cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -423,7 +423,7 @@
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unexpected \"%c\" in %s:%d",
+ "unexpected \"%c\" in %s:%ui",
ch, cf->conf_file->file.name.data,
cf->conf_file->line);
@@ -443,7 +443,7 @@
case '{':
if (cf->args->nelts == 0) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unexpected \"%c\" in %s:%d",
+ "unexpected \"%c\" in %s:%ui",
ch, cf->conf_file->file.name.data,
cf->conf_file->line);
return NGX_ERROR;
@@ -458,7 +458,7 @@
case '}':
if (cf->args->nelts > 0) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unexpected \"}\" in %s:%d",
+ "unexpected \"}\" in %s:%ui",
cf->conf_file->file.name.data,
cf->conf_file->line);
return NGX_ERROR;
@@ -729,7 +729,7 @@
*buf = '\0';
}
- ngx_log_error(level, cf->log, 0, "%s in %s:%d",
+ ngx_log_error(level, cf->log, 0, "%s in %s:%ui",
errstr, cf->conf_file->file.name.data, cf->conf_file->line);
}
@@ -1065,7 +1065,7 @@
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "value must be equal or more than %d", bounds->low);
+ "value must be equal or more than %i", bounds->low);
return NGX_CONF_ERROR;
}
@@ -1075,7 +1075,7 @@
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "value must be between %d and %d",
+ "value must be between %i and %i",
bounds->low, bounds->high);
return NGX_CONF_ERROR;
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index d5a7a66..4fab8c1 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -73,60 +73,60 @@
struct ngx_command_s {
- ngx_str_t name;
- int type;
- char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
- int conf;
- int offset;
- void *post;
+ ngx_str_t name;
+ ngx_uint_t type;
+ char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+ ngx_uint_t conf;
+ ngx_uint_t offset;
+ void *post;
};
#define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }
struct ngx_open_file_s {
- ngx_fd_t fd;
- ngx_str_t name;
+ ngx_fd_t fd;
+ ngx_str_t name;
#if 0
/* e.g. append mode, error_log */
- int flags;
+ ngx_uint_t flags;
/* e.g. reopen db file */
- int (*handler)(void *data, ngx_open_file_t *file);
- void *data;
+ ngx_uint_t (*handler)(void *data, ngx_open_file_t *file);
+ void *data;
#endif
};
struct ngx_module_s {
- ngx_uint_t ctx_index;
- ngx_uint_t index;
- void *ctx;
- ngx_command_t *commands;
- ngx_uint_t type;
- ngx_int_t (*init_module)(ngx_cycle_t *cycle);
- ngx_int_t (*init_process)(ngx_cycle_t *cycle);
+ ngx_uint_t ctx_index;
+ ngx_uint_t index;
+ void *ctx;
+ ngx_command_t *commands;
+ ngx_uint_t type;
+ ngx_int_t (*init_module)(ngx_cycle_t *cycle);
+ ngx_int_t (*init_process)(ngx_cycle_t *cycle);
#if 0
- ngx_int_t (*init_thread)(ngx_cycle_t *cycle);
+ ngx_int_t (*init_thread)(ngx_cycle_t *cycle);
#endif
};
typedef struct {
- ngx_str_t name;
- void *(*create_conf)(ngx_cycle_t *cycle);
- char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
+ ngx_str_t name;
+ void *(*create_conf)(ngx_cycle_t *cycle);
+ char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
} ngx_core_module_t;
typedef struct {
- ngx_file_t file;
- ngx_buf_t *buffer;
- ngx_uint_t line;
+ ngx_file_t file;
+ ngx_buf_t *buffer;
+ ngx_uint_t line;
} ngx_conf_file_t;
typedef char *(*ngx_conf_handler_pt)(ngx_conf_t *cf,
- ngx_command_t *dummy, void *conf);
+ ngx_command_t *dummy, void *conf);
struct ngx_conf_s {
@@ -157,22 +157,22 @@
typedef struct {
ngx_conf_post_handler_pt post_handler;
- int low;
- int high;
+ ngx_int_t low;
+ ngx_int_t high;
} ngx_conf_num_bounds_t;
typedef struct {
- ngx_str_t name;
- ngx_uint_t value;
+ ngx_str_t name;
+ ngx_uint_t value;
} ngx_conf_enum_t;
#define NGX_CONF_BITMASK_SET 1
typedef struct {
- ngx_str_t name;
- ngx_uint_t mask;
+ ngx_str_t name;
+ ngx_uint_t mask;
} ngx_conf_bitmask_t;
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 13053f2..9646f6c 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -12,6 +12,7 @@
typedef struct ngx_conf_s ngx_conf_t;
typedef struct ngx_cycle_s ngx_cycle_t;
typedef struct ngx_pool_s ngx_pool_t;
+typedef struct ngx_chain_s ngx_chain_t;
typedef struct ngx_log_s ngx_log_t;
typedef struct ngx_array_s ngx_array_t;
typedef struct ngx_open_file_s ngx_open_file_t;
@@ -51,7 +52,7 @@
#include <ngx_buf.h>
#include <ngx_array.h>
#include <ngx_list.h>
-#include <ngx_table.h>
+#include <ngx_hash.h>
#include <ngx_file.h>
#include <ngx_files.h>
#include <ngx_crc.h>
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index 51864e3..5104205 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -54,7 +54,7 @@
log = old_cycle->log;
- pool = ngx_create_pool(16 * 1024, log);
+ pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (pool == NULL) {
return NULL;
}
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index face67f..b1b5348 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -12,6 +12,11 @@
#include <ngx_core.h>
+#ifndef NGX_CYCLE_POOL_SIZE
+#define NGX_CYCLE_POOL_SIZE 16384
+#endif
+
+
#define NGX_DEBUG_POINTS_STOP 1
#define NGX_DEBUG_POINTS_ABORT 2
diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c
new file mode 100644
index 0000000..2c062b7
--- /dev/null
+++ b/src/core/ngx_hash.c
@@ -0,0 +1,160 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_int_t
+ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
+{
+ u_char *p;
+ ngx_str_t *n, *bucket;
+ ngx_uint_t i, key, size, best, *test, buckets, min_buckets;
+
+ test = ngx_alloc(hash->max_size * sizeof(ngx_uint_t), pool->log);
+ if (test == NULL) {
+ return NGX_ERROR;
+ }
+
+ min_buckets = hash->bucket_limit + 1;
+
+#if (NGX_SUPPRESS_WARN)
+ best = 0;
+#endif
+
+ for (size = 1; size < hash->max_size; size++) {
+
+ buckets = 0;
+
+ for (i = 0; i < size; i++) {
+ test[i] = 0;
+ }
+
+ for (n = (ngx_str_t *) names;
+ n->len;
+ n = (ngx_str_t *) ((char *) n + hash->bucket_size))
+ {
+ key = 0;
+
+ for (i = 0; i < n->len; i++) {
+ key += ngx_tolower(n->data[i]);
+ }
+
+ key %= size;
+
+ if (test[key] == hash->bucket_limit) {
+ break;
+ }
+
+ test[key]++;
+
+ if (buckets < test[key]) {
+ buckets = test[key];
+ }
+ }
+
+ if (n->len == 0) {
+ if (min_buckets > buckets) {
+ min_buckets = buckets;
+ best = size;
+ }
+
+ if (hash->bucket_limit == 1) {
+ break;
+ }
+ }
+ }
+
+ if (min_buckets == hash->bucket_limit + 1) {
+ ngx_log_error(NGX_LOG_EMERG, pool->log, 0,
+ "could not build the %s hash, you should increase "
+ "either %s_size: %i or %s_bucket_limit: %i",
+ hash->name, hash->name, hash->max_size,
+ hash->name, hash->bucket_limit);
+ ngx_free(test);
+ return NGX_ERROR;
+ }
+
+ hash->buckets = ngx_pcalloc(pool, best * hash->bucket_size);
+ if (hash->buckets == NULL) {
+ ngx_free(test);
+ return NGX_ERROR;
+ }
+
+ if (hash->bucket_limit != 1) {
+
+ for (i = 0; i < best; i++) {
+ test[i] = 0;
+ }
+
+ for (n = (ngx_str_t *) names;
+ n->len;
+ n = (ngx_str_t *) ((char *) n + hash->bucket_size))
+ {
+ key = 0;
+
+ for (i = 0; i < n->len; i++) {
+ key += ngx_tolower(n->data[i]);
+ }
+
+ key %= best;
+
+ test[key]++;
+ }
+
+ for (i = 0; i < best; i++) {
+ if (test[i] == 0) {
+ continue;
+ }
+
+ bucket = ngx_palloc(pool, test[i] * hash->bucket_size);
+ if (bucket == NULL) {
+ ngx_free(test);
+ return NGX_ERROR;
+ }
+
+ hash->buckets[i] = bucket;
+ bucket->len = 0;
+ }
+ }
+
+ for (n = (ngx_str_t *) names;
+ n->len;
+ n = (ngx_str_t *) ((char *) n + hash->bucket_size))
+ {
+ key = 0;
+
+ for (i = 0; i < n->len; i++) {
+ key += ngx_tolower(n->data[i]);
+ }
+
+ key %= best;
+
+ if (hash->bucket_limit == 1) {
+ p = (u_char *) hash->buckets + key * hash->bucket_size;
+ ngx_memcpy(p, n, hash->bucket_size);
+ continue;
+ }
+
+ for (bucket = hash->buckets[key];
+ bucket->len;
+ bucket = (ngx_str_t *) ((char *) bucket + hash->bucket_size))
+ {
+ bucket->len &= 0x7fffffff;
+ }
+
+ ngx_memcpy(bucket, n, hash->bucket_size);
+ bucket->len |= 0x80000000;
+ }
+
+ ngx_free(test);
+
+ hash->hash_size = best;
+ hash->min_buckets = min_buckets;
+
+ return NGX_OK;
+}
diff --git a/src/core/ngx_hash.h b/src/core/ngx_hash.h
new file mode 100644
index 0000000..5a4bf5f
--- /dev/null
+++ b/src/core/ngx_hash.h
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_HASH_H_INCLUDED_
+#define _NGX_HASH_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef struct {
+ void **buckets;
+ ngx_uint_t hash_size;
+
+ ngx_uint_t max_size;
+ ngx_uint_t bucket_limit;
+ size_t bucket_size;
+ char *name;
+ ngx_uint_t min_buckets;
+} ngx_hash_t;
+
+
+typedef struct {
+ ngx_uint_t hash;
+ ngx_str_t key;
+ ngx_str_t value;
+} ngx_table_elt_t;
+
+
+ngx_int_t ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names);
+
+
+#endif /* _NGX_HASH_H_INCLUDED_ */
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 313557d..fc8a0bf 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -119,8 +119,10 @@
/* get the free buf */
if (ctx->free) {
- ctx->buf = ctx->free->buf;
- ctx->free = ctx->free->next;
+ cl = ctx->free;
+ ctx->buf = cl->buf;
+ ctx->free = cl->next;
+ ngx_free_chain(ctx->pool, cl);
} else if (out || ctx->allocated == ctx->bufs.num) {
diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c
index 8faf9a7..2804dd0 100644
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -22,6 +22,7 @@
p->end = (u_char *) p + size;
p->next = NULL;
p->large = NULL;
+ p->chain = NULL;
p->log = log;
return p;
diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h
index b310082..bd256e8 100644
--- a/src/core/ngx_palloc.h
+++ b/src/core/ngx_palloc.h
@@ -33,6 +33,7 @@
struct ngx_pool_s {
u_char *last;
u_char *end;
+ ngx_chain_t *chain;
ngx_pool_t *next;
ngx_pool_large_t *large;
ngx_log_t *log;
diff --git a/src/core/ngx_table.h b/src/core/ngx_table.h
deleted file mode 100644
index 5e2f3a9..0000000
--- a/src/core/ngx_table.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#ifndef _NGX_TABLE_H_INCLUDED_
-#define _NGX_TABLE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef ngx_array_t ngx_table_t;
-
-typedef struct {
- ngx_str_t key;
- ngx_str_t value;
-} ngx_table_elt_t;
-
-
-#define ngx_create_table(p, n) ngx_create_array(p, n, 2 * sizeof(ngx_str_t))
-#define ngx_push_table(t) ngx_push_array(t)
-
-
-#endif /* _NGX_TABLE_H_INCLUDED_ */