~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/core/ngx_open_file_cache.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_event.h>
 10 
 11 
 12 /*
 13  * open file cache caches
 14  *    open file handles with stat() info;
 15  *    directories stat() info;
 16  *    files and directories errors: not found, access denied, etc.
 17  */
 18 
 19 
 20 #define NGX_MIN_READ_AHEAD  (128 * 1024)
 21 
 22 
 23 static void ngx_open_file_cache_cleanup(void *data);
 24 static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of,
 25     ngx_log_t *log);
 26 static void ngx_open_file_add_event(ngx_open_file_cache_t *cache,
 27     ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log);
 28 static void ngx_open_file_cleanup(void *data);
 29 static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
 30     ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log);
 31 static void ngx_open_file_del_event(ngx_cached_open_file_t *file);
 32 static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache,
 33     ngx_uint_t n, ngx_log_t *log);
 34 static void ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
 35     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
 36 static ngx_cached_open_file_t *
 37     ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
 38     uint32_t hash);
 39 static void ngx_open_file_cache_remove(ngx_event_t *ev);
 40 
 41 
 42 ngx_open_file_cache_t *
 43 ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive)
 44 {
 45     ngx_pool_cleanup_t     *cln;
 46     ngx_open_file_cache_t  *cache;
 47 
 48     cache = ngx_palloc(pool, sizeof(ngx_open_file_cache_t));
 49     if (cache == NULL) {
 50         return NULL;
 51     }
 52 
 53     ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
 54                     ngx_open_file_cache_rbtree_insert_value);
 55 
 56     ngx_queue_init(&cache->expire_queue);
 57 
 58     cache->current = 0;
 59     cache->max = max;
 60     cache->inactive = inactive;
 61 
 62     cln = ngx_pool_cleanup_add(pool, 0);
 63     if (cln == NULL) {
 64         return NULL;
 65     }
 66 
 67     cln->handler = ngx_open_file_cache_cleanup;
 68     cln->data = cache;
 69 
 70     return cache;
 71 }
 72 
 73 
 74 static void
 75 ngx_open_file_cache_cleanup(void *data)
 76 {
 77     ngx_open_file_cache_t  *cache = data;
 78 
 79     ngx_queue_t             *q;
 80     ngx_cached_open_file_t  *file;
 81 
 82     ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
 83                    "open file cache cleanup");
 84 
 85     for ( ;; ) {
 86 
 87         if (ngx_queue_empty(&cache->expire_queue)) {
 88             break;
 89         }
 90 
 91         q = ngx_queue_last(&cache->expire_queue);
 92 
 93         file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
 94 
 95         ngx_queue_remove(q);
 96 
 97         ngx_rbtree_delete(&cache->rbtree, &file->node);
 98 
 99         cache->current--;
100 
101         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
102                        "delete cached open file: %s", file->name);
103 
104         if (!file->err && !file->is_dir) {
105             file->close = 1;
106             file->count = 0;
107             ngx_close_cached_file(cache, file, 0, ngx_cycle->log);
108 
109         } else {
110             ngx_free(file->name);
111             ngx_free(file);
112         }
113     }
114 
115     if (cache->current) {
116         ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
117                       "%d items still leave in open file cache",
118                       cache->current);
119     }
120 
121     if (cache->rbtree.root != cache->rbtree.sentinel) {
122         ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
123                       "rbtree still is not empty in open file cache");
124 
125     }
126 }
127 
128 
129 ngx_int_t
130 ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
131     ngx_open_file_info_t *of, ngx_pool_t *pool)
132 {
133     time_t                          now;
134     uint32_t                        hash;
135     ngx_int_t                       rc;
136     ngx_file_info_t                 fi;
137     ngx_pool_cleanup_t             *cln;
138     ngx_cached_open_file_t         *file;
139     ngx_pool_cleanup_file_t        *clnf;
140     ngx_open_file_cache_cleanup_t  *ofcln;
141 
142     of->fd = NGX_INVALID_FILE;
143     of->err = 0;
144 
145     if (cache == NULL) {
146 
147         if (of->test_only) {
148 
149             if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) {
150                 of->err = ngx_errno;
151                 of->failed = ngx_file_info_n;
152                 return NGX_ERROR;
153             }
154 
155             of->uniq = ngx_file_uniq(&fi);
156             of->mtime = ngx_file_mtime(&fi);
157             of->size = ngx_file_size(&fi);
158             of->is_dir = ngx_is_dir(&fi);
159             of->is_file = ngx_is_file(&fi);
160             of->is_link = ngx_is_link(&fi);
161             of->is_exec = ngx_is_exec(&fi);
162 
163             return NGX_OK;
164         }
165 
166         cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
167         if (cln == NULL) {
168             return NGX_ERROR;
169         }
170 
171         rc = ngx_open_and_stat_file(name->data, of, pool->log);
172 
173         if (rc == NGX_OK && !of->is_dir) {
174             cln->handler = ngx_pool_cleanup_file;
175             clnf = cln->data;
176 
177             clnf->fd = of->fd;
178             clnf->name = name->data;
179             clnf->log = pool->log;
180         }
181 
182         return rc;
183     }
184 
185     cln = ngx_pool_cleanup_add(pool, sizeof(ngx_open_file_cache_cleanup_t));
186     if (cln == NULL) {
187         return NGX_ERROR;
188     }
189 
190     now = ngx_time();
191 
192     hash = ngx_crc32_long(name->data, name->len);
193 
194     file = ngx_open_file_lookup(cache, name, hash);
195 
196     if (file) {
197 
198         file->uses++;
199 
200         ngx_queue_remove(&file->queue);
201 
202         if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) {
203 
204             /* file was not used often enough to keep open */
205 
206             rc = ngx_open_and_stat_file(name->data, of, pool->log);
207 
208             if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
209                 goto failed;
210             }
211 
212             goto add_event;
213         }
214 
215         if (file->use_event
216             || (file->event == NULL
217                 && (of->uniq == 0 || of->uniq == file->uniq)
218                 && now - file->created < of->valid))
219         {
220             if (file->err == 0) {
221 
222                 of->fd = file->fd;
223                 of->uniq = file->uniq;
224                 of->mtime = file->mtime;
225                 of->size = file->size;
226 
227                 of->is_dir = file->is_dir;
228                 of->is_file = file->is_file;
229                 of->is_link = file->is_link;
230                 of->is_exec = file->is_exec;
231                 of->is_directio = file->is_directio;
232 
233                 if (!file->is_dir) {
234                     file->count++;
235                     ngx_open_file_add_event(cache, file, of, pool->log);
236                 }
237 
238             } else {
239                 of->err = file->err;
240                 of->failed = ngx_open_file_n;
241             }
242 
243             goto found;
244         }
245 
246         ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
247                        "retest open file: %s, fd:%d, c:%d, e:%d",
248                        file->name, file->fd, file->count, file->err);
249 
250         if (file->is_dir) {
251 
252             /*
253              * chances that directory became file are very small
254              * so test_dir flag allows to use a single syscall
255              * in ngx_file_info() instead of three syscalls
256              */
257 
258             of->test_dir = 1;
259         }
260 
261         of->fd = file->fd;
262         of->uniq = file->uniq;
263 
264         rc = ngx_open_and_stat_file(name->data, of, pool->log);
265 
266         if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
267             goto failed;
268         }
269 
270         if (of->is_dir) {
271 
272             if (file->is_dir || file->err) {
273                 goto update;
274             }
275 
276             /* file became directory */
277 
278         } else if (of->err == 0) {  /* file */
279 
280             if (file->is_dir || file->err) {
281                 goto add_event;
282             }
283 
284             if (of->uniq == file->uniq) {
285 
286                 file->count++;
287 
288                 if (file->event) {
289                     file->use_event = 1;
290                 }
291 
292                 goto renew;
293             }
294 
295             /* file was changed */
296 
297         } else { /* error to cache */
298 
299             if (file->err || file->is_dir) {
300                 goto update;
301             }
302 
303             /* file was removed, etc. */
304         }
305 
306         if (file->count == 0) {
307 
308             ngx_open_file_del_event(file);
309 
310             if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
311                 ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
312                               ngx_close_file_n " \"%s\" failed",
313                               name->data);
314             }
315 
316             goto add_event;
317         }
318 
319         ngx_rbtree_delete(&cache->rbtree, &file->node);
320 
321         cache->current--;
322 
323         file->close = 1;
324 
325         goto create;
326     }
327 
328     /* not found */
329 
330     rc = ngx_open_and_stat_file(name->data, of, pool->log);
331 
332     if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
333         goto failed;
334     }
335 
336 create:
337 
338     if (cache->current >= cache->max) {
339         ngx_expire_old_cached_files(cache, 0, pool->log);
340     }
341 
342     file = ngx_alloc(sizeof(ngx_cached_open_file_t), pool->log);
343 
344     if (file == NULL) {
345         goto failed;
346     }
347 
348     file->name = ngx_alloc(name->len + 1, pool->log);
349 
350     if (file->name == NULL) {
351         ngx_free(file);
352         file = NULL;
353         goto failed;
354     }
355 
356     ngx_cpystrn(file->name, name->data, name->len + 1);
357 
358     file->node.key = hash;
359 
360     ngx_rbtree_insert(&cache->rbtree, &file->node);
361 
362     cache->current++;
363 
364     file->uses = 1;
365     file->count = 0;
366     file->use_event = 0;
367     file->event = NULL;
368 
369 add_event:
370 
371     ngx_open_file_add_event(cache, file, of, pool->log);
372 
373 update:
374 
375     file->fd = of->fd;
376     file->err = of->err;
377 
378     if (of->err == 0) {
379         file->uniq = of->uniq;
380         file->mtime = of->mtime;
381         file->size = of->size;
382 
383         file->close = 0;
384 
385         file->is_dir = of->is_dir;
386         file->is_file = of->is_file;
387         file->is_link = of->is_link;
388         file->is_exec = of->is_exec;
389         file->is_directio = of->is_directio;
390 
391         if (!of->is_dir) {
392             file->count++;
393         }
394     }
395 
396 renew:
397 
398     file->created = now;
399 
400 found:
401 
402     file->accessed = now;
403 
404     ngx_queue_insert_head(&cache->expire_queue, &file->queue);
405 
406     ngx_log_debug5(NGX_LOG_DEBUG_CORE, pool->log, 0,
407                    "cached open file: %s, fd:%d, c:%d, e:%d, u:%d",
408                    file->name, file->fd, file->count, file->err, file->uses);
409 
410     if (of->err == 0) {
411 
412         if (!of->is_dir) {
413             cln->handler = ngx_open_file_cleanup;
414             ofcln = cln->data;
415 
416             ofcln->cache = cache;
417             ofcln->file = file;
418             ofcln->min_uses = of->min_uses;
419             ofcln->log = pool->log;
420         }
421 
422         return NGX_OK;
423     }
424 
425     return NGX_ERROR;
426 
427 failed:
428 
429     if (file) {
430         ngx_rbtree_delete(&cache->rbtree, &file->node);
431 
432         cache->current--;
433 
434         if (file->count == 0) {
435 
436             if (file->fd != NGX_INVALID_FILE) {
437                 if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
438                     ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
439                                   ngx_close_file_n " \"%s\" failed",
440                                   file->name);
441                 }
442             }
443 
444             ngx_free(file->name);
445             ngx_free(file);
446 
447         } else {
448             file->close = 1;
449         }
450     }
451 
452     if (of->fd != NGX_INVALID_FILE) {
453         if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
454             ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
455                           ngx_close_file_n " \"%s\" failed", name->data);
456         }
457     }
458 
459     return NGX_ERROR;
460 }
461 
462 
463 static ngx_int_t
464 ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
465 {
466     ngx_fd_t         fd;
467     ngx_file_info_t  fi;
468 
469     if (of->fd != NGX_INVALID_FILE) {
470 
471         if (ngx_file_info(name, &fi) == NGX_FILE_ERROR) {
472             of->failed = ngx_file_info_n;
473             goto failed;
474         }
475 
476         if (of->uniq == ngx_file_uniq(&fi)) {
477             goto done;
478         }
479 
480     } else if (of->test_dir) {
481 
482         if (ngx_file_info(name, &fi) == NGX_FILE_ERROR) {
483             of->failed = ngx_file_info_n;
484             goto failed;
485         }
486 
487         if (ngx_is_dir(&fi)) {
488             goto done;
489         }
490     }
491 
492     if (!of->log) {
493         fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
494 
495     } else {
496         fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN,
497                            NGX_FILE_DEFAULT_ACCESS);
498     }
499 
500     if (fd == NGX_INVALID_FILE) {
501         of->failed = ngx_open_file_n;
502         goto failed;
503     }
504 
505     if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
506         ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
507                       ngx_fd_info_n " \"%s\" failed", name);
508 
509         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
510             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
511                           ngx_close_file_n " \"%s\" failed", name);
512         }
513 
514         of->fd = NGX_INVALID_FILE;
515 
516         return NGX_ERROR;
517     }
518 
519     if (ngx_is_dir(&fi)) {
520         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
521             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
522                           ngx_close_file_n " \"%s\" failed", name);
523         }
524 
525         of->fd = NGX_INVALID_FILE;
526 
527     } else {
528         of->fd = fd;
529 
530         if (of->read_ahead && ngx_file_size(&fi) > NGX_MIN_READ_AHEAD) {
531             if (ngx_read_ahead(fd, of->read_ahead) == NGX_ERROR) {
532                 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
533                               ngx_read_ahead_n " \"%s\" failed", name);
534             }
535         }
536 
537         if (of->directio <= ngx_file_size(&fi)) {
538             if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
539                 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
540                               ngx_directio_on_n " \"%s\" failed", name);
541 
542             } else {
543                 of->is_directio = 1;
544             }
545         }
546     }
547 
548 done:
549 
550     of->uniq = ngx_file_uniq(&fi);
551     of->mtime = ngx_file_mtime(&fi);
552     of->size = ngx_file_size(&fi);
553     of->is_dir = ngx_is_dir(&fi);
554     of->is_file = ngx_is_file(&fi);
555     of->is_link = ngx_is_link(&fi);
556     of->is_exec = ngx_is_exec(&fi);
557 
558     return NGX_OK;
559 
560 failed:
561 
562     of->fd = NGX_INVALID_FILE;
563     of->err = ngx_errno;
564 
565     return NGX_ERROR;
566 }
567 
568 
569 /*
570  * we ignore any possible event setting error and
571  * fallback to usual periodic file retests
572  */
573 
574 static void
575 ngx_open_file_add_event(ngx_open_file_cache_t *cache,
576     ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log)
577 {
578     ngx_open_file_cache_event_t  *fev;
579 
580     if (!(ngx_event_flags & NGX_USE_VNODE_EVENT)
581         || !of->events
582         || file->event
583         || of->fd == NGX_INVALID_FILE
584         || file->uses < of->min_uses)
585     {
586         return;
587     }
588 
589     file->use_event = 0;
590 
591     file->event = ngx_calloc(sizeof(ngx_event_t), log);
592     if (file->event== NULL) {
593         return;
594     }
595 
596     fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), log);
597     if (fev == NULL) {
598         ngx_free(file->event);
599         file->event = NULL;
600         return;
601     }
602 
603     fev->fd = of->fd;
604     fev->file = file;
605     fev->cache = cache;
606 
607     file->event->handler = ngx_open_file_cache_remove;
608     file->event->data = fev;
609 
610     /*
611      * although vnode event may be called while ngx_cycle->poll
612      * destruction, however, cleanup procedures are run before any
613      * memory freeing and events will be canceled.
614      */
615 
616     file->event->log = ngx_cycle->log;
617 
618     if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT)
619         != NGX_OK)
620     {
621         ngx_free(file->event->data);
622         ngx_free(file->event);
623         file->event = NULL;
624         return;
625     }
626 
627     /*
628      * we do not set file->use_event here because there may be a race
629      * condition: a file may be deleted between opening the file and
630      * adding event, so we rely upon event notification only after
631      * one file revalidation on next file access
632      */
633 
634     return;
635 }
636 
637 
638 static void
639 ngx_open_file_cleanup(void *data)
640 {
641     ngx_open_file_cache_cleanup_t  *c = data;
642 
643     c->file->count--;
644 
645     ngx_close_cached_file(c->cache, c->file, c->min_uses, c->log);
646 
647     /* drop one or two expired open files */
648     ngx_expire_old_cached_files(c->cache, 1, c->log);
649 }
650 
651 
652 static void
653 ngx_close_cached_file(ngx_open_file_cache_t *cache,
654     ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log)
655 {
656     ngx_log_debug5(NGX_LOG_DEBUG_CORE, log, 0,
657                    "close cached open file: %s, fd:%d, c:%d, u:%d, %d",
658                    file->name, file->fd, file->count, file->uses, file->close);
659 
660     if (!file->close) {
661 
662         file->accessed = ngx_time();
663 
664         ngx_queue_remove(&file->queue);
665 
666         ngx_queue_insert_head(&cache->expire_queue, &file->queue);
667 
668         if (file->uses >= min_uses || file->count) {
669             return;
670         }
671     }
672 
673     ngx_open_file_del_event(file);
674 
675     if (file->count) {
676         return;
677     }
678 
679     if (file->fd != NGX_INVALID_FILE) {
680 
681         if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
682             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
683                           ngx_close_file_n " \"%s\" failed", file->name);
684         }
685 
686         file->fd = NGX_INVALID_FILE;
687     }
688 
689     if (!file->close) {
690         return;
691     }
692 
693     ngx_free(file->name);
694     ngx_free(file);
695 }
696 
697 
698 static void
699 ngx_open_file_del_event(ngx_cached_open_file_t *file)
700 {
701     if (file->event == NULL) {
702         return;
703     }
704 
705     (void) ngx_del_event(file->event, NGX_VNODE_EVENT,
706                          file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT);
707 
708     ngx_free(file->event->data);
709     ngx_free(file->event);
710     file->event = NULL;
711     file->use_event = 0;
712 }
713 
714 
715 static void
716 ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n,
717     ngx_log_t *log)
718 {
719     time_t                   now;
720     ngx_queue_t             *q;
721     ngx_cached_open_file_t  *file;
722 
723     now = ngx_time();
724 
725     /*
726      * n == 1 deletes one or two inactive files
727      * n == 0 deletes least recently used file by force
728      *        and one or two inactive files
729      */
730 
731     while (n < 3) {
732 
733         if (ngx_queue_empty(&cache->expire_queue)) {
734             return;
735         }
736 
737         q = ngx_queue_last(&cache->expire_queue);
738 
739         file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
740 
741         if (n++ != 0 && now - file->accessed <= cache->inactive) {
742             return;
743         }
744 
745         ngx_queue_remove(q);
746 
747         ngx_rbtree_delete(&cache->rbtree, &file->node);
748 
749         cache->current--;
750 
751         ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
752                        "expire cached open file: %s", file->name);
753 
754         if (!file->err && !file->is_dir) {
755             file->close = 1;
756             ngx_close_cached_file(cache, file, 0, log);
757 
758         } else {
759             ngx_free(file->name);
760             ngx_free(file);
761         }
762     }
763 }
764 
765 
766 static void
767 ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
768     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
769 {
770     ngx_rbtree_node_t       **p;
771     ngx_cached_open_file_t    *file, *file_temp;
772 
773     for ( ;; ) {
774 
775         if (node->key < temp->key) {
776 
777             p = &temp->left;
778 
779         } else if (node->key > temp->key) {
780 
781             p = &temp->right;
782 
783         } else { /* node->key == temp->key */
784 
785             file = (ngx_cached_open_file_t *) node;
786             file_temp = (ngx_cached_open_file_t *) temp;
787 
788             p = (ngx_strcmp(file->name, file_temp->name) < 0)
789                     ? &temp->left : &temp->right;
790         }
791 
792         if (*p == sentinel) {
793             break;
794         }
795 
796         temp = *p;
797     }
798 
799     *p = node;
800     node->parent = temp;
801     node->left = sentinel;
802     node->right = sentinel;
803     ngx_rbt_red(node);
804 }
805 
806 
807 static ngx_cached_open_file_t *
808 ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
809     uint32_t hash)
810 {
811     ngx_int_t                rc;
812     ngx_rbtree_node_t       *node, *sentinel;
813     ngx_cached_open_file_t  *file;
814 
815     node = cache->rbtree.root;
816     sentinel = cache->rbtree.sentinel;
817 
818     while (node != sentinel) {
819 
820         if (hash < node->key) {
821             node = node->left;
822             continue;
823         }
824 
825         if (hash > node->key) {
826             node = node->right;
827             continue;
828         }
829 
830         /* hash == node->key */
831 
832         do {
833             file = (ngx_cached_open_file_t *) node;
834 
835             rc = ngx_strcmp(name->data, file->name);
836 
837             if (rc == 0) {
838                 return file;
839             }
840 
841             node = (rc < 0) ? node->left : node->right;
842 
843         } while (node != sentinel && hash == node->key);
844 
845         break;
846     }
847 
848     return NULL;
849 }
850 
851 
852 static void
853 ngx_open_file_cache_remove(ngx_event_t *ev)
854 {
855     ngx_cached_open_file_t       *file;
856     ngx_open_file_cache_event_t  *fev;
857 
858     fev = ev->data;
859     file = fev->file;
860 
861     ngx_queue_remove(&file->queue);
862 
863     ngx_rbtree_delete(&fev->cache->rbtree, &file->node);
864 
865     fev->cache->current--;
866 
867     /* NGX_ONESHOT_EVENT was already deleted */
868     file->event = NULL;
869     file->use_event = 0;
870 
871     file->close = 1;
872 
873     ngx_close_cached_file(fev->cache, file, 0, ev->log);
874 
875     /* free memory only when fev->cache and fev->file are already not needed */
876 
877     ngx_free(ev->data);
878     ngx_free(ev);
879 }
880 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.