~britco/nginx/master

« back to all changes in this revision

Viewing changes to src/http/ngx_http_file_cache.c

  • Committer: Bazaar Package Importer
  • Author(s): Kartik Mistry, Kartik Mistry, Michael Lustfield
  • Date: 2010-11-27 21:04:02 UTC
  • mfrom: (1.3.8 upstream)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20101127210402-14sgjpe6r3jup8a9
Tags: 0.8.53-1
[Kartik Mistry]
* debian/control:
  + Added Michael Lustfield as co-maintainer
* nginx.conf:
  + No need to use regex in gzip_disable for msie6, Thanks to António P. P.
    Almeida <appa@perusio.net> (Closes: #592147)
* conf/sites-available/default:
  + Fixed typo for "include fastcgi", Thanks to Mostafa Ghadamyari
    <nginx@gigfa.com> (Closes: #593142, #593143)
* debian/patches/fix_reloading_ipv6.diff:
  + Removed, merged upstream
* debian/init.d:
  + Added fix to control nginx by user in a simple way by setting DAEMON
    variable to an invalid name in /etc/default/nginx. Patch by Toni Mueller
    <support@oeko.net> (Closes: #594598)
* debian/NEWS.Debian:
  + Updated news for 0.8.x as stable branch

[Michael Lustfield]
* New upstream release (Closes: #602970)
  + 0.8.x branch is declared stable by upstream now
* Add a UFW profile set:
  + debian/nginx.ufw.profile: Added.
  + debian/control: nginx: Suggests ufw.
  + debian/dirs: Add 'etc/ufw/applications.d'
  + debian/rules: Add install rule for the nginx UFW profile.
* Moved debian/dirs to debian/nginx.dirs
* Added types_hash_max_size to nginx.conf
* Install simple default index.html file (Closes: #581416)
  + debian/dirs: Add 'usr/share/nginx/www'.
  + debian/nginx.install: Add 'html/* usr/share/nginx/www'.
* debian/patches/nginx-echo.diff:
  + Added Echo module
* Added files for nginx.docs
  - /usr/share/doc/nginx/
    + debian/help/docs/fcgiwrap
    + debian/help/docs/php
    + debian/help/docs/support-irc
    + debian/help/docs/upstream
* Added files for nginx.examples
  - /usr/share/doc/nginx/examples/
    + debian/help/docs/drupal
    + debian/help/docs/http
    + debian/help/docs/mail
    + debian/help/docs/mailman
    + debian/help/docs/nginx.conf
    + debian/help/docs/virtual_hosts
    + debian/help/docs/wordpress
* debian/conf/:
  + Removed excess spaces
  + Added tabs where appropriate
  + Added SCRIPT_FILENAME to fastcgi_params

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <ngx_md5.h>
11
11
 
12
12
 
 
13
static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
 
14
    ngx_http_cache_t *c);
 
15
static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
 
16
    ngx_http_cache_t *c);
 
17
#if (NGX_HAVE_FILE_AIO)
 
18
static void ngx_http_cache_aio_event_handler(ngx_event_t *ev);
 
19
#endif
13
20
static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache,
14
21
    ngx_http_cache_t *c);
 
22
static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r,
 
23
    ngx_path_t *path);
15
24
static ngx_http_file_cache_node_t *
16
25
    ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key);
17
26
static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
37
46
 
38
47
ngx_str_t  ngx_http_cache_status[] = {
39
48
    ngx_string("MISS"),
 
49
    ngx_string("BYPASS"),
40
50
    ngx_string("EXPIRED"),
41
51
    ngx_string("STALE"),
42
52
    ngx_string("UPDATING"),
135
145
}
136
146
 
137
147
 
 
148
ngx_int_t
 
149
ngx_http_file_cache_new(ngx_http_request_t *r)
 
150
{
 
151
    ngx_http_cache_t  *c;
 
152
 
 
153
    c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
 
154
    if (c == NULL) {
 
155
        return NGX_ERROR;
 
156
    }
 
157
 
 
158
    if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
 
159
        return NGX_ERROR;
 
160
    }
 
161
 
 
162
    r->cache = c;
 
163
    c->file.log = r->connection->log;
 
164
    c->file.fd = NGX_INVALID_FILE;
 
165
 
 
166
    return NGX_OK;
 
167
}
 
168
 
 
169
 
 
170
ngx_int_t
 
