open_file_cache_min_uses
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index a05bbcf..5748f9e 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -20,7 +20,7 @@
static void ngx_open_file_cache_cleanup(void *data);
static void ngx_open_file_cleanup(void *data);
static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_log_t *log);
+ ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log);
static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of,
ngx_log_t *log);
static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache,
@@ -95,7 +95,7 @@
if (!file->err && !file->is_dir) {
file->close = 1;
file->count = 0;
- ngx_close_cached_file(cache, file, ngx_cycle->log);
+ ngx_close_cached_file(cache, file, 0, ngx_cycle->log);
} else {
ngx_free(file->name);
@@ -187,10 +187,29 @@
if (rc == 0) {
+ file->uses++;
+
ngx_queue_remove(&file->queue);
+ if (file->fd == NGX_INVALID_FILE
+ && file->err == 0
+ && !file->is_dir)
+ {
+ /* file was not used often enough to be open */
+
+ rc = ngx_open_and_stat_file(name->data, of, pool->log);
+
+ if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
+ goto failed;
+ }
+
+ goto update;
+ }
+
if (file->event || now - file->created < of->valid) {
+
if (file->err == 0) {
+
of->fd = file->fd;
of->uniq = file->uniq;
of->mtime = file->mtime;
@@ -338,6 +357,7 @@
cache->current++;
file->count = 0;
+ file->uses = 1;
update:
@@ -412,9 +432,9 @@
ngx_queue_insert_head(&cache->expire_queue, &file->queue);
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
- "cached open file: %s, fd:%d, c:%d, e:%d",
- file->name, file->fd, file->count, file->err);
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, pool->log, 0,
+ "cached open file: %s, fd:%d, c:%d, e:%d, u:%d",
+ file->name, file->fd, file->count, file->err, file->uses);
if (of->err == 0) {
@@ -424,6 +444,7 @@
ofcln->cache = cache;
ofcln->file = file;
+ ofcln->min_uses = of->min_uses;
ofcln->log = pool->log;
}
@@ -536,7 +557,7 @@
c->file->count--;
- ngx_close_cached_file(c->cache, c->file, c->log);
+ ngx_close_cached_file(c->cache, c->file, c->min_uses, c->log);
/* drop one or two expired open files */
ngx_expire_old_cached_files(c->cache, 1, c->log);
@@ -545,11 +566,11 @@
static void
ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_log_t *log)
+ ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log)
{
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0,
- "close cached open file: %s, fd:%d, c:%d, %d",
- file->name, file->fd, file->count, file->close);
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, log, 0,
+ "close cached open file: %s, fd:%d, c:%d, u:%d, %d",
+ file->name, file->fd, file->count, file->uses, file->close);
if (!file->close) {
@@ -559,7 +580,9 @@
ngx_queue_insert_head(&cache->expire_queue, &file->queue);
- return;
+ if (file->uses >= min_uses || file->count) {
+ return;
+ }
}
if (file->event) {
@@ -575,9 +598,18 @@
return;
}
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file->name);
+ if (file->fd != NGX_INVALID_FILE) {
+
+ if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", file->name);
+ }
+
+ file->fd = NGX_INVALID_FILE;
+ }
+
+ if (!file->close) {
+ return;
}
ngx_free(file->name);
@@ -626,7 +658,7 @@
if (!file->err && !file->is_dir) {
file->close = 1;
- ngx_close_cached_file(cache, file, log);
+ ngx_close_cached_file(cache, file, 0, log);
} else {
ngx_free(file->name);
@@ -697,7 +729,7 @@
file->close = 1;
- ngx_close_cached_file(fev->cache, file, ev->log);
+ ngx_close_cached_file(fev->cache, file, 0, ev->log);
/* free memory only when fev->cache and fev->file are already not needed */
diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h
index 6865f68..8ef4aea 100644
--- a/src/core/ngx_open_file_cache.h
+++ b/src/core/ngx_open_file_cache.h
@@ -21,6 +21,8 @@
time_t valid;
+ ngx_uint_t min_uses;
+
unsigned test_dir:1;
unsigned errors:1;
unsigned events:1;
@@ -48,6 +50,8 @@
off_t size;
ngx_err_t err;
+ uint32_t uses;
+
unsigned count:24;
unsigned close:1;
@@ -74,6 +78,7 @@
typedef struct {
ngx_open_file_cache_t *cache;
ngx_cached_open_file_t *file;
+ ngx_uint_t min_uses;
ngx_log_t *log;
} ngx_open_file_cache_cleanup_t;
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 2c14d29..1e8f96f 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -107,6 +107,7 @@
of.test_dir = 0;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index a82b318..c962283 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -210,6 +210,7 @@
of.test_dir = 0;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
@@ -293,6 +294,7 @@
of.test_dir = 1;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = 0;
of.errors = clcf->open_file_cache_errors;
if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool)
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index e89b1cd..cfc7089 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -98,6 +98,7 @@
of.test_dir = 0;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 771fd81..78455b9 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -644,6 +644,7 @@
of.test_dir = 0;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 066e129..a7da92a 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -491,6 +491,13 @@
offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
&ngx_conf_deprecated_open_file_cache_retest },
+ { ngx_string("open_file_cache_min_uses"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
+ NULL },
+
{ ngx_string("open_file_cache_errors"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -2429,6 +2436,7 @@
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
lcf->open_file_cache = NGX_CONF_UNSET_PTR;
lcf->open_file_cache_valid = NGX_CONF_UNSET;
+ lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
lcf->open_file_cache_errors = NGX_CONF_UNSET;
lcf->open_file_cache_events = NGX_CONF_UNSET;
@@ -2634,6 +2642,9 @@
ngx_conf_merge_sec_value(conf->open_file_cache_valid,
prev->open_file_cache_valid, 60);
+ ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
+ prev->open_file_cache_min_uses, 1);
+
ngx_conf_merge_sec_value(conf->open_file_cache_errors,
prev->open_file_cache_errors, 0);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index d08e9b1..52eb947 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -296,6 +296,7 @@
ngx_open_file_cache_t *open_file_cache;
time_t open_file_cache_valid;
+ ngx_uint_t open_file_cache_min_uses;
ngx_flag_t open_file_cache_errors;
ngx_flag_t open_file_cache_events;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 0ae27aa..e30fda2 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -977,6 +977,7 @@
of.test_dir = 0;
of.valid = clcf->open_file_cache_valid;
+ of.min_uses = clcf->open_file_cache_min_uses;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;