Changeset 771

Show
Ignore:
Timestamp:
06/14/07 01:03:21 (1 year ago)
Author:
alo
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cherokee/trunk/ChangeLog

    r770 r771  
     12007-06-13  Alvaro Lopez Ortega  <alvaro@alobbs.com> 
     2 
     3        * cherokee/handler_common.c, cherokee/macros.h, 
     4        cherokee/handler_file.c, cherokee/Makefile.am, cherokee/table.h, 
     5        cherokee//cherokee.h, cherokee/iocache.c, cherokee/connection.c, 
     6        cherokee/iocache.h, cherokee/server.c: Many changes that aim to 
     7        fix the IOcache class. It is still failing though, this is the 
     8        first approach to solve the problem, but there is still work to be 
     9        done. 
     10 
    1112007-05-11  A.D.F  <adefacc@tin.it> 
    212 
  • cherokee/trunk/cherokee/Makefile.am

    r723 r771  
    913913header.h \ 
    914914resolv_cache.h \ 
     915post.h \ 
    915916\ 
    916917server.h \ 
  • cherokee/trunk/cherokee/cherokee.h

    r597 r771  
    4444#include <cherokee/header.h> 
    4545#include <cherokee/resolv_cache.h> 
     46#include <cherokee/post.h> 
    4647 
    4748/* Server library 
  • cherokee/trunk/cherokee/connection.c

    r769 r771  
    109109        n->realm_ref         = NULL; 
    110110        n->mmaped            = NULL; 
     111        n->mmaped_len        = 0; 
    111112        n->io_entry_ref      = NULL; 
    112113        n->thread            = NULL; 
     
    217218        if (conn->io_entry_ref != NULL) { 
    218219                cherokee_iocache_mmap_release (srv->iocache, conn->io_entry_ref); 
    219                 conn->io_entry_ref = NULL;              
     220                conn->io_entry_ref = NULL;       
    220221        } 
    221222#endif 
     
    234235        conn->realm_ref         = NULL; 
    235236        conn->mmaped            = NULL; 
     237        conn->mmaped_len        = 0; 
    236238        conn->rx                = 0;     
    237239        conn->tx                = 0; 
     
    334336         */ 
    335337        cherokee_socket_close (&conn->socket); 
    336  
    337338        cherokee_socket_clean (&conn->socket); 
    338339 
     
    396397        /* Nothing should be mmaped any longer 
    397398         */ 
    398         if (conn->mmaped != NULL) { 
     399        if (conn->io_entry_ref != NULL) { 
    399400#ifndef CHEROKEE_EMBEDDED 
    400401                ret = cherokee_iocache_mmap_release (srv->iocache, conn->io_entry_ref); 
    401                 conn->mmaped       = NULL; 
    402                 conn->io_entry_ref = NULL; 
    403402#endif 
    404403        } 
     404 
     405        conn->io_entry_ref = NULL; 
     406        conn->mmaped       = NULL; 
     407        conn->mmaped_len   = 0; 
    405408 
    406409        return ret; 
  • cherokee/trunk/cherokee/handler_file.c

    r639 r771  
    314314        cherokee_server_t *srv = CONN_SRV(conn); 
    315315 
    316         /* Without cache 
    317          */ 
    318         if (! HDL_FILE_PROP(fhdl)->use_cache) { 
    319                 re = stat (conn->local_directory.buf, &fhdl->cache_info); 
    320                 if (re < 0) { 
    321                         switch (errno) { 
    322                         case ENOENT:  
    323                                 conn->error_code = http_not_found; 
    324                                 break; 
    325                         case EACCES:  
    326                                 conn->error_code = http_access_denied; 
    327                                 break; 
    328                         default:      
    329                                 conn->error_code = http_internal_error; 
    330                         } 
    331  
    332                         cherokee_buffer_drop_endding (&conn->local_directory, conn->request.len); 
    333                         return ret_error; 
    334                 } 
    335  
    336                 *info = &fhdl->cache_info;               
    337                 return ret_ok; 
    338         }  
    339  
    340316        /* I/O cache 
    341317         */ 
    342318#ifndef CHEROKEE_EMBEDDED 
    343         ret = cherokee_iocache_stat_get (srv->iocache, conn->local_directory.buf, io_entry); 
    344         if (ret != ret_ok) { 
     319        if (HDL_FILE_PROP(fhdl)->use_cache) { 
     320               ret = cherokee_iocache_get_or_create_w_stat (srv->iocache, conn->local_directory.buf, io_entry); 
    345321                switch (ret) { 
     322                case ret_ok: 
     323                        *info = &(*io_entry)->state; 
     324                        return ret_ok; 
     325 
     326                case ret_no_sys: 
     327                        goto without; 
     328 
    346329                case ret_not_found: 
    347330                        conn->error_code = http_not_found; 
     
    354337                } 
    355338                 
    356                 cherokee_buffer_drop_endding (&conn->local_directory, conn->request.len); 
    357339                return ret_error;                
    358340        } 
    359  
    360         *info = &(*io_entry)->state; 
    361         return ret_ok; 
    362341#endif  
     342 
     343        /* Without cache 
     344         */ 
     345without: 
     346        re = stat (conn->local_directory.buf, &fhdl->cache_info); 
     347        if (re >= 0) { 
     348                *info = &fhdl->cache_info;               
     349                return ret_ok; 
     350        } 
     351 
     352        switch (errno) { 
     353        case ENOENT:  
     354                conn->error_code = http_not_found; 
     355                break; 
     356        case EACCES:  
     357                conn->error_code = http_access_denied; 
     358                break; 
     359        default:      
     360                conn->error_code = http_internal_error; 
     361        } 
    363362 
    364363        return ret_error; 
     
    371370        ret_t                     ret; 
    372371        cherokee_boolean_t        use_io   = false; 
    373         cherokee_iocache_entry_t *io_entry = NULL; 
    374372        cherokee_connection_t    *conn     = HANDLER_CONN(fhdl); 
    375373        cherokee_server_t        *srv      = HANDLER_SRV(fhdl); 
     
    384382        /* Query the I/O cache 
    385383         */ 
    386         ret = stat_local_directory (fhdl, conn, &io_entry, &fhdl->info); 
    387         if (ret != ret_ok) return ret; 
     384        ret = stat_local_directory (fhdl, conn, &conn->io_entry_ref, &fhdl->info); 
     385        if (ret != ret_ok) { 
     386                cherokee_buffer_drop_endding (&conn->local_directory, conn->request.len);                
     387                return ret; 
     388        } 
    388389 
    389390        /* Ensure it is a file 
     
    430431         
    431432        if (use_io) { 
    432                 ret = cherokee_iocache_mmap_lookup (srv->iocache, 
    433                                                     conn->local_directory.buf, 
    434                                                     &io_entry); 
    435  
    436                 TRACE(ENTRIES, "iocache looked up, local=%s ret=%d\n", conn->local_directory.buf, ret); 
    437                          
    438                 if ((ret != ret_ok) ||  
    439                     (io_entry->mmaped == NULL)) 
    440                 { 
    441                         /* Open fhdl->fd 
    442                          */ 
    443                         ret = open_local_directory (fhdl, conn); 
    444                         if (ret != ret_ok) { 
    445                                 cherokee_buffer_drop_endding (&conn->local_directory, conn->request.len); 
    446                                 return ret; 
    447                         } 
    448  
    449                         /* Map the file 
    450                          */ 
    451                         ret = cherokee_iocache_mmap_get_w_fd (srv->iocache, 
    452                                                               conn->local_directory.buf, 
    453                                                               fhdl->fd, 
    454                                                               &io_entry); 
    455  
    456                         TRACE(ENTRIES, "Got it from the iocache fd=%d, entry=%p\n", fhdl->fd, io_entry); 
    457                 } 
    458  
    459                 if (ret == ret_ok) { 
    460                         conn->io_entry_ref = io_entry; 
     433//              if (conn->io_entry_ref) 
     434//                      cherokee_iocache_mmap_release (srv->iocache, conn->io_entry_ref); 
     435                ret = cherokee_iocache_get_or_create_w_mmap (srv->iocache, 
     436                                                             conn->local_directory.buf, 
     437                                                             &conn->io_entry_ref,  
     438                                                             &fhdl->fd); 
     439 
     440                TRACE (ENTRIES, "iocache looked up, local=%s ret=%d\n",  
     441                       conn->local_directory.buf, ret); 
     442 
     443                switch (ret) { 
     444                case ret_ok: 
     445                        break; 
     446                case ret_no_sys: 
     447                        use_io = false; 
     448                        break; 
     449                default: 
     450                        cherokee_buffer_drop_endding (&conn->local_directory, conn->request.len); 
     451                        return ret_error; 
    461452                } 
    462453        } 
     
    511502        /* Set mmap or file position 
    512503         */ 
    513         if (conn->io_entry_ref != NULL) { 
     504        if ((conn->io_entry_ref != NULL) && 
     505            (conn->io_entry_ref->mmaped != NULL))  
     506        { 
    514507                /* Set the mmap info 
    515508                 */ 
     
    549542{ 
    550543        ret_t                  ret; 
    551         size_t                 szlen = 0; 
     544        char                   bufstr[DTM_SIZE_GMTTM_STR]; 
     545        size_t                 szlen          = 0; 
    552546        off_t                  content_length = 0; 
    553         struct tm              modified_tm = { 0 }; 
    554         char                   bufstr[DTM_SIZE_GMTTM_STR]; 
    555         cherokee_connection_t *conn         = HANDLER_CONN(fhdl); 
     547        struct tm              modified_tm    = { 0 }; 
     548        cherokee_connection_t *conn           = HANDLER_CONN(fhdl); 
    556549 
    557550        /* ETag: 
  • cherokee/trunk/cherokee/iocache.c

    r597 r771  
    4747 
    4848 
    49 #define FRESHNESS_TIME 600 
    50 #define CACHE_SIZE      10 
     49#define FRESHNESS_TIME_STAT 300 
     50#define FRESHNESS_TIME_MMAP 600 
     51#define CACHE_SIZE          10 
     52#define CACHE_SIZE_MAX      50 
    5153 
    5254#ifndef O_BINARY 
     
    6365typedef struct { 
    6466        cherokee_iocache_entry_t base; 
     67 
     68        /* check 1 */ 
     69        cuint_t                  test1; 
     70 
    6571        time_t                   stat_update; 
    6672        time_t                   mmap_update; 
    6773        cint_t                   ref_counter; 
    6874        cint_t                   usages; 
    69         CHEROKEE_MUTEX_T        (lock); 
     75 
     76        /* unref */ 
     77        cherokee_list_t          to_be_deleted; 
     78        const char              *name_ref; 
     79 
     80        /* check 2 */ 
     81        cuint_t                  test2; 
    7082} cherokee_iocache_entry_extension_t; 
    7183 
     
    7587        cherokee_table_t   files; 
    7688        cuint_t            files_num; 
     89        cuint_t            files_max; 
    7790        cuint_t            files_usages; 
    7891        CHEROKEE_MUTEX_T  (files_lock); 
     
    102115 
    103116 
    104 ret_t  
     117static ret_t  
    105118cherokee_iocache_new (cherokee_iocache_t **iocache, cherokee_server_t *srv) 
    106119{ 
     
    110123        CHEROKEE_MUTEX_INIT (&n->files_lock, NULL); 
    111124 
    112         n->files_num    = 0; 
    113         n->files_usages = 0; 
     125        n->files_num     = 0; 
     126        n->files_max     = CACHE_SIZE_MAX; 
     127        n->files_usages  = 0; 
     128        n->srv           = srv; 
    114129 
    115130        *iocache = n; 
     
    146161 
    147162 
    148 static int 
    149 iocache_clean_up_each (const char *key, void *value, void *param) 
    150 { 
    151         clean_up_params_t        *params = param; 
    152         cherokee_iocache_entry_t *file   = IOCACHE_ENTRY(value);  
    153         to_delete_entry_t        *delobj; 
    154         float                     usage; 
    155  
    156         /* Reset usage 
    157          */ 
    158         usage = (float) PRIV(file)->usages; 
    159         PRIV(file)->usages = 0; 
    160  
    161         /* Is it in use? 
    162          */ 
    163         if (PRIV(file)->ref_counter > 0) { 
    164                 return true; 
    165         } 
    166  
    167         if ((usage == -1) || 
    168             (usage <= params->average)) 
    169         { 
    170                 /* Add to the removal list 
    171                  */ 
    172                 delobj = malloc (sizeof (to_delete_entry_t)); 
    173                 INIT_LIST_HEAD (&delobj->list);  
    174                  
    175                 delobj->file     = file; 
    176                 delobj->filename = key; 
    177                  
    178                 cherokee_list_add (LIST(delobj), &params->to_delete); 
    179         } 
    180  
    181         return true; 
    182 } 
    183  
    184  
    185163static ret_t 
    186164iocache_entry_new (cherokee_iocache_entry_t **entry) 
     
    191169        PRIV(n)->mmap_update = 0; 
    192170        PRIV(n)->usages      = 0; 
    193         PRIV(n)->ref_counter = 1; 
    194          
    195         CHEROKEE_MUTEX_INIT (&PRIV(n)->lock, NULL); 
     171        PRIV(n)->ref_counter = 0; 
     172 
     173        PRIV(n)->name_ref    = NULL; 
     174        INIT_LIST_HEAD(&PRIV(n)->to_be_deleted); 
    196175 
    197176        PUBL(n)->mmaped      = NULL; 
    198177        PUBL(n)->mmaped_len  = 0; 
    199178 
     179        PRIV(n)->test1    = 123456; 
     180        PRIV(n)->test2    = 987654; 
     181 
    200182        *entry = PUBL(n); 
    201183        return ret_ok; 
     
    204186 
    205187static ret_t 
    206 iocache_entry_free (cherokee_iocache_entry_t *entry) 
    207 
     188iocache_entry_ref (cherokee_iocache_entry_t *entry) 
     189
     190        PRIV(entry)->ref_counter++; 
     191        return ret_ok; 
     192
     193 
     194 
     195static ret_t 
     196iocache_entry_unref (cherokee_iocache_entry_t *entry) 
     197
     198        cherokee_iocache_entry_extension_t *priv = PRIV(entry); 
     199 
     200        priv->ref_counter--;     
     201        if (priv->ref_counter > 0) 
     202                return ret_eagain; 
     203 
     204        return ret_ok; 
     205
     206 
     207 
     208static ret_t 
     209iocache_free_entry (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry) 
     210
     211        /* Free the object 
     212         */ 
    208213        if (entry->mmaped != NULL) { 
    209214                munmap (entry->mmaped, entry->mmaped_len); 
     
    213218        } 
    214219 
    215         CHEROKEE_MUTEX_DESTROY (&PRIV(entry)->lock); 
    216  
     220        PRIV(entry)->test1 = 0; 
     221        PRIV(entry)->test2 = 0; 
     222 
     223        /* Free the entry object 
     224         */ 
    217225        free (entry); 
    218         return ret_ok; 
    219 
    220  
    221  
    222 static ret_t 
    223 iocache_entry_update_stat (cherokee_iocache_entry_t *entry, char *filename, cherokee_iocache_t *iocache) 
     226 
     227        /* Update the obj counter 
     228         */ 
     229        iocache->files_num--; 
     230 
     231        return ret_ok; 
     232
     233 
     234 
     235static ret_t 
     236iocache_entry_update_stat (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry, char *filename) 
    224237{ 
    225238        int re; 
     
    245258 
    246259static ret_t 
    247 iocache_entry_update_mmap (cherokee_iocache_entry_t *entry, char *filename, int fd, cherokee_iocache_t *iocache) 
    248 
    249         ret_t              ret; 
    250         cherokee_boolean_t do_close = false; 
     260iocache_entry_update_mmap (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry, char *filename, int fd, int *ret_fd) 
     261
     262        ret_t ret; 
    251263 
    252264        /* The stat information has to be fresh enough 
    253265         */ 
    254         if (iocache->srv->bogo_now >= (PRIV(entry)->stat_update + FRESHNESS_TIME)) { 
    255                 ret = iocache_entry_update_stat (entry, filename, iocache); 
     266        if (iocache->srv->bogo_now >= (PRIV(entry)->stat_update + FRESHNESS_TIME_STAT)) { 
     267                ret = iocache_entry_update_stat (iocache, entry, filename); 
    256268                if (ret != ret_ok) return ret; 
    257269        } 
    258270 
    259         /* Directories can not be mmaped 
    260          */ 
    261         if (unlikely (S_ISDIR(entry->state.st_mode))) { 
     271        /* Only map regular files 
     272         */ 
     273        if (unlikely (! S_ISREG(entry->state.st_mode))) { 
    262274                return ret_deny; 
    263275        } 
    264276 
    265         /* Maybe open 
     277        /* Maybe it is already opened 
    266278         */ 
    267279        if (fd < 0) { 
    268280                fd = open (filename, O_RDONLY|O_BINARY); 
    269281                if (unlikely (fd < 0)) return ret_error; 
    270  
    271                 do_close = true; 
    272         } 
    273  
    274         /* Free previous mmap 
     282        } 
     283 
     284        *ret_fd = fd; 
     285 
     286        /* Might need to free the previous mmap 
    275287         */ 
    276288        if (entry->mmaped != NULL) { 
     
    292304 
    293305        if (entry->mmaped == MAP_FAILED) { 
    294                 return ret_not_found; 
     306                int err = errno; 
     307                switch (err) { 
     308                case EAGAIN: 
     309                case ENOMEM: 
     310                case ENFILE: 
     311                        return ret_eagain; 
     312                default:  
     313                        return ret_not_found; 
     314                } 
    295315        } 
    296316 
     
    298318        PRIV(entry)->mmap_update = iocache->srv->bogo_now; 
    299319 
    300         /* Has it to close 
    301          */ 
    302         if (do_close) { 
    303                 close (fd); 
    304         } 
    305  
    306         return ret_ok; 
     320        return ret_ok; 
     321
     322 
     323 
     324static ret_t 
     325iocache_entry_maybe_update_mmap (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *entry, char *filename, int fd, int *ret_fd) 
     326
     327        cherokee_boolean_t update; 
     328 
     329        /* Update mmap only if.. 
     330         * - It is not refered and either: 
     331         *   - It has no mmap 
     332         *   - It is old 
     333         */ 
     334        update  = (entry->mmaped == NULL); 
     335        update |= (iocache->srv->bogo_now >= (PRIV(entry)->mmap_update + FRESHNESS_TIME_MMAP)); 
     336        update &= (PRIV(entry)->ref_counter <= 1); 
     337 
     338        if (! update) 
     339                return ret_deny; 
     340 
     341        return iocache_entry_update_mmap (iocache, entry, filename, fd, ret_fd); 
     342
     343 
     344 
     345static void 
     346test_entry (cherokee_iocache_entry_t *file, char *p)  
     347
     348        if (!file) { 
     349                printf ("%s: NULLLLLLLLL!", p); 
     350                exit(1); 
     351        } 
     352 
     353        if (PRIV(file)->test1 != 123456) { 
     354                printf ("%s: wasn't an obj %p\n", p, file); 
     355                exit(1); 
     356        } 
     357 
     358        if (PRIV(file)->test2 != 987654) { 
     359                printf ("%s: wasn't an obj2 %p\n", p, file); 
     360                exit(1); 
     361        } 
     362
     363 
     364 
     365static int 
     366iocache_clean_up_each (const char *key, void *value, void *param) 
     367
     368        float                               usage; 
     369        clean_up_params_t                  *params = param; 
     370        cherokee_iocache_entry_t           *file   = IOCACHE_ENTRY(value);  
     371        cherokee_iocache_entry_extension_t *entry  = PRIV(value); 
     372 
     373        test_entry (file, "clean_up_each"); 
     374         
     375        /* Reset usage value 
     376         */ 
     377        usage = (float) entry->usages; 
     378        entry->usages = 0; 
     379 
     380        /* Is it in use or worth keeping? 
     381         */ 
     382        if ((entry->ref_counter > 0) || 
     383            (usage > params->average))  
     384        { 
     385                goto out; 
     386        } 
     387 
     388        /* Then, it should be deleted 
     389         */ 
     390        entry->name_ref = key; 
     391        cherokee_list_add (&entry->to_be_deleted, &params->to_delete); 
     392 
     393out: 
     394        return false; 
    307395} 
    308396 
     
    311399cherokee_iocache_clean_up (cherokee_iocache_t *iocache, cuint_t num) 
    312400{ 
     401        ret_t              ret; 
    313402        float              average; 
    314403        clean_up_params_t  params; 
    315404        cherokee_list_t   *i, *tmp; 
    316          
     405 
     406        CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
     407 
    317408        if (iocache->files_num < CACHE_SIZE) 
    318                 return ret_ok; 
    319  
    320         average = (iocache->files_usages / iocache->files_num)
     409                goto ok; 
     410 
     411        average = (iocache->files_usages / iocache->files_num) + 1
    321412 
    322413        params.iocache = iocache; 
     
    335426         */ 
    336427        list_for_each_safe (i, tmp, &params.to_delete) { 
    337                 to_delete_entry_t *delobj = (to_delete_entry_t *)i; 
    338  
    339                 cherokee_table_del (&iocache->files, (char *)delobj->filename, NULL); 
    340                 iocache->files_num--; 
    341  
    342                 iocache_entry_free (delobj->file); 
    343                 free (delobj); 
    344         } 
     428                cherokee_iocache_entry_extension_t *entry; 
     429 
     430                entry = list_entry (i, cherokee_iocache_entry_extension_t, to_be_deleted); 
     431                cherokee_list_del (&entry->to_be_deleted); 
     432 
     433                test_entry (entry, "clean_up_for"); 
     434 
     435                ret = cherokee_table_del (&iocache->files, (char *)entry->name_ref, NULL); 
     436                if (unlikely (ret != ret_ok)) { 
     437                        return ret; 
     438                } 
     439                iocache_free_entry (iocache, IOCACHE_ENTRY(entry)); 
     440        } 
     441 
    345442 
    346443        /* Reset statistics values 
     
    348445        iocache->files_usages = 0; 
    349446 
    350         return ret_ok; 
    351 
    352  
    353  
    354 ret_t  
     447ok: 
     448        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
     449        return ret_ok; 
     450
     451 
     452 
     453static ret_t 
     454free_while_func (const char *key, void *value, void *param) 
     455
     456        iocache_free_entry (IOCACHE(param), IOCACHE_ENTRY(value)); 
     457        return ret_ok; 
     458
     459 
     460 
     461static ret_t  
    355462cherokee_iocache_free (cherokee_iocache_t *iocache) 
    356463{ 
    357         cherokee_table_mrproper2 (&iocache->files, (cherokee_table_free_item_t)iocache_entry_free); 
     464        cherokee_table_while (&iocache->files,  
     465                              (cherokee_table_while_func_t)free_while_func,  
     466                              iocache, NULL, NULL); 
    358467 
    359468        CHEROKEE_MUTEX_DESTROY (&iocache->files_lock); 
     
    382491 
    383492 
     493ret_t 
     494cherokee_iocache_get_or_create_w_stat (cherokee_iocache_t *iocache, char *filename, cherokee_iocache_entry_t **ret_file) 
     495{ 
     496        ret_t                     ret; 
     497        cherokee_iocache_entry_t *entry; 
     498 
     499        CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
     500 
     501        /* Look inside the table 
     502         */ 
     503        ret = cherokee_table_get (&iocache->files, filename, (void **)ret_file); 
     504        if (ret != ret_ok) { 
     505                if (iocache->files_num >= iocache->files_max) { 
     506                        ret = ret_no_sys; 
     507                        goto error; 
     508                } 
     509 
     510                ret = iocache_entry_new (ret_file); 
     511                if (unlikely (ret != ret_ok)) goto error; 
     512 
     513                ret = cherokee_table_add (&iocache->files, filename, *ret_file); 
     514                if (unlikely (ret != ret_ok)) goto error_free; 
     515 
     516                iocache->files_num++; 
     517        }  
     518         
     519        /* Reference it 
     520         */ 
     521        entry = *ret_file; 
     522        hit (iocache, entry); 
     523        iocache_entry_ref(entry); 
     524         
     525        /* May update the stat info 
     526         */ 
     527        if (iocache->srv->bogo_now >= (PRIV(entry)->stat_update + FRESHNESS_TIME_STAT)) { 
     528                ret = iocache_entry_update_stat (iocache, entry, filename); 
     529                if (unlikely (ret != ret_ok)) goto error; 
     530        } 
     531 
     532        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
     533        return ret_ok; 
     534 
     535error_free: 
     536        free (*ret_file); 
     537        *ret_file = NULL; 
     538 
     539error: 
     540        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
     541        return ret; 
     542} 
     543 
     544 
    384545ret_t  
    385 cherokee_iocache_stat_get (cherokee_iocache_t *iocache, char *filename, cherokee_iocache_entry_t **file
     546cherokee_iocache_get_or_create_w_mmap (cherokee_iocache_t *iocache, char *filename, cherokee_iocache_entry_t **ret_file, int *ret_fd
    386547{ 
    387548        ret_t                     ret; 
    388         cherokee_iocache_entry_t *new
     549        cherokee_iocache_entry_t *entry
    389550 
    390551        CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
    391552 
    392         /* Look inside the table 
    393          */ 
    394         ret = cherokee_table_get (&iocache->files, filename, (void **)file); 
    395         if (ret == ret_ok) { 
    396                 new = *file; 
    397  
    398                 if (iocache->srv->bogo_now >= (PRIV(new)->stat_update + FRESHNESS_TIME)) { 
    399                         ret = iocache_entry_update_stat (new, filename, iocache); 
    400                         if (ret != ret_ok) { 
    401                                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    402                                 return ret; 
     553        /* Fetch or create the entry object 
     554         */ 
     555        if (*ret_file == NULL) { 
     556                ret = cherokee_table_get (&iocache->files, filename, (void **)ret_file); 
     557                if (ret != ret_ok) { 
     558                        if (iocache->files_num >= iocache->files_max) { 
     559                                ret = ret_no_sys; 
     560                                goto error; 
    403561                        } 
     562                         
     563                        ret = iocache_entry_new (ret_file); 
     564                        if (unlikely (ret != ret_ok)) goto error; 
     565                         
     566                        ret = cherokee_table_add (&iocache->files, filename, *ret_file); 
     567                        if (unlikely (ret != ret_ok)) goto error_free; 
     568                         
     569                        iocache->files_num++; 
    404570                } 
    405571 
    406                 hit (iocache, *file); 
    407                 PRIV(*file)->ref_counter++; 
    408  
    409                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    410                 return ret_ok; 
    411         } 
    412  
    413         /* Create a new entry 
    414          */ 
    415         iocache_entry_new (&new); 
    416  
    417         ret = iocache_entry_update_stat (new, filename, iocache); 
    418         if (ret != ret_ok) { 
    419                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    420                 iocache_entry_free(new); 
    421                 return ret; 
    422         } 
    423  
    424         /* Add to the table 
    425          */ 
    426         cherokee_table_add (&iocache->files, filename, (void *)new); 
    427         iocache->files_num++; 
    428  
    429         *file = new; 
    430         hit (iocache, new); 
     572                /* Reference the entry 
     573                 */ 
     574                iocache_entry_ref(*ret_file); 
     575        } 
     576 
     577        /* Update statistics 
     578         */ 
     579        entry = *ret_file; 
     580        hit (iocache, entry); 
     581 
     582        /* Try to update the mmaped memory 
     583         */ 
     584        ret = iocache_entry_maybe_update_mmap (iocache, entry, filename, -1, ret_fd); 
     585        switch (ret) { 
     586        case ret_ok: 
     587                /* Updated */  
     588                ret = ret_ok; 
     589                break; 
     590        case ret_deny: 
     591                /* Not updated */ 
     592                ret = ret_ok; 
     593                break; 
     594        case ret_eagain: 
     595                /* Tried, but failed  */ 
     596                ret = ret_no_sys; 
     597                break; 
     598        default: 
     599                goto error; 
     600        } 
    431601 
    432602        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    433         return ret_ok; 
    434 
    435  
    436  
    437 ret_t  
    438 cherokee_iocache_mmap_get_w_fd (cherokee_iocache_t *iocache, char *filename, int fd, cherokee_iocache_entry_t **file) 
    439 
    440         ret_t                     ret; 
    441         cherokee_iocache_entry_t *new; 
    442  
    443         CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
    444  
    445         /* Look inside the table 
    446          */ 
    447         ret = cherokee_table_get (&iocache->files, filename, (void **)file); 
    448         if (ret == ret_ok) { 
    449                 new = *file; 
    450  
    451                 if (iocache->srv->bogo_now >= (PRIV(new)->stat_update + FRESHNESS_TIME)) { 
    452                         ret = iocache_entry_update_stat (new, filename, iocache); 
    453                         if (ret != ret_ok) { 
    454                                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    455                                 return ret; 
    456                         } 
    457                 } 
    458  
    459                 if (iocache->srv->bogo_now >= (PRIV(new)->mmap_update + FRESHNESS_TIME)) { 
    460                         ret = iocache_entry_update_mmap (new, filename, fd, iocache); 
    461                         if (ret != ret_ok) { 
    462                                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    463                                 return ret; 
    464                         } 
    465                 } 
    466  
    467                 hit (iocache, new); 
    468                 PRIV(new)->ref_counter++; 
    469  
    470                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    471                 return ret_ok; 
    472         } 
    473  
    474         /* Create a new entry 
    475          */ 
    476         iocache_entry_new (&new); 
    477         iocache_entry_update_mmap (new, filename, fd, iocache); 
    478  
    479         /* Add to the table 
    480          */ 
    481         cherokee_table_add (&iocache->files, filename, new); 
    482         iocache->files_num++; 
    483  
    484         *file = new; 
    485         hit (iocache, new); 
    486  
     603        return ret; 
     604 
     605error_free: 
     606        free (*ret_file); 
     607        *ret_file = NULL; 
     608 
     609error: 
    487610        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    488         return ret_ok; 
    489 
    490  
    491  
    492 ret_t  
    493 cherokee_iocache_mmap_lookup (cherokee_iocache_t *iocache, char *filename, cherokee_iocache_entry_t **file) 
    494 
    495         ret_t                     ret; 
    496         cherokee_iocache_entry_t *new; 
    497  
    498         CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
    499  
    500         /* Look in the table 
    501          */ 
    502         ret = cherokee_table_get (&iocache->files, filename, (void **)file); 
    503         if (ret != ret_ok) { 
    504                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    505                 return ret; 
    506         } 
    507  
    508         new = *file; 
    509  
    510         /* Is it old? 
    511          */ 
    512         if (iocache->srv->bogo_now >= (PRIV(new)->mmap_update + FRESHNESS_TIME)) { 
    513                 CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    514                 return ret_eagain; 
    515         } 
    516  
    517         /* Return it 
    518          */ 
    519         hit (iocache, new); 
    520         PRIV(new)->ref_counter++; 
    521  
    522         CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    523         return ret_ok; 
    524 
    525  
    526  
    527 ret_t  
    528 cherokee_iocache_mmap_get (cherokee_iocache_t *iocache, char *filename, cherokee_iocache_entry_t **file) 
    529 
    530         return cherokee_iocache_mmap_get_w_fd (iocache, filename, -1, file); 
     611        return ret; 
    531612} 
    532613 
     
    535616cherokee_iocache_mmap_release (cherokee_iocache_t *iocache, cherokee_iocache_entry_t *file) 
    536617{ 
     618        ret_t ret; 
     619 
    537620        if (file == NULL) 
    538621                return ret_not_found; 
    539622 
    540623        CHEROKEE_MUTEX_LOCK (&iocache->files_lock); 
    541         PRIV(file)->ref_counter--
     624        ret = iocache_entry_unref (file)
    542625        CHEROKEE_MUTEX_UNLOCK (&iocache->files_lock); 
    543626 
    544         return ret_ok
    545 } 
     627        return ret
     628} 
  • cherokee/trunk/cherokee/iocache.h

    r597 r771  
    3636 
    3737typedef struct { 
    38         struct stat  state; 
    39         void        *mmaped; 
    40         size_t       mmaped_len; 
     38        struct stat       state; 
     39        void             *mmaped; 
     40        size_t            mmaped_len; 
    4141} cherokee_iocache_entry_t; 
    4242 
     
    4444#define IOCACHE_ENTRY(x) ((cherokee_iocache_entry_t *)(x)) 
    45