171
ngx_http_file_cache_create(ngx_http_request_t *r)
 
172
{
 
173
    ngx_http_cache_t       *c;
 
174
    ngx_pool_cleanup_t     *cln;
 
175
    ngx_http_file_cache_t  *cache;
 
176
 
 
177
    ngx_http_file_cache_create_key(r);
 
178
 
 
179
    c = r->cache;
 
180
    cache = c->file_cache;
 
181
 
 
182
    cln = ngx_pool_cleanup_add(r->pool, 0);
 
183
    if (cln == NULL) {
 
184
        return NGX_ERROR;
 
185
    }
 
186
 
 
187
    if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
 
188
        return NGX_ERROR;
 
189
    }
 
190
 
 
191
    cln->handler = ngx_http_file_cache_cleanup;
 
192
    cln->data = c;
 
193
 
 
194
    if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
 
195
        return NGX_ERROR;
 
196
    }
 
197
 
 
198
    return NGX_OK;
 
199
}
 
200
 
 
201
 
138
202
void
139
203
ngx_http_file_cache_create_key(ngx_http_request_t *r)
140
204
{
173
237
ngx_int_t
174
238
ngx_http_file_cache_open(ngx_http_request_t *r)
175
239
{
176
 
    u_char                        *p;
177
 
    time_t                         now;
178
 
    ssize_t                        n;
179
 
    ngx_int_t                      rc, rv;
180
 
    ngx_uint_t                     cold, test;
181
 
    ngx_path_t                    *path;
182
 
    ngx_http_cache_t              *c;
183
 
    ngx_pool_cleanup_t            *cln;
184
 
    ngx_open_file_info_t           of;
185
 
    ngx_http_file_cache_t         *cache;
186
 
    ngx_http_core_loc_conf_t      *clcf;
187
 
    ngx_http_file_cache_header_t  *h;
 
240
    ngx_int_t                  rc, rv;
 
241
    ngx_uint_t                 cold, test;
 
242
    ngx_http_cache_t          *c;
 
243
    ngx_pool_cleanup_t        *cln;
 
244
    ngx_open_file_info_t       of;
 
245
    ngx_http_file_cache_t     *cache;
 
246
    ngx_http_core_loc_conf_t  *clcf;
188
247
 
189
248
    c = r->cache;
 
249
 
 
250
    if (c->buf) {
 
251
        return ngx_http_file_cache_read(r, c);
 
252
    }
 
253
 
190
254
    cache = c->file_cache;
191
255
 
192
256
    cln = ngx_pool_cleanup_add(r->pool, 0);
207
271
    cln->data = c;
208
272
 
209
273
    if (rc == NGX_AGAIN) {
210
 
        return rc;
 
274
        return NGX_HTTP_CACHE_SCARCE;
211
275
    }
212
276
 
213
277
    cold = cache->sh->cold;
227
291
        if (c->min_uses > 1) {
228
292
 
229
293
            if (!cold) {
230
 
                return NGX_AGAIN;
 
294
                return NGX_HTTP_CACHE_SCARCE;
231
295
            }
232
296
 
233
297
            test = 1;
234
 
            rv = NGX_AGAIN;
 
298
            rv = NGX_HTTP_CACHE_SCARCE;
235
299
 
236
300
        } else {
237
301
            c->temp_file = 1;
240
304
        }
241
305
    }
242
306
 
243
 
    path = cache->path;
244
 
 
245
 
    c->file.name.len = path->name.len + 1 + path->len
246
 
                       + 2 * NGX_HTTP_CACHE_KEY_LEN;
247
 
 
248
 
    c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);
249
 
    if (c->file.name.data == NULL) {
 
307
    if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
250
308
        return NGX_ERROR;
251
309
    }
252
310
 
253
 
    ngx_memcpy(c->file.name.data, path->name.data, path->name.len);
254
 
 
255
 
    p = c->file.name.data + path->name.len + 1 + path->len;
256
 
    p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN);
257
 
    *p = '\0';
258
 
 
259
 
    ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len);
260
 
 
261
 
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
262
 
                   "cache file: \"%s\"", c->file.name.data);
263
 
 
264
311
    if (!test) {
265
312
        return NGX_DECLINED;
266
313
    }
274
321
    of.min_uses = clcf->open_file_cache_min_uses;
275
322
    of.events = clcf->open_file_cache_events;
