Changeset 1673
- Timestamp:
- 07/21/08 17:03:56 (6 months ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/Makefile.am (modified) (1 diff)
- cherokee/trunk/cherokee/cache.c (added)
- cherokee/trunk/cherokee/cache.h (added)
- cherokee/trunk/cherokee/cherokee.h (modified) (1 diff)
- cherokee/trunk/cherokee/connection-protected.h (modified) (1 diff)
- cherokee/trunk/cherokee/connection.c (modified) (6 diffs)
- cherokee/trunk/cherokee/handler_cgi_base.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_common.c (modified) (13 diffs)
- cherokee/trunk/cherokee/handler_file.c (modified) (13 diffs)
- cherokee/trunk/cherokee/iocache.c (modified) (8 diffs)
- cherokee/trunk/cherokee/iocache.h (modified) (2 diffs)
- cherokee/trunk/cherokee/server-protected.h (modified) (2 diffs)
- cherokee/trunk/cherokee/server.c (modified) (3 diffs)
- cherokee/trunk/cherokee/thread.c (modified) (5 diffs)
- cherokee/trunk/cherokee/thread.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r1670 r1673 1 1 2008-07-21 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 3 * cherokee/iocache.c, cherokee/iocache.h 4 cherokee/connection-protected.h, cherokee/handler_cgi_base.c, 5 cherokee/handler_common.c, cherokee/thread.c, cherokee/thread.h, 6 cherokee/handler_file.c, cherokee/server-protected.h, 7 cherokee/connection.c, cherokee/server.c: The I/O cache has been 8 reimplemented. Now it uses the new cherokee_cache_t class. It 9 should be faster than its predecessor. 10 11 * cherokee/cache.c, cherokee/cache.h, cherokee/Makefile.am, 12 cherokee/cherokee.h: Added new cherokee_cache_t class. It 13 implements a generic cache policy class. 2 14 3 15 * qa/run-tests.py (mainloop_iterator): Fixes a really nasty bug cherokee/trunk/cherokee/Makefile.am
r1660 r1673 949 949 bogotime.c \ 950 950 connector.h \ 951 connector.c 951 connector.c \ 952 cache.h \ 953 cache.c 952 954 953 955 libcherokee_client_la_SOURCES = \ cherokee/trunk/cherokee/cherokee.h
r1569 r1673 47 47 #include <cherokee/avl.h> 48 48 #include <cherokee/trace.h> 49 #include <cherokee/cache.h> 49 50 50 51 /* Server library cherokee/trunk/cherokee/connection-protected.h
r1607 r1673 200 200 ret_t cherokee_connection_free (cherokee_connection_t *conn); 201 201 ret_t cherokee_connection_clean (cherokee_connection_t *conn); 202 ret_t cherokee_connection_ mrproper(cherokee_connection_t *conn);202 ret_t cherokee_connection_clean_close (cherokee_connection_t *conn); 203 203 204 204 /* Close cherokee/trunk/cherokee/connection.c
r1654 r1673 207 207 cherokee_connection_clean (cherokee_connection_t *conn) 208 208 { 209 uint32_t header_len; 210 size_t crlf_len; 211 cherokee_server_t *srv = CONN_SRV(conn); 209 uint32_t header_len; 210 size_t crlf_len; 212 211 213 212 if (conn->io_entry_ref != NULL) { 214 cherokee_iocache_ mmap_release (srv->iocache,conn->io_entry_ref);215 conn->io_entry_ref = NULL; 213 cherokee_iocache_entry_unref (&conn->io_entry_ref); 214 conn->io_entry_ref = NULL; 216 215 } 217 216 … … 313 312 314 313 ret_t 315 cherokee_connection_mrproper (cherokee_connection_t *conn) 316 { 317 /* Close and clean socket, objects, etc. 318 * IGNORING ERRORS in order to not leave things 319 * in an uncleaned / undetermined state. 320 */ 321 conn->keepalive = 0; 322 314 cherokee_connection_clean_close (cherokee_connection_t *conn) 315 { 323 316 /* Close and clean the socket 324 317 */ … … 326 319 cherokee_socket_clean (&conn->socket); 327 320 321 /* Make sure the connection Keep-Alive is disabled 322 */ 323 conn->keepalive = 0; 324 cherokee_buffer_clean (&conn->incoming_header); 325 328 326 /* Clean the connection object 329 327 */ 330 328 cherokee_connection_clean (conn); 331 332 /* It is not a keep-alive connection, so we shouldn't333 * keep any previous header334 */335 cherokee_buffer_clean (&conn->incoming_header);336 337 329 return ret_ok; 338 330 } … … 386 378 */ 387 379 if (conn->io_entry_ref != NULL) { 388 cherokee_iocache_ mmap_release (srv->iocache,conn->io_entry_ref);380 cherokee_iocache_entry_unref (&conn->io_entry_ref); 389 381 } 390 382 … … 845 837 cherokee_connection_linger_read (cherokee_connection_t *conn) 846 838 { 847 ret_t ret; 848 int retries = 2; 849 cherokee_thread_t *thread = CONN_THREAD(conn); 850 cherokee_buffer_t *tmp1 = THREAD_TMP_BUF1(thread); 839 ret_t ret; 840 size_t cnt_read = 0; 841 int retries = 2; 842 cherokee_thread_t *thread = CONN_THREAD(conn); 843 cherokee_buffer_t *tmp1 = THREAD_TMP_BUF1(thread); 851 844 852 845 while (true) { 853 size_t cnt_read = 0;854 855 846 /* Read from the socket to nowhere 856 847 */ … … 868 859 case ret_ok: 869 860 TRACE(ENTRIES, "read %u, ok\n", cnt_read); 870 if (cnt_read == tmp1->size && --retries > 0) 861 retries--; 862 if (cnt_read == tmp1->size && retries > 0) 871 863 continue; 872 864 return ret; cherokee/trunk/cherokee/handler_cgi_base.c
r1614 r1673 722 722 /* Get the file information 723 723 */ 724 ret = cherokee_iocache_get_or_create_w_stat (srv->iocache, 725 &cgi->xsendfile, 726 &cached); 727 TRACE (ENTRIES, "iocache: %s, ret=%d\n", cgi->xsendfile.buf, ret); 724 if (srv->iocache) { 725 ret = cherokee_iocache_autoget (srv->iocache, 726 &cgi->xsendfile, 727 iocache_stat, 728 &cached); 729 TRACE (ENTRIES, "iocache: %s, ret=%d\n", 730 cgi->xsendfile.buf, ret); 731 } else { 732 ret = ret_no_sys; 733 } 734 728 735 switch (ret) { 729 736 case ret_ok: … … 751 758 cherokee_buffer_add_str (buffer, CRLF); 752 759 753 cherokee_iocache_mmap_release (srv->iocache, cached); 754 760 cherokee_iocache_entry_unref (&cached); 755 761 return ret_ok; 756 762 } cherokee/trunk/cherokee/handler_common.c
r1614 r1673 107 107 108 108 static ret_t 109 stat_file (cherokee_boolean_t useit, cherokee_iocache_t *iocache, struct stat *nocache_info, 110 cherokee_buffer_t *path, cherokee_iocache_entry_t **io_entry, struct stat **info) 109 stat_file (cherokee_boolean_t useit, 110 cherokee_iocache_t *iocache, 111 struct stat *nocache_info, 112 cherokee_buffer_t *path, 113 cherokee_iocache_entry_t **io_entry, 114 struct stat **info) 111 115 { 112 116 ret_t ret; … … 116 120 */ 117 121 if (useit) { 118 ret = cherokee_iocache_ get_or_create_w_stat (iocache, path, io_entry);119 TRACE (ENTRIES, "%s, use_iocache=1 re r=%d\n", path->buf, ret);122 ret = cherokee_iocache_autoget (iocache, path, iocache_stat, io_entry); 123 TRACE (ENTRIES, "%s, use_iocache=1 ret=%d\n", path->buf, ret); 120 124 121 125 switch (ret) { 122 126 case ret_ok: 127 case ret_deny: 123 128 *info = &(*io_entry)->state; 124 129 return ret_ok; 125 130 131 case ret_no_sys: 132 goto without; 133 126 134 case ret_not_found: 127 135 return ret_not_found; 128 129 case ret_no_sys:130 goto without;131 case ret_deny:132 return ret_deny;133 136 default: 134 137 return ret_error; 135 138 } 136 137 139 } 138 140 … … 161 163 162 164 165 163 166 ret_t 164 167 cherokee_handler_common_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_props_t *props) … … 168 171 struct stat nocache_info; 169 172 struct stat *info; 170 cherokee_iocache_entry_t * file= NULL;173 cherokee_iocache_entry_t *io_entry = NULL; 171 174 cherokee_iocache_t *iocache = NULL; 172 175 cherokee_boolean_t use_iocache = true; … … 184 187 */ 185 188 cherokee_buffer_add_buffer (&conn->local_directory, &conn->request); 186 187 cherokee_iocache_get_default (&iocache); 188 ret = stat_file (use_iocache, iocache, &nocache_info, &conn->local_directory, &file, &info); 189 190 if (use_iocache) 191 cherokee_iocache_get_default (&iocache); 192 193 ret = stat_file (use_iocache, iocache, &nocache_info, &conn->local_directory, &io_entry, &info); 189 194 exists = (ret == ret_ok); 190 195 … … 201 206 */ 202 207 if (! PROP_COMMON(props)->allow_pathinfo) { 208 TRACE(ENTRIES, "Returns conn->error_code: %s\n", "http_not_found"); 209 cherokee_iocache_entry_unref (&io_entry); 210 203 211 conn->error_code = http_not_found; 204 212 return ret_error; … … 212 220 ret = cherokee_split_pathinfo (&conn->local_directory, begin, true, &pathinfo, &pathinfo_len); 213 221 if ((ret == ret_not_found) || (pathinfo_len <= 0)) { 214 cherokee_iocache_mmap_release (iocache, file); 222 TRACE(ENTRIES, "Returns conn->error_code: %s\n", "http_not_found"); 223 cherokee_iocache_entry_unref (&io_entry); 224 215 225 conn->error_code = http_not_found; 216 226 return ret_error; … … 226 236 */ 227 237 cherokee_buffer_clean (&conn->local_directory); 228 cherokee_iocache_ mmap_release (iocache, file);238 cherokee_iocache_entry_unref (&io_entry); 229 239 230 240 TRACE_CONN(conn); … … 238 248 if (S_ISREG(info->st_mode)) { 239 249 TRACE (ENTRIES, "going for %s\n", "handler_file"); 250 cherokee_iocache_entry_unref (&io_entry); 251 240 252 return cherokee_handler_file_new (hdl, cnt, MODULE_PROPS(PROP_COMMON(props)->props_file)); 241 253 } … … 247 259 cherokee_list_t *i; 248 260 249 cherokee_iocache_ mmap_release (iocache, file);261 cherokee_iocache_entry_unref (&io_entry); 250 262 251 263 /* Maybe it has to be redirected … … 287 299 cherokee_buffer_add (new_local_dir, index, index_len); 288 300 289 ret = stat_file (use_iocache, iocache, &nocache_info, new_local_dir, & file, &info);301 ret = stat_file (use_iocache, iocache, &nocache_info, new_local_dir, &io_entry, &info); 290 302 exists = (ret == ret_ok); 291 cherokee_iocache_ mmap_release (iocache, file);303 cherokee_iocache_entry_unref (&io_entry); 292 304 293 305 if (!exists) … … 314 326 */ 315 327 cherokee_buffer_add (&conn->local_directory, index, index_len); 316 ret = stat_file (use_iocache, iocache, &nocache_info, &conn->local_directory, & file, &info);328 ret = stat_file (use_iocache, iocache, &nocache_info, &conn->local_directory, &io_entry, &info); 317 329 318 330 exists = (ret == ret_ok); 319 331 is_dir = ((ret == ret_ok) && S_ISDIR(info->st_mode)); 320 332 321 cherokee_iocache_ mmap_release (iocache, file);333 cherokee_iocache_entry_unref (&io_entry); 322 334 cherokee_buffer_drop_ending (&conn->local_directory, index_len); 323 335 … … 346 358 /* Unknown request type 347 359 */ 360 TRACE(ENTRIES, "Returns conn->error_code: %s\n", "http_internal_error"); 348 361 conn->error_code = http_internal_error; 362 349 363 SHOULDNT_HAPPEN; 350 364 return ret_error; cherokee/trunk/cherokee/handler_file.c
r1631 r1673 90 90 } 91 91 92 /* Post checks 93 */ 94 if (srv->iocache == NULL) 95 props->use_cache = false; 96 92 97 return ret_ok; 93 98 } … … 293 298 */ 294 299 fhdl->fd = open (local_file->buf, CHE_O_READ); 295 if (fhdl->fd > 0) return ret_ok; 300 if (fhdl->fd > 0) 301 return ret_ok; 296 302 297 303 /* Manage errors … … 324 330 /* I/O cache 325 331 */ 326 if (HDL_FILE_PROP(fhdl)->use_cache) { 327 ret = cherokee_iocache_get_or_create_w_stat (srv->iocache, local_file, io_entry); 332 if (srv->iocache && 333 HDL_FILE_PROP(fhdl)->use_cache) 334 { 335 ret = cherokee_iocache_autoget (srv->iocache, local_file, iocache_stat, io_entry); 328 336 TRACE (ENTRIES, "%s, use_iocache=1 ret=%d\n", local_file->buf, ret); 329 337 … … 380 388 ret_t ret; 381 389 char *ext; 390 cherokee_iocache_entry_t *io_entry = NULL; 382 391 cherokee_boolean_t use_io = false; 383 392 cherokee_connection_t *conn = HANDLER_CONN(fhdl); … … 386 395 /* Query the I/O cache 387 396 */ 388 ret = stat_local_directory (fhdl, local_file, & conn->io_entry_ref, &fhdl->info);389 if (ret != ret_ok) 390 return ret;397 ret = stat_local_directory (fhdl, local_file, &io_entry, &fhdl->info); 398 if (ret != ret_ok) 399 goto out; 391 400 392 401 /* Ensure it is a file … … 394 403 if (S_ISDIR(fhdl->info->st_mode)) { 395 404 conn->error_code = http_access_denied; 396 return ret_error; 405 ret = ret_error; 406 goto out; 397 407 } 398 408 … … 410 420 ret = check_cached (fhdl); 411 421 if ((ret != ret_ok) || (fhdl->not_modified)) 412 return ret;422 goto out; 413 423 414 424 /* Is this file cached in the io cache? 415 425 */ 416 use_io = ((conn->encoder == NULL) && 426 use_io = ((srv->iocache != NULL) && 427 (conn->encoder == NULL) && 417 428 (HDL_FILE_PROP(fhdl)->use_cache) && 418 429 (conn->socket.is_tls == non_TLS) && … … 424 435 425 436 if (use_io) { 426 ret = cherokee_iocache_get_or_create_w_mmap (srv->iocache, 427 local_file, 428 &conn->io_entry_ref, 429 &fhdl->fd); 437 ret = cherokee_iocache_autoget_fd (srv->iocache, 438 local_file, 439 iocache_mmap, 440 &fhdl->fd, 441 &io_entry); 430 442 431 443 TRACE (ENTRIES, "iocache looked up, local=%s ret=%d\n", … … 439 451 break; 440 452 default: 441 return ret_error;453 goto out; 442 454 } 443 455 } … … 445 457 /* Maybe open the file 446 458 */ 447 if ( (fhdl->fd < 0) && (!use_io)) {459 if (! use_io) { 448 460 ret = open_local_directory (fhdl, local_file); 449 461 if (ret != ret_ok) 450 return ret;462 goto out; 451 463 } 452 464 453 465 /* Is it a directory? 454 466 */ 455 if (S_ISDIR (fhdl->info->st_mode)) {467 if (S_ISDIR (fhdl->info->st_mode)) { 456 468 conn->error_code = http_access_denied; 457 return ret_error; 469 ret = ret_error; 470 goto out; 458 471 } 459 472 … … 464 477 conn->range_end = fhdl->info->st_size; 465 478 conn->error_code = http_range_not_satisfiable; 466 return ret_error; 479 ret = ret_error; 480 goto out; 467 481 } 468 482 … … 484 498 */ 485 499 if (use_io && 486 ( conn->io_entry_ref!= NULL) &&487 ( conn->io_entry_ref->mmaped != NULL)) {500 (io_entry != NULL) && 501 (io_entry->mmaped != NULL)) { 488 502 /* Set the mmap info 489 503 */ 490 conn->mmaped = conn->io_entry_ref->mmaped + conn->range_start; 491 conn->mmaped_len = conn->io_entry_ref->mmaped_len - 492 ( conn->range_start + 493 (conn->io_entry_ref->mmaped_len - conn->range_end)); 504 conn->io_entry_ref = io_entry; 505 506 conn->mmaped = io_entry->mmaped + conn->range_start; 507 conn->mmaped_len = io_entry->mmaped_len - 508 (conn->range_start + 509 (io_entry->mmaped_len - conn->range_end)); 494 510 } else { 511 /* Does no longer care about the io_entry 512 */ 513 cherokee_iocache_entry_unref (&io_entry); 514 495 515 /* Seek the file if needed 496 516 */ … … 516 536 517 537 return ret_ok; 538 539 out: 540 cherokee_iocache_entry_unref (&io_entry); 541 return ret; 518 542 } 519 543 cherokee/trunk/cherokee/iocache.c
r1654 r1673 26 26 #include "iocache.h" 27 27 28 #include "avl.h"29 #include "list.h"30 28 #include "buffer.h" 31 29 #include "server-protected.h" … … 49 47 #define ENTRIES "iocache" 50 48 51 #define FRESHNESS_TIME_STAT 300 52 #define FRESHNESS_TIME_MMAP 600 53 #define CACHE_SIZE 10 54 #define CACHE_SIZE_MAX 50 49 #define LASTING_MMAP 300 /* 5 mins */ 50 #define LASTING_STAT 300 /* 5 mins */ 55 51 56 52 #ifndef O_BINARY … … 67 63 typedef struct { 68 64 cherokee_iocache_entry_t base; 69 70 time_t stat_update; 71 time_t mmap_update; 72 cint_t ref_counter; 73 cint_t usages; 74 75 /* unref */ 76 cherokee_list_t to_be_deleted; 77 cherokee_buffer_t *name_ref; 65 time_t stat_expiration; 66 time_t mmap_expiration; 78 67 } cherokee_iocache_entry_extension_t; 79 80 81 struct cherokee_iocache {82 cherokee_server_t *srv;83 cherokee_avl_t files;84 cuint_t files_num;85 cuint_t files_max;86 cuint_t files_usages;87 CHEROKEE_MUTEX_T (files_lock);88 89 /* cleaning up stuff */90 float average;91 cherokee_list_t to_delete;92 };93 94 68 95 69 #define PUBL(o) ((cherokee_iocache_entry_t *)(o)) 96 70 #define PRIV(o) ((cherokee_iocache_entry_extension_t *)(o)) 97 71 72 /* Global I/O cache object 73 */ 98 74 99 75 static cherokee_iocache_t *global_io = NULL; 100 76 101 102 static ret_t 103 cherokee_iocache_new (cherokee_iocache_t **iocache, cherokee_server_t *srv) 104 { 105 CHEROKEE_NEW_STRUCT (n, iocache); 106 107 cherokee_avl_init (&n->files); 108 CHEROKEE_MUTEX_INIT (&n->files_lock, NULL); 109 110 n->files_num = 0; 111 n->files_max = CACHE_SIZE_MAX; 112 n->files_usages = 0; 113 n->srv = srv; 114 115 *iocache = n; 116 return ret_ok; 117 } 118 77 static ret_t 78 clean_info_cb (cherokee_cache_entry_t *entry) 79 { 80 cherokee_iocache_entry_t *ioentry = IOCACHE_ENTRY(entry); 81 82 TRACE (ENTRIES, "Cleaning cached info: '%s': %s\n", 83 entry->key.buf, ioentry->mmaped ? "mmap": "no mmap"); 84 85 if (ioentry->mmaped) { 86 munmap (ioentry->mmaped, ioentry->mmaped_len); 87 88 ioentry->mmaped = NULL; 89 ioentry->mmaped_len = 0; 90 } 91 92 return ret_ok; 93 } 94 95 static ret_t 96 fetch_info_cb (cherokee_cache_entry_t *entry) 97 { 98 UNUSED(entry); 99 return ret_ok; 100 } 101 102 static ret_t 103 free_cb (cherokee_cache_entry_t *entry) 104 { 105 UNUSED(entry); 106 return ret_ok; 107 } 108 109 110 static ret_t 111 iocache_entry_new_cb (cherokee_cache_t *cache, 112 cherokee_buffer_t *key, 113 void *param, 114 cherokee_cache_entry_t **ret_entry) 115 { 116 CHEROKEE_NEW_STRUCT(n, iocache_entry_extension); 117 118 UNUSED(cache); 119 UNUSED(param); 120 121 /* Init its parent class 122 */ 123 cherokee_cache_entry_init (CACHE_ENTRY(n), key); 124 125 /* Set the virtual methods 126 */ 127 CACHE_ENTRY(n)->clean_cb = clean_info_cb; 128 CACHE_ENTRY(n)->fetch_cb = fetch_info_cb; 129 CACHE_ENTRY(n)->free_cb = free_cb; 130 131 /* Init its properties 132 */ 133 PRIV(n)->stat_expiration = 0; 134 PRIV(n)->mmap_expiration = 0; 135 PUBL(n)->mmaped = NULL; 136 PUBL(n)->mmaped_len = 0; 137 138 /* Return the new object 139 */ 140 *ret_entry = CACHE_ENTRY(n); 141 return ret_ok; 142 } 119 143 120 144 ret_t 121 cherokee_iocache_ new_default (cherokee_iocache_t **iocache, cherokee_server_t *srv)145 cherokee_iocache_init (cherokee_iocache_t *iocache) 122 146 { 123 147 ret_t ret; 124 148 125 ret = cherokee_iocache_get_default (iocache); 126 if (unlikely (ret != ret_ok)) return ret_ok; 127 128 (*iocache)->srv = srv; 129 return ret_ok; 130 } 131 149 /* Init the parent (cache policy) class 150 */ 151 ret = cherokee_cache_init (CACHE(iocache)); 152 if (ret != ret_ok) 153 return ret; 154 155 /* Init its virtual methods 156 */ 157 CACHE(iocache)->new_cb = iocache_entry_new_cb; 158 CACHE(iocache)->new_cb_param = NULL; 159 160 return ret_ok; 161 } 162 163 ret_t 164 cherokee_iocache_mrproper (cherokee_iocache_t *iocache) 165 { 166 return cherokee_cache_mrproper (CACHE(iocache)); 167 } 132 168 133 169 ret_t … … 137 173 138 174 if (global_io == NULL) { 139 ret = cherokee_iocache_new (&global_io, NULL); 140 if (unlikely (ret != ret_ok)) return ret; 175 CHEROKEE_NEW_STRUCT (n, iocache); 176 177 ret = cherokee_iocache_init (n); 178 if (ret != ret_ok) 179 return ret; 180 181 global_io = n; 141 182 } 142 183 … … 145 186 } 146 187 147 148 static ret_t 149 iocache_entry_new (cherokee_iocache_entry_t **entry) 150 { 151 CHEROKEE_NEW_STRUCT(n, iocache_entry_extension); 152 153 PRIV(n)->stat_update = 0; 154 PRIV(n)->mmap_update = 0; 155 PRIV(n)->usages = 0; 156 PRIV(n)->ref_counter = 0; 157 158 PRIV(n)->name_ref = NULL; 159 INIT_LIST_HEAD(&PRIV(n)->to_be_deleted); 160 161 PUBL(n)->mmaped = NULL; 162 PUBL(n)->mmaped_len = 0; 163 164 *entry = PUBL(n); 165 return ret_ok; 166 } 167 168 static ret_t 169 iocache_entry_free (cherokee_iocache_entry_t *entry) 170 { 171 /* Free the object 188 ret_t 189 cherokee_iocache_free_default (void) 190 { 191 ret_t ret; 192 193 if (global_io == NULL) 194 return ret_ok; 195 196 ret = cherokee_iocache_mrproper (global_io); 197 if (ret != ret_ok) 198 return ret; 199 200 free (global_io); 201 return ret_ok; 202 } 203 204 205 /* Cache entry objects 206 */ 207 208 ret_t 209 cherokee_iocache_entry_unref (cherokee_iocache_entry_t **entry) 210 { 211 return cherokee_cache_entry_unref ((cherokee_cache_entry_t **)entry); 212 } 213 214 static ret_t 215 ioentry_update_stat (cherokee_iocache_entry_t *entry) 216 { 217 int re; 218 ret_t ret; 219 220 if (PRIV(entry)->stat_expiration >= cherokee_bogonow_now) { 221 TRACE (ENTRIES, "Update stat: %s: updated - skipped\n", 222 CACHE_ENTRY(entry)->key.buf); 223 return ret_ok; 224 } 225 226 /* Update stat 227 */ 228 re = cherokee_stat (CACHE_ENTRY(entry)->key.buf, &entry->state); 229 if (re < 0) { 230 TRACE(ENTRIES, "Couldn't update stat: %s: errno=%d\n", 231 CACHE_ENTRY(entry)->key.buf, re); 232 233 switch (errno) { 234 case EACCES: 235 ret = ret_deny; 236 goto error; 237 case ENOENT: 238 ret = ret_not_found; 239 goto error; 240 default: 241 break; 242 } 243 244 return ret_error; 245 } 246 247 TRACE (ENTRIES, "Updated stat: %s\n", CACHE_ENTRY(entry)->key.buf); 248 249 PRIV(entry)->stat_expiration = cherokee_bogonow_now + LASTING_STAT; 250 return ret_ok; 251 252 error: 253 return ret; 254 } 255 256 static ret_t 257 ioentry_update_mmap (cherokee_iocache_entry_t *entry, 258 int *fd) 259 { 260 ret_t ret; 261 int fd_local = -1; 262 cherokee_buffer_t *filename = &CACHE_ENTRY(entry)->key; 263 264 /* Short path 265 */ 266 if (PRIV(entry)->mmap_expiration >= cherokee_bogonow_now) { 267 TRACE(ENTRIES, "Update mmap: %s: updated - skipped\n", filename->buf); 268 return ret_ok; 269 } 270 271 /* Check the fd 272 */ 273 if (fd != NULL) 274 fd_local = *fd; 275 276 /* Only map regular files 277 */ 278 if (unlikely (! S_ISREG(entry->state.st_mode))) { 279 TRACE(ENTRIES, "Not a regular file: %s\n", filename->buf); 280 ret = ret_deny; 281 goto error; 282 } 283 284 /* Maybe it is already opened 285 */ 286 if (fd_local < 0) { 287 fd_local = open (filename->buf, (O_RDONLY | O_BINARY)); 288 if (unlikely (fd_local < 0)) { 289 TRACE(ENTRIES, "Couldn't open(): %s\n", filename->buf); 290 ret = ret_error; 291 goto error; 292 } 293 294 if (fd != NULL) 295 *fd = fd_local; 296 } 297 298 /* Might need to free the previous mmap 172 299 */ 173 300 if (entry->mmaped != NULL) { 301 TRACE(ENTRIES, "Cleaning previos mmap: %s\n", filename->buf); 174 302 munmap (entry->mmaped, entry->mmaped_len); 175 303 … … 178 306 } 179 307 180 /* Free the entry object 181 */ 182 free (entry); 183 return ret_ok; 184 } 185 186 static ret_t 187 iocache_entry_ref (cherokee_iocache_entry_t *entry) 188 { 189 PRIV(entry)->ref_counter++; 190 return ret_ok; 191 } 192 193 194 static ret_t 195 iocache_entry_unref (cherokee_iocache_entry_t *entry) 196 { 197 cherokee_iocache_entry_extension_t *priv = PRIV(entry); 198 199 priv->ref_counter--; 200 if (priv->ref_counter > 0) 201 return ret_eagain; 202 203 return ret_ok; 204 } 205 206 207 static ret_t 208 iocache_free_entry (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry) 209 { 210 ret_t ret; 211 212 ret = iocache_entry_free (entry); 213 214 /* Update the obj counter 215 */ 216 iocache->files_num--; 217 218 return ret; 219 } 220 221 222 static ret_t 223 iocache_entry_update_stat (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry, cherokee_buffer_t *filename) 224 { 225 int re; 226 227 re = cherokee_stat (filename->buf, &entry->state); 228 if (re < 0) { 229 TRACE(ENTRIES, "Couldn't update stat: errno=%d\n", re); 230 231 switch (errno) { 232 case EACCES: 233 return ret_deny; 234 case ENOENT: 235 return ret_not_found; 236 default: 237 break; 238 } 239 240 return ret_error; 241 } 242 243 PRIV(entry)->stat_update = cherokee_bogonow_now; 244 return ret_ok; 245 } 246 247 248 static ret_t 249 iocache_entry_update_mmap (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry, cherokee_buffer_t *filename, int fd, int *ret_fd) 250 { 251 ret_t ret; 252 253 TRACE(ENTRIES, "Update mmap: %s\n", filename->buf); 254 255 /* The stat information has to be fresh enough 256 */ 257 if (cherokee_bogonow_now >= (PRIV(entry)->stat_update + FRESHNESS_TIME_STAT)) { 258 ret = iocache_entry_update_stat (iocache, entry, filename); 259 if (ret != ret_ok) return ret; 260 } 261 262 /* Only map regular files 263 */ 264 if (unlikely (! S_ISREG(entry->state.st_mode))) { 265 TRACE(ENTRIES, "Not a regular file: %s\n", filename->buf); 266 return ret_deny; 267 } 268 269 /* Maybe it is already opened 270 */ 271 if (fd < 0) { 272 fd = open (filename->buf, O_RDONLY|O_BINARY); 273 if (unlikely (fd < 0)) { 274 TRACE(ENTRIES, "Couldn't open(): %s\n", filename->buf); 275 return ret_error; 276 } 277 } 278 279 *ret_fd = fd; 280 281 /* Might need to free the previous mmap 282 */ 283 if (entry->mmaped != NULL) { 284 munmap (entry->mmaped, entry->mmaped_len); 285 286 entry->mmaped = NULL; 287 entry->mmaped_len = 0; 288 } 289 290 /* Do it 308 /* Map the file into memory 291 309 */ 292 310 entry->mmaped = … … 295 313 PROT_READ, /* int prot */ 296 314 MAP_OPTIONS, /* int flag */ 297 fd ,/* int fd */315