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
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-11-27 10:45:22 +0300
committerIgor Sysoev <igor@sysoev.ru>2003-11-27 10:45:22 +0300
commit0e499db3ed63432cfacd08282cce1d42b568b567 (patch)
tree3dc7936e2083a5b72f82340973dd3dea55bb1ee8 /src
parentc0f8d91bde06aeeb53ff16d6c26490f5961f5a31 (diff)
nginx-0.0.1-2003-11-27-10:45:22 import
Diffstat (limited to 'src')
-rw-r--r--src/http/modules/ngx_http_static_handler.c39
-rw-r--r--src/http/ngx_http.h4
-rw-r--r--src/http/ngx_http_cache.c213
-rw-r--r--src/http/ngx_http_cache.h62
-rw-r--r--src/http/ngx_http_request.h4
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c3
-rw-r--r--src/os/unix/ngx_solaris.h8
-rw-r--r--src/os/unix/ngx_solaris_config.h1
-rw-r--r--src/os/unix/ngx_solaris_sendfilev_chain.c147
9 files changed, 286 insertions, 195 deletions
diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c
index 80af26672..42dd14a21 100644
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -39,12 +39,13 @@ ngx_module_t ngx_http_static_module = {
};
-int ngx_http_static_translate_handler(ngx_http_request_t *r)
+ngx_int_t ngx_http_static_translate_handler(ngx_http_request_t *r)
{
- int rc, level;
+ ngx_int_t rc, level;
+ uint32_t crc;
char *location, *last;
ngx_err_t err;
- ngx_http_cache_ctx_t ctx;
+ ngx_http_cache_t *cache;
ngx_http_cache_conf_t *ccf;
ngx_http_core_loc_conf_t *clcf;
@@ -87,23 +88,16 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r)
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
-
- /* STUB */
- ccf = NULL;
- ctx.key.len = 0;
-
-#if 0
ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module);
if (ccf->open_files) {
- ctx->hash = ccf->open_files;
- ctx->key = r->file.name;
+ cache = ngx_http_cache_get(ccf->open_files, &r->file.name, &crc);
- cache = ngx_http_cache_get_data(r, ctx);
+ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
if (cache
&& ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
- || ccf->hash->life_time >= ngx_time() - cache->updated))
+ || ccf->open_files->check_time >= ngx_time() - cache->updated))
{
cache->refs++;
r->file.fd = cache->fd;
@@ -117,8 +111,6 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
cache = NULL;
}
-#endif
-
#if (WIN9X)
if (ngx_win32_version < NGX_WIN_NT) {
@@ -215,6 +207,23 @@ ngx_log_debug(r->connection->log, "FILE: %d" _ r->file.fd);
r->file.info_valid = 1;
}
+ if (ccf->open_files) {
+ if (cache == NULL) {
+ cache = ngx_http_cache_alloc(ccf->open_files, &r->file.name, crc,
+ r->connection->log);
+ }
+
+ngx_log_debug(r->connection->log, "cache alloc: %x" _ cache);
+
+ if (cache) {
+ cache->fd = r->file.fd;
+ cache->data.size = ngx_file_size(&r->file.info);
+ cache->accessed = ngx_time();
+ cache->last_modified = ngx_file_mtime(&r->file.info);
+ cache->updated = ngx_time();
+ }
+ }
+
if (ngx_is_dir(&r->file.info)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 4271da3e7..4fa657293 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -6,9 +6,11 @@
#include <ngx_core.h>
#include <ngx_garbage_collector.h>
+typedef struct ngx_http_request_s ngx_http_request_t;
+
+#include <ngx_http_cache.h>
#include <ngx_http_request.h>
#include <ngx_http_config.h>
-#include <ngx_http_cache.h>
#include <ngx_http_busy_lock.h>
#include <ngx_http_filter.h>
#include <ngx_http_log_handler.h>
diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c
index 7b9cd0489..b1cd52c54 100644
--- a/src/http/ngx_http_cache.c
+++ b/src/http/ngx_http_cache.c
@@ -80,81 +80,87 @@ ngx_log_debug(r->connection->log, "FILE: %s" _ ctx->file.name.data);
}
-int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
+ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
+ ngx_str_t *key, uint32_t *crc)
{
- ngx_uint_t n, i;
+ ngx_uint_t i;
+ ngx_http_cache_t *c;
- ctx->crc = ngx_crc(ctx->key.data, ctx->key.len);
+ *crc = ngx_crc(key->data, key->len);
- n = ctx->crc % ctx->hash->hash;
- for (i = 0; i < ctx->hash->nelts; i++) {
- if (ctx->hash->cache[n][i].crc == ctx->crc
- && ctx->hash->cache[n][i].key.len == ctx->key.len
- && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data,
- ctx->key.len) == 0)
+ c = cache->elts
+ + *crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t);
+
+ for (i = 0; i < cache->nelts; i++) {
+ if (c[i].crc == *crc
+ && c[i].key.len == key->len
+ && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0)
{
- ctx->cache = ctx->hash->cache[n][i].data;
- ctx->hash->cache[n][i].refs++;
- return NGX_OK;
+ c[i].refs++;
+ return &c[i];
}
}
- return NGX_DECLINED;
+ return NULL;
}
-ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r,
- ngx_http_cache_ctx_t *ctx)
+ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
+ ngx_str_t *key, uint32_t crc,
+ ngx_log_t *log)
{
- time_t old;
- ngx_uint_t n, i;
- ngx_http_cache_entry_t *ce;
+ time_t old;
+ ngx_uint_t i;
+ ngx_http_cache_t *c, *found;
old = ngx_time() + 1;
- ce = NULL;
+ found = NULL;
- n = ctx->crc % ctx->hash->hash;
- for (i = 0; i < ctx->hash->nelts; i++) {
- if (ctx->hash->cache[n][i].key.data == NULL) {
+ c = cache->elts
+ + crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t);
+
+ for (i = 0; i < cache->nelts; i++) {
+ if (c[i].key.data == NULL) {
/* a free entry is found */
- ce = &ctx->hash->cache[n][i];
+ found = &c[i];
break;
}
- if (ctx->hash->cache[n][i].refs == 0
- && old > ctx->hash->cache[n][i].accessed)
- {
- /* looking for the oldest cache entry that is not used right now */
+ /* looking for the oldest cache entry that is not been using */
- old = ctx->hash->cache[n][i].accessed;
- ce = &ctx->hash->cache[n][i];
+ if (c[i].refs == 0 && old > c[i].accessed) {
+
+ old = c[i].accessed;
+ found = &c[i];
}
}
- if (ce) {
- if (ce->key.data) {
- if (ctx->key.len > ce->key.len) {
- ngx_free(ce->key.data);
- ce->key.data = NULL;
+ if (found) {
+ if (found->key.data) {
+ if (key->len > found->key.len) {
+ ngx_free(found->key.data);
+ found->key.data = NULL;
}
}
- if (ce->key.data) {
- ce->key.data = ngx_alloc(ctx->key.len, r->connection->log);
- if (ce->key.data == NULL) {
+ if (found->key.data == NULL) {
+ found->key.data = ngx_alloc(key->len, log);
+ if (found->key.data == NULL) {
return NULL;
}
}
- ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len);
+ ngx_memcpy(found->key.data, key->data, key->len);
- ce->key.len = ctx->key.len;
- ce->crc = ctx->crc;
+ found->crc = crc;
+ found->key.len = key->len;
+ found->refs = 1;
+ found->deleted = 0;
}
- return ce;
+ return found;
}
@@ -373,24 +379,25 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
ngx_http_cache_conf_t *prev = parent;
ngx_http_cache_conf_t *conf = child;
- if (conf->hash == NULL) {
- if (prev->hash) {
- conf->hash = prev->hash;
+ if (conf->open_files == NULL) {
+ if (prev->open_files) {
+ conf->open_files = prev->open_files;
} else {
- conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t));
- if (conf->hash == NULL) {
+ conf->open_files = ngx_pcalloc(cf->pool,
+ sizeof(ngx_http_cache_hash_t));
+ if (conf->open_files == NULL) {
return NGX_CONF_ERROR;
}
- conf->hash->hash = NGX_HTTP_CACHE_HASH;
- conf->hash->nelts = NGX_HTTP_CACHE_NELTS;
+ conf->open_files->hash = NGX_HTTP_CACHE_HASH;
+ conf->open_files->nelts = NGX_HTTP_CACHE_NELTS;
- conf->hash->cache = ngx_pcalloc(cf->pool,
- NGX_HTTP_CACHE_HASH
- * NGX_HTTP_CACHE_NELTS
- * sizeof(ngx_http_cache_entry_t));
- if (conf->hash->cache == NULL) {
+ conf->open_files->elts = ngx_pcalloc(cf->pool,
+ NGX_HTTP_CACHE_HASH
+ * NGX_HTTP_CACHE_NELTS
+ * sizeof(ngx_http_cache_t));
+ if (conf->open_files->elts == NULL) {
return NGX_CONF_ERROR;
}
}
@@ -398,103 +405,3 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
return NGX_CONF_OK;
}
-
-
-#if 0
-
-/*
- * small file in malloc()ed memory, mmap()ed file, file descriptor only,
- * file access time only (to estimate could pages still be in memory),
- * translated URI (ngx_http_index_hanlder),
- * compiled script (ngx_http_ssi_filter).
- */
-
-
-#define NGX_HTTP_CACHE_ENTRY_DELETED 0x00000001
-#define NGX_HTTP_CACHE_ENTRY_MMAPED 0x00000002
-
-/* "/" -> "/index.html" in ngx_http_index_handler */
-#define NGX_HTTP_CACHE_ENTRY_URI 0x00000004
-
-/* 301 location "/dir" -> "dir/" in ngx_http_core_handler */
-
-/* compiled script in ngx_http_ssi_filter */
-#define NGX_HTTP_CACHE_ENTRY_SCRIPT 0x00000008
-
-#define NGX_HTTP_CACHE_FILTER_FLAGS 0xFFFF0000
-
-
-typedef struct {
- ngx_fd_t fd;
- off_t size;
- void *data;
- time_t accessed;
- time_t last_modified;
- time_t updated; /* no needed with kqueue */
- int refs;
- int flags;
-} ngx_http_cache_entry_t;
-
-
-typedef struct {
- uint32_t crc;
- ngx_str_t uri;
- ngx_http_cache_t *cache;
-} ngx_http_cache_hash_entry_t;
-
-
-typedef struct {
- ngx_http_cache_t *cache;
- uint32_t crc;
- int n;
-} ngx_http_cache_handle_t;
-
-
-int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash,
- ngx_str_t *uri, ngx_http_cache_handle_t *h)
-{
- int hi;
- ngx_http_cache_hash_entry_t *entry;
-
- h->crc = ngx_crc(uri->data, uri->len);
-
- hi = h->crc % cache_hash->size;
- entry = cache_hash[hi].elts;
-
- for (i = 0; i < cache_hash[hi].nelts; i++) {
- if (entry[i].crc == crc
- && entry[i].uri.len == uri->len
- && ngx_strncmp(entry[i].uri.data, uri->data, uri->len) == 0
- {
- h->cache = entry[i].cache;
- h->cache->refs++;
- h->n = hi;
- return NGX_OK;
- }
- }
-
- return NGX_ERROR;
-}
-
-
-/* 32-bit crc16 */
-
-int ngx_crc(char *data, size_t len)
-{
- uint32_t sum;
-
- for (sum = 0; len; len--) {
- /*
- * gcc 2.95.2 x86 and icc 7.1.006 compile that operator
- * into the single rol opcode.
- * msvc 6.0sp2 compiles it into four opcodes.
- */
- sum = sum >> 1 | sum << 31;
-
- sum += *data++;
- }
-
- return sum;
-}
-
-#endif
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 6e8042df4..768ab0f56 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -8,6 +8,26 @@
typedef struct {
+ uint32_t crc;
+ ngx_str_t key;
+ time_t accessed;
+
+ unsigned refs:20; /* 1048576 references */
+ unsigned count:2; /* lazy allocation: the 4 uses */
+ unsigned deleted:1;
+
+ ngx_fd_t fd;
+ time_t last_modified;
+ time_t updated;
+
+ union {
+ off_t size;
+ ngx_str_t value;
+ } data;
+} ngx_http_cache_t;
+
+
+typedef struct {
time_t expires;
time_t last_modified;
time_t date;
@@ -17,24 +37,11 @@ typedef struct {
} ngx_http_cache_header_t;
-typedef struct {
- uint32_t crc;
- ngx_str_t key;
- ngx_fd_t fd;
- off_t size;
- void *data; /* mmap, memory */
- time_t accessed;
- time_t last_modified;
- time_t updated; /* no needed with kqueue */
- int refs;
- int flags;
-} ngx_http_cache_entry_t;
-
-#define NGX_HTTP_CACHE_HASH 1021
+#define NGX_HTTP_CACHE_HASH 7
#define NGX_HTTP_CACHE_NELTS 4
typedef struct {
- ngx_http_cache_entry_t **cache;
+ ngx_http_cache_t *elts;
size_t hash;
size_t nelts;
time_t life_time;
@@ -45,12 +52,7 @@ typedef struct {
typedef struct {
ngx_http_cache_hash_t *hash;
-} ngx_http_cache_conf_t;
-
-
-typedef struct {
- ngx_http_cache_hash_t *hash;
- ngx_http_cache_entry_t *cache;
+ ngx_http_cache_t *cache;
ngx_file_t file;
ngx_str_t key;
uint32_t crc;
@@ -67,6 +69,11 @@ typedef struct {
} ngx_http_cache_ctx_t;
+typedef struct {
+ ngx_http_cache_hash_t *open_files;
+} ngx_http_cache_conf_t;
+
+
#define NGX_HTTP_CACHE_STALE 1
#define NGX_HTTP_CACHE_AGED 2
#define NGX_HTTP_CACHE_THE_SAME 3
@@ -74,11 +81,20 @@ typedef struct {
int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx);
int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq);
-int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
- ngx_dir_t *dir);
int ngx_http_cache_update_file(ngx_http_request_t *r,ngx_http_cache_ctx_t *ctx,
ngx_str_t *temp_file);
+ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
+ ngx_str_t *key, uint32_t *crc);
+ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
+ ngx_str_t *key, uint32_t crc,
+ ngx_log_t *log);
+
+int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
+ ngx_dir_t *dir);
+
+extern ngx_module_t ngx_http_cache_module;
+
#endif /* _NGX_HTTP_CACHE_H_INCLUDED_ */
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 2a28a67b0..3b62d58e7 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -144,8 +144,6 @@ typedef struct {
} ngx_http_headers_out_t;
-typedef struct ngx_http_request_s ngx_http_request_t;
-
typedef int (*ngx_http_handler_pt)(ngx_http_request_t *r);
struct ngx_http_request_s {
@@ -156,6 +154,8 @@ struct ngx_http_request_s {
void **srv_conf;
void **loc_conf;
+ ngx_http_cache_t *cache;
+
ngx_file_t file;
ngx_pool_t *pool;
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index 6b0e62efc..bb89336fe 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -192,7 +192,8 @@ ngx_log_debug(c->log, "NOPUSH");
if (err == NGX_EAGAIN || err == NGX_EINTR) {
ngx_log_error(NGX_LOG_INFO, c->log, err,
- "sendfile() sent only %qd bytes", sent);
+ "sendfile() sent only " OFF_T_FMT " bytes",
+ sent);
} else {
wev->error = 1;
diff --git a/src/os/unix/ngx_solaris.h b/src/os/unix/ngx_solaris.h
new file mode 100644
index 000000000..c0829b782
--- /dev/null
+++ b/src/os/unix/ngx_solaris.h
@@ -0,0 +1,8 @@
+#ifndef _NGX_SOLARIS_H_INCLUDED_
+#define _NGX_SOLARIS_H_INCLUDED_
+
+
+ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in);
+
+
+#endif /* _NGX_SOLARIS_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
index 078d8d07c..233b46bf2 100644
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -23,6 +23,7 @@
#include <sys/filio.h> /* FIONBIO */
#include <sys/stropts.h> /* INFTIM */
#include <sys/socket.h>
+#include <sys/sendfile.h>
#include <sys/systeminfo.h>
#include <netinet/in.h>
#include <arpa/inet.h>
diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
new file mode 100644
index 000000000..8fe5cef1e
--- /dev/null
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -0,0 +1,147 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
+ int fd;
+ char *prev;
+ off_t fprev;
+ size_t sent;
+ ssize_t n;
+ ngx_int_t eintr;
+ sendfilevec_t *sfv;
+ ngx_array_t vec;
+ ngx_event_t *wev;
+ ngx_chain_t *cl;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return in;
+ }
+
+ do {
+ fd = SFV_FD_SELF;
+ prev = NULL;
+ sfv = NULL;
+ eintr = 0;
+ sent = 0;
+
+ /* create the sendfilevec and coalesce the neighbouring hunks */
+
+ for (cl = in; cl; cl = cl->next) {
+ if (ngx_hunk_special(cl->hunk)) {
+ continue;
+ }
+
+ if (ngx_hunk_in_memory_only(cl->hunk)) {
+ fd = SFV_FD_SELF;
+
+ if (prev == cl->hunk->pos) {
+ sfv->sfv_len += cl->hunk->last - cl->hunk->pos;
+
+ } else {
+ ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
+ sfv->sfv_fd = SFV_FD_SELF;
+ sfv->sfv_flag = 0;
+ sfv->sfv_off = cl->hunk->pos;
+ sfv->sfv_len = cl->hunk->last - cl->hunk->pos;
+ }
+
+ prev = cl->hunk->last;
+
+ } else {
+ prev = NULL;
+
+ if (fd == cl->hunk->file->fd && fprev == cl->hunk->file_pos) {
+ sfv->sfv_len += cl->hunk->file_last - cl->hunk->file_pos;
+
+ } else {
+ ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
+ fd = cl->hunk->file->fd;
+ sfv->sfv_fd = fd;
+ sfv->sfv_flag = 0;
+ sfv->sfv_off = cl->hunk->file_pos;
+ sfv->sfv_len = cl->hunk->file_last - cl->hunk->file_pos;
+ }
+
+ fprev = cl->hunk->file_last;
+ }
+ }
+
+ n = sendfile(c->fd, vec->elts, vec->nelts, &sent);
+
+ if (n == -1) {
+ err = ngx_errno;
+
+ if (err == NGX_EINTR) {
+ eintr = 1;
+ }
+
+ if (err == NGX_EAGAIN || err == NGX_EINTR) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err,
+ "sendfilev() sent only " SIZE_T_FMT " bytes",
+ sent);
+ } else {
+ wev->error = 1;
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfilev() failed");
+ return NGX_CHAIN_ERROR;
+ }
+ }
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "sendfilev: %d " SIZE_T_FMT ", n _ sent);
+#endif
+
+ c->sent += sent;
+
+ for (cl = in; cl; cl = cl->next) {
+
+ if (ngx_hunk_special(cl->hunk)) {
+ continue;
+ }
+
+ if (sent == 0) {
+ break;
+ }
+
+ size = ngx_hunk_size(cl->hunk);
+
+ if (sent >= size) {
+ sent -= size;
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos = cl->hunk->last;
+ }
+
+ if (cl->hunk->type & NGX_HUNK_FILE) {
+ cl->hunk->file_pos = cl->hunk->file_last;
+ }
+
+ continue;
+ }
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos += sent;
+ }
+
+ if (cl->hunk->type & NGX_HUNK_FILE) {
+ cl->hunk->file_pos += sent;
+ }
+
+ break;
+ }
+
+ in = cl;
+
+ } while (eintr);
+
+ if (in) {
+ wev->ready = 0;
+ }
+
+ return in;
+}