276
323
    of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
 
324
    of.read_ahead = clcf->read_ahead;
277
325
 
278
326
    if (ngx_open_cached_file(clcf->open_file_cache, &c->file.name, &of, r->pool)
279
327
        != NGX_OK)
299
347
 
300
348
    c->file.fd = of.fd;
301
349
    c->file.log = r->connection->log;
 
350
    c->uniq = of.uniq;
 
351
    c->length = of.size;
302
352
 
303
353
    c->buf = ngx_create_temp_buf(r->pool, c->body_start);
304
354
    if (c->buf == NULL) {
305
355
        return NGX_ERROR;
306
356
    }
307
357
 
308
 
    n = ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
309
 
 
310
 
    if (n == NGX_ERROR) {
 
358
    return ngx_http_file_cache_read(r, c);
 
359
}
 
360
 
 
361
 
 
362
static ngx_int_t
 
363
ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
 
364
{
 
365
    time_t                         now;
 
366
    ssize_t                        n;
 
367
    ngx_int_t                      rc;
 
368
    ngx_http_file_cache_t         *cache;
 
369
    ngx_http_file_cache_header_t  *h;
 
370
 
 
371
    n = ngx_http_file_cache_aio_read(r, c);
 
372
 
 
373
    if (n < 0) {
311
374
        return n;
312
375
    }
313
376
 
319
382
 
320
383
    h = (ngx_http_file_cache_header_t *) c->buf->pos;
321
384
 
322
 
    if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) {
 
385
    if (h->crc32 != c->crc32) {
323
386
        ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
324
387
                      "cache file \"%s\" has md5 collision", c->file.name.data);
325
388
        return NGX_DECLINED;
331
394
    c->last_modified = h->last_modified;
332
395
    c->date = h->date;
333
396
    c->valid_msec = h->valid_msec;
334
 
    c->length = of.size;
 
397
    c->header_start = h->header_start;
335
398
    c->body_start = h->body_start;
336
399
 
337
400
    r->cached = 1;
338
401
 
339
 
    if (cold) {
 
402
    cache = c->file_cache;
 
403
 
 
404
    if (cache->sh->cold) {
340
405
 
341
406
        ngx_shmtx_lock(&cache->shpool->mutex);
342
407
 
344
409
            c->node->uses = 1;
345
410
            c->node->body_start = c->body_start;
346
411
            c->node->exists = 1;
347
 
            c->node->uniq = of.uniq;
 
412
            c->node->uniq = c->uniq;
348
413
 
349
414
            cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize;
350
415
        }
363
428
 
364
429
        } else {
365
430
            c->node->updating = 1;
 
431
            c->updating = 1;
366
432
            rc = NGX_HTTP_CACHE_STALE;
367
433
        }
368
434
 
379
445
}
380
446
 
381
447
 
 
448
static ssize_t
 
449
ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
 
450
{
 
451
#if (NGX_HAVE_FILE_AIO)
 
452
    ssize_t                    n;
 
453
    ngx_http_core_loc_conf_t  *clcf;
 
454
 
 
455
    if (!ngx_file_aio) {
 
456
        goto noaio;
 
457
    }
 
458
 
 
459
    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
460
 
 
461
    if (!clcf->aio) {
 
462
        goto noaio;
 
463
    }
 
464
 
 
465
    n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
 
466
 
 
467
    if (n != NGX_AGAIN) {
 
468
        return n;
 
469
    }
 
470
 
 
471
    c->file.aio->data = r;
 
472
    c->file.aio->handler = ngx_http_cache_aio_event_handler;
 
473
 
 
474
    r->main->blocked++;
 
475
    r->aio = 1;
 
476
 
 
477
    return NGX_AGAIN;
 
478
 
 
479
noaio:
 
480
 
 
481
#endif
 
482
 
 
483
    return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
 
484
}
 
485
 
 
486
 
 
487
#if (NGX_HAVE_FILE_AIO)
 
488
 
 
489
static void
 
490
ngx_http_cache_aio_event_handler(ngx_event_t *ev)
 
491
{
 
492
    ngx_event_aio_t     *aio;
 
493
    ngx_http_request_t  *r;
 
494
 
 
495
    aio = ev->data;
 
496
    r = aio->data;
 
497
 
 
498
    r->main->blocked--;
 
499
    r->aio = 0;
 
500
 
 
501
    r->connection->write->handler(r->connection->write);
 
502
}
 
503
 
 
504
#endif
 
505
 
 
506
 
382
507
static ngx_int_t
383
508
ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
384
509
{
392
517
    if (fcn) {
393
518
        ngx_queue_remove(&fcn->queue);
394
519
 
 
520
        fcn->uses++;
 
521
        fcn->count++;
 
522
 
395
523
        if (fcn->error) {
396
524
 
397
525
            if (fcn->valid_sec < ngx_time()) {
403
531
            goto done;
404
532
        }
405
533
 
406
 
        fcn->uses++;
407
 
        fcn->count++;
408
 
 
409
534
        if (fcn->exists) {
410
535
 
411
536
            c->exists = fcn->exists;
454
579
 
455
580
    ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
456
581
 
 
582
    fcn->uses = 1;
 
583
    fcn->count = 1;
 
584
    fcn->updating = 0;
 
585
    fcn->deleting = 0;
 
586
 
457
587
renew:
458
588
 
459
589
    rc = NGX_DECLINED;
460
590
 
461
 
    fcn->uses = 1;
462
 
    fcn->count = 1;
463
591
    fcn->valid_msec = 0;
464
592
    fcn->error = 0;
465
593
    fcn->exists = 0;
486
614
}
487
615
 
488
616
 
 
617
static ngx_int_t
 
618
ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path)
 
619
{
 
620
    u_char            *p;
 
621
    ngx_http_cache_t  *c;
 
622
 
 
623
    c = r->cache;
 
624
 
 
625
    c->file.name.len = path->name.len + 1 + path->len
 
626
                       + 2 * NGX_HTTP_CACHE_KEY_LEN;
 
627
 
 
628
    c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);
 
629
    if (c->file.name.data == NULL) {
 
630
        return NGX_ERROR;
 
631
    }
 
632
 
 
633
    ngx_memcpy(c->file.name.data, path->name.data, path->name.len);
 
634
 
 
635
    p = c->file.name.data + path->name.len + 1 + path->len;
 
636
    p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN);
 
637
    *p = '\0';
 
638
 
 
639
    ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len);
 
640
 
 
641
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
642
                   "cache file: \"%s\"", c->file.name.data);
 
643
 
 
644
    return NGX_OK;
 
645
}
 
646
 
 
647
 
489
648
static ngx_http_file_cache_node_t *
490
649
ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key)
491
650
{
636
795
                   "http file cache update");
637
796
 
638
797
    c->updated = 1;
 
798
    c->updating = 0;
639
799
 
640
800
    cache = c->file_cache;
641
801
 
745
905
 
746
906
 
747
907
void
748
 
ngx_http_file_cache_free(ngx_http_request_t *r, ngx_temp_file_t *tf)
 
908
ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf)
749
909
{
750
 
    ngx_http_cache_t       *c;
751
 
    ngx_http_file_cache_t  *cache;
752
 
 
753
 
    c = r->cache;
 
910
    ngx_http_file_cache_t       *cache;
 
911
    ngx_http_file_cache_node_t  *fcn;
754
912
 
755
913
    if (c->updated) {
756
914
        return;
757
915
    }
758
916
 
759
 
    c->updated = 1;
760
 
 
761
917
    cache = c->file_cache;
762
918
 
763
 
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
764
 
                   "http file cache free");
 
919
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
 
920
                   "http file cache free, fd: %d", c->file.fd);
765
921
 
766
922
    ngx_shmtx_lock(&cache->shpool->mutex);
767
923
 
768
 
    c->node->count--;
 
924
    fcn = c->node;
 
925
    fcn->count--;
 
926
 
 
927
    if (c->updating) {
 
928
        fcn->updating = 0;
 
929
    }
769
930
 
770
931
    if (c->error) {
771
 
        c->node->valid_sec = c->valid_sec;
772
 
        c->node->valid_msec = c->valid_msec;
773
 
        c->node->error = c->error;
 
932
        fcn->error = c->error;
 
933
 
 
934
        if (c->valid_sec) {
 
935
            fcn->valid_sec = c->valid_sec;
 
936
            fcn->valid_msec = c->valid_msec;
 
937
        }
 
938
 
 
939
    } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) {
 
940
        ngx_queue_remove(&fcn->queue);
 
941
        ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
 
942
        ngx_slab_free_locked(cache->shpool, fcn);
 
943
        c->node = NULL;
774
944
    }
775
945
 
776
 
    c->node->updating = 0;
777
 
 
778
946
    ngx_shmtx_unlock(&cache->shpool->mutex);
779
947
 
 
948
    c->updated = 1;
 
949
    c->updating = 0;
 
950
 
780
951
    if (c->temp_file) {
781
952
        if (tf && tf->file.fd != NGX_INVALID_FILE) {
782
 
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
953
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
783
954
                           "http file cache incomplete: \"%s\"",
784
955
                           tf->file.name.data);
785
956
 
786
957
            if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
787
 
                ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
 
958
                ngx_log_error(NGX_LOG_CRIT, c->file.log, ngx_errno,
788
959
                              ngx_delete_file_n " \"%s\" failed",
789
960
                              tf->file.name.data);
790
961
            }
798
969
{
799
970
    ngx_http_cache_t  *c = data;
800
971
 
801
 
    ngx_http_file_cache_t  *cache;
802
 
 
803
972
    if (c->updated) {
804
973
        return;
805
974
    }
806
975
 
807
 
    c->updated = 1;
808
 
 
809
976
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
810
977
                   "http file cache cleanup");
811
978
 
812
 
    if (c->error) {
813
 
        return;
 
979
    if (c->updating) {
 
980
        ngx_log_error(NGX_LOG_ALERT, c->file.log, 0,
 
981
                      "stalled cache updating, error:%ui", c->error);
814
982
    }
815
983
 
816
 
    cache = c->file_cache;
817
 
 
818
 
    ngx_shmtx_lock(&cache->shpool->mutex);
819
 
 
820
 
    c->node->count--;
821
 
 
822
 
    ngx_shmtx_unlock(&cache->shpool->mutex);
 
984
    ngx_http_file_cache_free(c, NULL);
823
985
}
824
986
 
825
987
 
848
1010
    ngx_memcpy(name, path->name.data, path->name.len);
849
1011
 
850
1012
    wait = 10;
851
 
    tries = 0;
 
1013
    tries = 20;
852
1014
 
853
1015
    ngx_shmtx_lock(&cache->shpool->mutex);
854
1016
 
863
1025
                  fcn->count, fcn->exists,
864
1026
                  fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
865
1027
 
866
 
        if (fcn->count) {
 
1028
        if (fcn->count == 0) {
 
1029
            ngx_http_file_cache_delete(cache, q, name);
867
1030
 
868
 
            if (tries++ < 20) {
 
1031
        } else {
 
1032
            if (--tries) {
869
1033
                continue;
870
1034
            }
871
1035
 
872
1036
            wait = 1;
873
 
 
874
 
            break;
875
 
        }
876
 
 
877
 
        if (!fcn->exists) {
878
 
 
879
 
            ngx_queue_remove(q);
880
 
            ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
881
 
            ngx_slab_free_locked(cache->shpool, fcn);
882
 
 
883
 
            break;
884
 
        }
885
 
 
886
 
        ngx_http_file_cache_delete(cache, q, name);
 
1037
        }
887
1038
 
888
1039
        break;
889
1040
    }
947
1098
                       fcn->count, fcn->exists,
948
1099
                       fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
949
1100
 
950
 
        if (fcn->count) {
951
 
 
952
 
            p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
953
 
                             sizeof(ngx_rbtree_key_t));
954
 
 
955
 
            len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
956
 
            (void) ngx_hex_dump(p, fcn->key, len);
957
 
 
958
 
            /*
959
 
             * abnormally exited workers may leave locked cache entries,
960
 
             * and although it may be safe to remove them completely,
961
 
             * we prefer to remove them from inactive queue and rbtree
962
 
             * only, and to allow other leaks
963
 
             */
964
 
 
965
 
            ngx_queue_remove(q);
966
 
            ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
967
 
 
968
 
            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
969
 
                       "ignore long locked inactive cache entry %*s, count:%d",
970
 
                       2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
971
 
 
972
 
            continue;
973
 
        }
974
 
 
975
 
        if (!fcn->exists) {
976
 
 
977
 
            ngx_queue_remove(q);
978
 
            ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
979
 
            ngx_slab_free_locked(cache->shpool, fcn);
980
 
 
981
 
            continue;
982
 
        }
983
 
 
984
 
        ngx_http_file_cache_delete(cache, q, name);
 
1101
        if (fcn->count == 0) {
 
1102
            ngx_http_file_cache_delete(cache, q, name);
 
1103
            continue;
 
1104
        }
 
1105
 
 
1106
        if (fcn->deleting) {
 
1107
            continue;
 
1108
        }
 
1109
 
 
1110
        p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
 
1111
                         sizeof(ngx_rbtree_key_t));
 
1112
        len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
 
1113
        (void) ngx_hex_dump(p, fcn->key, len);
 
1114
 
 
1115
        /*
 
1116
         * abnormally exited workers may leave locked cache entries,
 
1117
         * and although it may be safe to remove them completely,
 
1118
         * we prefer to remove them from inactive queue and rbtree
 
1119
         * only, and to allow other leaks
 
1120
         */
 
1121
 
 
1122
        ngx_queue_remove(q);
 
1123
        ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
 
1124
 
 
1125
        ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
 
1126
                      "ignore long locked inactive cache entry %*s, count:%d",
 
1127
                      2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
985
1128
    }
986
1129
 
987
1130
    ngx_shmtx_unlock(&cache->shpool->mutex);
1003
1146
 
1004
1147
    fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
1005
1148
 
1006
 
    cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize;
1007
 
 
1008
 
    path = cache->path;
1009
 
 
1010
 
    p = name + path->name.len + 1 + path->len;
1011
 
 
1012
 
    p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t));
1013
 
 
1014
 
    len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1015
 
    p = ngx_hex_dump(p, fcn->key, len);
1016
 
    *p = '\0';
1017
 
 
1018
 
    ngx_queue_remove(q);
1019
 
 
1020
 
    ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1021
 
 
1022
 
    ngx_slab_free_locked(cache->shpool, fcn);
1023
 
 
1024
 
    ngx_shmtx_unlock(&cache->shpool->mutex);
1025
 
 
1026
 
    len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
1027
 
 
1028
 
    ngx_create_hashed_filename(path, name, len);
1029
 
 
1030
 
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1031
 
                   "http file cache expire: \"%s\"", name);
1032
 
 
1033
 
    if (ngx_delete_file(name) == NGX_FILE_ERROR) {
1034
 
        ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
1035
 
                      ngx_delete_file_n " \"%s\" failed", name);
1036
 
    }
1037
 
 
1038
 
    ngx_shmtx_lock(&cache->shpool->mutex);
 
1149
    if (fcn->exists) {
 
1150
        cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize;
 
1151
 
 
1152
        path = cache->path;
 
1153
        p = name + path->name.len + 1 + path->len;
 
1154
        p = ngx_hex_dump(p, (u_char *) &fcn->node.key,
 
1155
                         sizeof(ngx_rbtree_key_t));
 
1156
        len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
 
1157
        p = ngx_hex_dump(p, fcn->key, len);
 
1158
        *p = '\0';
 
1159
 
 
1160
        fcn->count++;
 
1161
        fcn->deleting = 1;
 
1162
        ngx_shmtx_unlock(&cache->shpool->mutex);
 
1163
 
 
1164
        len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
 
1165
        ngx_create_hashed_filename(path, name, len);
 
1166
 
 
1167
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
 
1168
                       "http file cache expire: \"%s\"", name);
 
1169
 
 
1170
        if (ngx_delete_file(name) == NGX_FILE_ERROR) {
 
1171
            ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
 
1172
                          ngx_delete_file_n " \"%s\" failed", name);
 
1173
        }
 
1174
 
 
1175
        ngx_shmtx_lock(&cache->shpool->mutex);
 
1176
        fcn->count--;
 
1177
        fcn->deleting = 0;
 
1178
    }
 
1179
 
 
1180
    if (fcn->count == 0) {
 
1181
        ngx_queue_remove(q);
 
1182
        ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
 
1183
        ngx_slab_free_locked(cache->shpool, fcn);
 
1184
    }
1039
1185
}
1040
1186
 
1041
1187
 
1291
1437
        fcn->valid_msec = c->valid_msec;
1292
1438
        fcn->error = 0;
1293
1439
        fcn->exists = 1;
 
1440
        fcn->updating = 0;
 
1441
        fcn->deleting = 0;
1294
1442
        fcn->uniq = c->uniq;
1295
1443
        fcn->valid_sec = c->valid_sec;
1296
1444
        fcn->body_start = c->body_start;