Changeset 180

Show
Ignore:
Timestamp:
03/07/06 12:57:49 (3 years ago)
Author:
bart
Message:

Set refcount to 1 before storing a zval in the usercache. This fixes bug #4.
Some formatting cleanups in cache.c
In restore_zval the zval length could be something else then 0 when an empty string was set.

Files:

Legend:

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

    r179 r180  
     12006-03-07  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
     2 
     3        * Set refcount to 1 before storing a zval in the usercache. This fixes 
     4          bug #4. 
     5        * Some formatting cleanups in cache.c 
     6        * In restore_zval the zval length could be something else then 0 when  
     7          an empty string was set. 
     8 
    192006-03-06  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
    210 
  • eaccelerator/trunk/cache.c

    • Property svn:keywords changed from Author Date Id Revision to svn:eol-style
    r178 r180  
    44   +----------------------------------------------------------------------+ 
    55   | Copyright (c) 2004 - 2006 eAccelerator                               | 
    6    | http://eaccelerator.net                                                     | 
     6   | http://eaccelerator.net                                              | 
    77   +----------------------------------------------------------------------+ 
    88   | This program is free software; you can redistribute it and/or        | 
     
    2323   | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            | 
    2424   +----------------------------------------------------------------------+ 
    25    $Id
     25   $Id: cache.c 178 2006-03-06 09:08:40Z bart
    2626*/ 
    2727 
     
    5050static char *build_key(const char *key, int key_len, int *xlen TSRMLS_DC) 
    5151{ 
    52        int len; 
    53  
    54        /* 
    55         * namespace  
    56         */ 
    57        len = strlen(EAG(name_space)); 
    58        if (len > 0) { 
    59                char *xkey; 
    60                *xlen = len + key_len + 1; 
    61                xkey = emalloc((*xlen) + 1); 
    62                memcpy(xkey, EAG(name_space), len); 
    63                xkey[len] = ':'; 
    64                memcpy(xkey + len + 1, key, key_len + 1); 
    65                return xkey; 
    66        
    67  
    68        /* 
    69         * hostname  
    70         */ 
    71        len = strlen(EAG (hostname)); 
    72        if (len > 0) { 
    73                char *xkey; 
    74                *xlen = len + key_len + 1; 
    75                xkey = emalloc((*xlen) + 1); 
    76                memcpy(xkey, EAG(hostname), len); 
    77                xkey[len] = ':'; 
    78                memcpy(xkey + len + 1, key, key_len + 1); 
    79                return xkey; 
    80        } else { 
    81                *xlen = key_len; 
    82                return (char *) key; 
    83        
     52    int len; 
     53 
     54    /* 
     55    * namespace  
     56    */ 
     57    len = strlen(EAG(name_space)); 
     58    if (len > 0) { 
     59        char *xkey; 
     60        *xlen = len + key_len + 1; 
     61        xkey = emalloc((*xlen) + 1); 
     62        memcpy(xkey, EAG(name_space), len); 
     63        xkey[len] = ':'; 
     64        memcpy(xkey + len + 1, key, key_len + 1); 
     65        return xkey; 
     66   
     67 
     68    /* 
     69    * hostname  
     70    */ 
     71    len = strlen(EAG(hostname)); 
     72    if (len > 0) { 
     73        char *xkey; 
     74        *xlen = len + key_len + 1; 
     75        xkey = emalloc((*xlen) + 1); 
     76        memcpy(xkey, EAG(hostname), len); 
     77        xkey[len] = ':'; 
     78        memcpy(xkey + len + 1, key, key_len + 1); 
     79        return xkey; 
     80    } else { 
     81        *xlen = key_len; 
     82        return (char *) key; 
     83   
    8484} 
    8585 
    8686/* lock the key cache */ 
    87 int eaccelerator_lock (const char *key, int key_len TSRMLS_DC) 
    88 { 
    89        int xlen; 
    90        char *xkey; 
    91        mm_lock_entry *x; 
    92        mm_lock_entry **p; 
    93        int ok = 0; 
    94  
    95        if (eaccelerator_mm_instance == NULL) 
    96                return 0; 
    97  
    98        xkey = build_key (key, key_len, &xlen TSRMLS_CC); 
    99        EACCELERATOR_UNPROTECT (); 
    100        x = eaccelerator_malloc (offsetof (mm_lock_entry, key) + xlen + 1); 
    101        if (x == NULL) { 
    102                EACCELERATOR_PROTECT (); 
    103                if (xlen != key_len) 
    104                        efree (xkey); 
    105  
    106                return 0; 
    107        
    108        x->pid = getpid (); 
     87int eaccelerator_lock(const char *key, int key_len TSRMLS_DC) 
     88{ 
     89    int xlen; 
     90    char *xkey; 
     91    mm_lock_entry *x; 
     92    mm_lock_entry **p; 
     93    int ok = 0; 
     94 
     95    if (eaccelerator_mm_instance == NULL) 
     96        return 0; 
     97 
     98    xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
     99    EACCELERATOR_UNPROTECT(); 
     100    x = eaccelerator_malloc(offsetof(mm_lock_entry, key) + xlen + 1); 
     101    if (x == NULL) { 
     102        EACCELERATOR_PROTECT(); 
     103        if (xlen != key_len) 
     104            efree(xkey); 
     105 
     106        return 0; 
     107   
     108    x->pid = getpid(); 
    109109#ifdef ZTS 
    110        x->thread = tsrm_thread_id (); 
     110    x->thread = tsrm_thread_id(); 
    111111#endif 
    112        x->next = NULL; 
    113        memcpy (x->key, xkey, xlen + 1); 
    114        while (1) { 
    115                EACCELERATOR_LOCK_RW (); 
    116                p = &eaccelerator_mm_instance->locks; 
    117                while ((*p) != NULL) { 
    118                        if (strcmp ((*p)->key, x->key) == 0) { 
     112    x->next = NULL; 
     113    memcpy(x->key, xkey, xlen + 1); 
     114    while (1) { 
     115        EACCELERATOR_LOCK_RW(); 
     116        p = &eaccelerator_mm_instance->locks; 
     117        while ((*p) != NULL) { 
     118            if (strcmp((*p)->key, x->key) == 0) { 
    119119#ifdef ZTS 
    120                                if (x->pid == (*p)->pid && x->thread == (*p)->thread) { 
     120                if (x->pid ==(*p)->pid && x->thread == (*p)->thread) { 
    121121#else 
    122                                if (x->pid == (*p)->pid) { 
     122                if (x->pid ==(*p)->pid) { 
    123123#endif 
    124                                        ok = 1; 
    125                                        eaccelerator_free_nolock (x); 
    126                                
    127                                break; 
    128                        
    129                        p = &(*p)->next; 
    130                
    131                if ((*p) == NULL) { 
    132                        *p = x; 
    133                        ok = 1; 
    134                
    135                EACCELERATOR_UNLOCK_RW (); 
    136                if (ok) { 
    137                        break; 
    138                } else { 
     124                    ok = 1; 
     125                    eaccelerator_free_nolock(x); 
     126               
     127                break; 
     128           
     129            p = &(*p)->next; 
     130       
     131        if ((*p) == NULL) { 
     132            *p = x; 
     133            ok = 1; 
     134       
     135        EACCELERATOR_UNLOCK_RW(); 
     136        if (ok) { 
     137            break; 
     138        } else { 
    139139#ifdef ZEND_WIN32 
    140                        Sleep (100); 
     140            Sleep(100); 
    141141#else 
    142                        struct timeval t; 
    143                        t.tv_sec = 0; 
    144                        t.tv_usec = 100; 
    145                        select (0, NULL, NULL, NULL, &t); 
     142            struct timeval t; 
     143            t.tv_sec = 0; 
     144            t.tv_usec = 100; 
     145            select(0, NULL, NULL, NULL, &t); 
    146146#endif 
    147                
    148        
    149        EACCELERATOR_PROTECT (); 
    150        if (xlen != key_len) 
    151                efree (xkey); 
    152  
    153        return 1; 
     147       
     148   
     149    EACCELERATOR_PROTECT(); 
     150    if (xlen != key_len) 
     151        efree(xkey); 
     152 
     153    return 1; 
    154154} 
    155155 
    156156/* unlock to key cache */ 
    157 int eaccelerator_unlock (const char *key, int key_len TSRMLS_DC) 
    158 { 
    159        int xlen; 
    160        char *xkey; 
    161        mm_lock_entry **p; 
    162  
    163        if (eaccelerator_mm_instance == NULL) 
    164                return 0; 
    165  
    166        xkey = build_key (key, key_len, &xlen TSRMLS_CC); 
    167        EACCELERATOR_UNPROTECT (); 
    168        EACCELERATOR_LOCK_RW (); 
    169        p = &eaccelerator_mm_instance->locks; 
    170        while ((*p) != NULL) { 
    171                if (strcmp ((*p)->key, xkey) == 0) { 
     157int eaccelerator_unlock(const char *key, int key_len TSRMLS_DC) 
     158{ 
     159    int xlen; 
     160    char *xkey; 
     161    mm_lock_entry **p; 
     162 
     163    if (eaccelerator_mm_instance == NULL) 
     164        return 0; 
     165 
     166    xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
     167    EACCELERATOR_UNPROTECT(); 
     168    EACCELERATOR_LOCK_RW(); 
     169    p = &eaccelerator_mm_instance->locks; 
     170    while ((*p) != NULL) { 
     171        if (strcmp((*p)->key, xkey) == 0) { 
    172172#ifdef ZTS 
    173                         if ((*p)->pid == getpid () 
    174                                 && (*p)->thread == tsrm_thread_id ()) { 
     173            if ((*p)->pid == getpid() && (*p)->thread == tsrm_thread_id()) { 
    175174#else 
    176                        if ((*p)->pid == getpid ()) { 
     175            if ((*p)->pid == getpid()) { 
    177176#endif 
    178                                mm_lock_entry *x = (*p); 
    179                                *p = (*p)->next; 
    180                                eaccelerator_free_nolock (x); 
    181                        } else { 
    182                                EACCELERATOR_UNLOCK_RW (); 
    183                                EACCELERATOR_PROTECT (); 
    184                                if (xlen != key_len) 
    185                                        efree (xkey); 
    186  
    187                                return 0; 
    188                        
    189                        break; 
    190                
    191                p = &(*p)->next; 
    192        
    193        EACCELERATOR_UNLOCK_RW (); 
    194        EACCELERATOR_PROTECT (); 
    195        if (xlen != key_len) 
    196                efree (xkey); 
    197  
    198        return 1; 
     177                mm_lock_entry *x = (*p); 
     178                *p = (*p)->next; 
     179                eaccelerator_free_nolock(x); 
     180            } else { 
     181                EACCELERATOR_UNLOCK_RW(); 
     182                EACCELERATOR_PROTECT(); 
     183                if (xlen != key_len) 
     184                    efree(xkey); 
     185 
     186                return 0; 
     187           
     188            break; 
     189       
     190        p = &(*p)->next; 
     191   
     192    EACCELERATOR_UNLOCK_RW(); 
     193    EACCELERATOR_PROTECT(); 
     194    if (xlen != key_len) 
     195        efree(xkey); 
     196 
     197    return 1; 
    199198} 
    200199 
    201200/* put a key in the cache (shm or disk) */ 
    202 int eaccelerator_put (const char *key, int key_len, zval * val, time_t ttl, 
    203                                           eaccelerator_cache_place where TSRMLS_DC) 
    204 
    205         mm_user_cache_entry *p, *q; 
    206         unsigned int slot, hv; 
    207         long size; 
    208         int use_shm = 1; 
    209         int ret = 0; 
    210         char s[MAXPATHLEN]; 
    211         int xlen; 
    212         char *xkey; 
    213  
    214         xkey = build_key (key, key_len, &xlen TSRMLS_CC); 
    215         EAG (compress) = 1; 
    216         EAG (mem) = NULL; 
    217         zend_hash_init (&EAG (strings), 0, NULL, NULL, 0); 
    218         EACCELERATOR_ALIGN (EAG (mem)); 
    219         EAG (mem) += offsetof (mm_user_cache_entry, key) + xlen + 1; 
    220         calc_zval (val TSRMLS_CC); 
    221         zend_hash_destroy (&EAG (strings)); 
    222  
    223         size = (long) EAG (mem); 
    224  
    225         EAG (mem) = NULL; 
    226         if (eaccelerator_mm_instance != NULL && 
    227                 (where == eaccelerator_shm_and_disk || 
    228                  where == eaccelerator_shm || where == eaccelerator_shm_only)) { 
    229                 EACCELERATOR_UNPROTECT (); 
    230                 if (eaccelerator_shm_max == 0 || size <= eaccelerator_shm_max) { 
    231                         EAG (mem) = eaccelerator_malloc (size); 
    232                         if (EAG (mem) == NULL) { 
    233                                 EAG (mem) = eaccelerator_malloc2 (size TSRMLS_CC); 
    234                         } 
    235                 } 
    236                 if (EAG (mem) == NULL) { 
    237                         EACCELERATOR_PROTECT (); 
    238                 } 
    239         } 
    240         if (EAG (mem) == NULL && 
    241                 (where == eaccelerator_shm_and_disk || 
    242                  where == eaccelerator_shm || where == eaccelerator_disk_only)) { 
    243                 use_shm = 0; 
    244                 EAG (mem) = emalloc (size); 
    245         } 
    246         if (EAG (mem)) { 
    247                 zend_hash_init (&EAG (strings), 0, NULL, NULL, 0); 
    248                 EACCELERATOR_ALIGN (EAG (mem)); 
    249                 q = (mm_user_cache_entry *) EAG (mem); 
    250                 q->size = size; 
    251                 EAG (mem) += offsetof (mm_user_cache_entry, key) + xlen + 1; 
    252                 q->hv = hash_mm (xkey, xlen); 
    253                 memcpy (q->key, xkey, xlen + 1); 
    254                 memcpy (&q->value, val, sizeof (zval)); 
    255                 q->ttl = ttl ? time (0) + ttl : 0; 
    256                 q->create = time (0); 
    257                 store_zval (&q->value TSRMLS_CC); 
    258                 zend_hash_destroy (&EAG (strings)); 
    259  
    260                 /* 
    261                  * storing to file  
    262                  */ 
    263                 if ((where == eaccelerator_shm_and_disk || 
    264                          ((where == eaccelerator_shm) && !use_shm) || 
    265                          where == eaccelerator_disk_only) && 
    266                         eaccelerator_md5 (s, "/eaccelerator-user-", q->key TSRMLS_CC)) { 
    267                         int f; 
    268                         unlink (s); 
    269                         f = open (s, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, 
    270                                           S_IRUSR | S_IWUSR); 
    271                         if (f > 0) { 
    272                                 mm_file_header hdr; 
    273                                 EACCELERATOR_FLOCK (f, LOCK_EX); 
    274                                 strncpy (hdr.magic, "EACCELERATOR", 8); 
    275                                 hdr.eaccelerator_version = binary_eaccelerator_version; 
    276                                 hdr.zend_version = binary_zend_version; 
    277                                 hdr.php_version = binary_php_version; 
    278                                 hdr.size = q->size; 
    279                                 hdr.mtime = q->ttl; 
    280                                 q->next = q; 
    281                                 hdr.crc32 = eaccelerator_crc32 ((const char *) q, q->size); 
    282                                 if (write (f, &hdr, sizeof (hdr)) == sizeof (hdr)) { 
    283                                         write (f, q, q->size); 
    284                                         EACCELERATOR_FLOCK (f, LOCK_UN); 
    285                                         close (f); 
    286                                         ret = 1; 
    287                                 } else { 
    288                                         EACCELERATOR_FLOCK (f, LOCK_UN); 
    289                                         close (f); 
    290                                         unlink (s); 
    291                                 } 
    292                         } 
    293                         if (!use_shm) 
    294                                 efree (q); 
    295                 } 
    296  
    297                 if ((where == eaccelerator_shm_and_disk || where == eaccelerator_shm 
    298                          || where == eaccelerator_shm_only) && use_shm) { 
    299                         /* 
    300                          * storing to shared memory  
    301                          */ 
    302                         slot = q->hv & MM_USER_HASH_MAX; 
     201int eaccelerator_put(const char *key, int key_len, zval * val, time_t ttl, 
     202                      eaccelerator_cache_place where TSRMLS_DC) 
     203
     204    mm_user_cache_entry *p, *q; 
     205    unsigned int slot, hv; 
     206    long size; 
     207    int use_shm = 1; 
     208    int ret = 0; 
     209    char s[MAXPATHLEN]; 
     210    int xlen; 
     211    char *xkey; 
     212 
     213    xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
     214    EAG(compress) = 1; 
     215    EAG(mem) = NULL; 
     216    zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); 
     217    EACCELERATOR_ALIGN(EAG(mem)); 
     218    EAG(mem) += offsetof(mm_user_cache_entry, key) + xlen + 1; 
     219    calc_zval(val TSRMLS_CC); 
     220    zend_hash_destroy(&EAG(strings)); 
     221 
     222    size = (long) EAG(mem); 
     223 
     224    EAG(mem) = NULL; 
     225    if (eaccelerator_mm_instance != NULL && (where == eaccelerator_shm_and_disk ||  
     226                where == eaccelerator_shm || where == eaccelerator_shm_only)) { 
     227        EACCELERATOR_UNPROTECT(); 
     228        if (eaccelerator_shm_max == 0 || size <= eaccelerator_shm_max) { 
     229            EAG(mem) = eaccelerator_malloc(size); 
     230            if (EAG(mem) == NULL) { 
     231                EAG(mem) = eaccelerator_malloc2(size TSRMLS_CC); 
     232            } 
     233        } 
     234        if (EAG(mem) == NULL) { 
     235            EACCELERATOR_PROTECT(); 
     236        } 
     237    } 
     238    if (EAG(mem) == NULL && (where == eaccelerator_shm_and_disk ||  
     239                where == eaccelerator_shm || where == eaccelerator_disk_only)) { 
     240        use_shm = 0; 
     241        EAG(mem) = emalloc(size); 
     242    } 
     243    if (EAG(mem)) { 
     244        zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); 
     245        EACCELERATOR_ALIGN(EAG(mem)); 
     246        q = (mm_user_cache_entry *) EAG(mem); 
     247        q->size = size; 
     248        EAG(mem) += offsetof(mm_user_cache_entry, key) + xlen + 1; 
     249        q->hv = hash_mm(xkey, xlen); 
     250        memcpy(q->key, xkey, xlen + 1); 
     251        memcpy(&q->value, val, sizeof(zval)); 
     252        q->ttl = ttl ? time(0) + ttl : 0; 
     253        q->create = time(0); 
     254        /* set the refcount to 1 */ 
     255        q->value.refcount = 1; 
     256        store_zval(&q->value TSRMLS_CC); 
     257        zend_hash_destroy(&EAG(strings)); 
     258 
     259        /* 
     260         * storing to file  
     261         */ 
     262        if ((where == eaccelerator_shm_and_disk || ((where == eaccelerator_shm) && !use_shm) ||  
     263                    where == eaccelerator_disk_only) && eaccelerator_md5(s, "/eaccelerator-user-", q->key TSRMLS_CC)) { 
     264            int f; 
     265            unlink(s); 
     266            f = open(s, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR); 
     267            if (f > 0) { 
     268                mm_file_header hdr; 
     269                EACCELERATOR_FLOCK(f, LOCK_EX); 
     270                strncpy(hdr.magic, "EACCELERATOR", 8); 
     271                hdr.eaccelerator_version = binary_eaccelerator_version; 
     272                hdr.zend_version = binary_zend_version; 
     273                hdr.php_version = binary_php_version; 
     274                hdr.size = q->size; 
     275                hdr.mtime = q->ttl; 
     276                q->next = q; 
     277                hdr.crc32 = eaccelerator_crc32((const char *) q, q->size); 
     278                if (write(f, &hdr, sizeof(hdr)) == sizeof(hdr)) { 
     279                    write(f, q, q->size); 
     280                    EACCELERATOR_FLOCK(f, LOCK_UN); 
     281                    close(f); 
     282                    ret = 1; 
     283                } else { 
     284                    EACCELERATOR_FLOCK(f, LOCK_UN); 
     285                    close(f); 
     286                    unlink(s); 
     287                } 
     288            } 
     289            if (!use_shm) 
     290                efree(q); 
     291        } 
     292 
     293        if ((where == eaccelerator_shm_and_disk || where == eaccelerator_shm || where == eaccelerator_shm_only) && use_shm) { 
     294            /* 
     295             * storing to shared memory  
     296             */ 
     297            slot = q->hv & MM_USER_HASH_MAX; 
    303298            hv = q->hv; 
    304                        EACCELERATOR_LOCK_RW (); 
    305                        eaccelerator_mm_instance->user_hash_cnt++; 
    306                        q->next = eaccelerator_mm_instance->user_hash[slot]; 
    307                        eaccelerator_mm_instance->user_hash[slot] = q; 
    308                        p = q->next; 
    309                        while (p != NULL) { 
    310                                if ((p->hv == hv) && (strcmp (p->key, xkey) == 0)) { 
    311                                        eaccelerator_mm_instance->user_hash_cnt--; 
    312                                        q->next = p->next; 
    313                                        eaccelerator_free_nolock (p); 
    314                                        break; 
    315                                
    316                                q = p; 
    317                                p = p->next; 
    318                        
    319                        EACCELERATOR_UNLOCK_RW (); 
    320                        EACCELERATOR_PROTECT (); 
    321                        ret = 1; 
    322                
    323        
    324        if (xlen != key_len) 
    325                efree (xkey); 
    326  
    327        return ret; 
     299            EACCELERATOR_LOCK_RW(); 
     300            eaccelerator_mm_instance->user_hash_cnt++; 
     301            q->next = eaccelerator_mm_instance->user_hash[slot]; 
     302            eaccelerator_mm_instance->user_hash[slot] = q; 
     303            p = q->next; 
     304            while (p != NULL) { 
     305                if ((p->hv == hv) && (strcmp(p->key, xkey) == 0)) { 
     306                    eaccelerator_mm_instance->user_hash_cnt--; 
     307                    q->next = p->next; 
     308                    eaccelerator_free_nolock(p); 
     309                    break; 
     310               
     311                q = p; 
     312                p = p->next; 
     313           
     314            EACCELERATOR_UNLOCK_RW(); 
     315            EACCELERATOR_PROTECT(); 
     316            ret = 1; 
     317       
     318   
     319    if (xlen != key_len) 
     320        efree(xkey); 
     321 
     322    return ret; 
    328323} 
    329324 
    330325/* get a key from the cache */ 
    331 int eaccelerator_get (const char *key, int key_len, zval * return_value, 
    332                                   eaccelerator_cache_place where TSRMLS_DC) 
    333 
    334         unsigned int hv, slot; 
    335         char s[MAXPATHLEN]; 
    336         int xlen; 
    337         char *xkey; 
    338  
    339         xkey = build_key (key, key_len, &xlen TSRMLS_CC); 
    340         hv = hash_mm (xkey, xlen); 
    341         slot = hv & MM_USER_HASH_MAX; 
    342  
    343         if (eaccelerator_mm_instance != NULL 
    344                 && (where == eaccelerator_shm_and_disk || where == eaccelerator_shm 
    345                         || where == eaccelerator_shm_only)) { 
    346                 mm_user_cache_entry *p, *q; 
    347                 mm_user_cache_entry *x = NULL; 
    348                 EACCELERATOR_UNPROTECT (); 
    349                 EACCELERATOR_LOCK_RW (); 
    350                 q = NULL; 
    351                 p = eaccelerator_mm_instance->user_hash[slot]; 
    352                 while (p != NULL) { 
    353                         if ((p->hv == hv) && (strcmp (p->key, xkey) == 0)) { 
    354                                 x = p; 
    355                                 if (p->ttl != 0 && p->ttl < time (0)) { 
    356                                         if (q == NULL) { 
    357                                                 eaccelerator_mm_instance->user_hash[slot] = p->next; 
    358                                         } else { 
    359                                                 q->next = p->next; 
    360                                         } 
    361                                         eaccelerator_mm_instance->user_hash_cnt--; 
    362                                         eaccelerator_free_nolock (x); 
    363                                         x = NULL; 
    364                                 } 
    365                                 break; 
    366                         } 
    367                         q = p; 
    368                         p = p->next; 
    369                 } 
    370                 EACCELERATOR_UNLOCK_RW (); 
    371                 EACCELERATOR_PROTECT (); 
    372                 if (x) { 
    373                         memcpy (return_value, &x->value, sizeof (zval)); 
    374                         restore_zval (return_value TSRMLS_CC); 
    375                         if (xlen != key_len) { 
    376                                 efree (xkey); 
    377                         } 
    378                         return 1; 
    379                 } 
    380         } 
    381  
    382         /* 
    383          * key is not found in shared memory try to load it from file  
    384          */ 
    385         if ((where == eaccelerator_shm_and_disk || where == eaccelerator_shm || 
    386                  where == eaccelerator_disk_only) && 
    387                 eaccelerator_md5 (s, "/eaccelerator-user-", xkey TSRMLS_CC)) { 
    388                 time_t t = time (0); 
    389                 int use_shm = 1; 
    390                 int ret = 0; 
    391                 int f; 
    392  
    393                 if ((f = open (s, O_RDONLY | O_BINARY)) > 0) { 
    394                         mm_file_header hdr; 
    395  
    396                         EACCELERATOR_FLOCK (f, LOCK_SH); 
    397                         if (read (f, &hdr, sizeof (hdr)) != sizeof (hdr) || 
    398                                 strncmp (hdr.magic, "EACCELERATOR", 8) != 0 || 
    399                                 hdr.eaccelerator_version != binary_eaccelerator_version 
    400                                 || hdr.zend_version != binary_zend_version 
    401                                 || hdr.php_version != binary_php_version) { 
    402                                 EACCELERATOR_FLOCK (f, LOCK_UN); 
    403                                 close (f); 
    404                                 unlink (s); 
    405                                 if (xlen != key_len) 
    406                                         efree (xkey); 
    407                                 return 0; 
    408                         } 
    409                         if (hdr.mtime == 0 || hdr.mtime > t) { 
    410                                 /* 
    411                                  * try to put it into shared memory  
    412                                  */ 
    413                                 mm_user_cache_entry *p = NULL; 
    414                                 if (eaccelerator_mm_instance != NULL && 
    415                                         (where == eaccelerator_shm_and_disk 
    416                                          || where == eaccelerator_shm)) { 
    417                                         if (eaccelerator_shm_max == 0 
    418                                                 || hdr.size <= eaccelerator_shm_max) { 
    419                                                 EACCELERATOR_UNPROTECT (); 
    420                                                 p = eaccelerator_malloc (hdr.size); 
    421                                                 if (p == NULL) { 
    422                                                         p = eaccelerator_malloc2 (hdr.size TSRMLS_CC); 
    423                                                 } 
    424                                                 if (p == NULL) { 
    425                                                         EACCELERATOR_PROTECT (); 
    426                                                 } 
    427                                         } 
    428                                 } 
    429                                 if (p == NULL) { 
    430                                         p = emalloc (hdr.size); 
    431                                         use_shm = 0; 
    432                                 } 
    433                                 if (p != NULL) { 
    434                                         if (read (f, p, hdr.size) == hdr.size && hdr.size == p->size 
    435                                                 && hdr.crc32 == 
    436                                                 eaccelerator_crc32 ((const char *) p, p->size)) { 
    437                                                 EAG (mem) = (char *) ((long) p - (long) p->next); 
    438                                                 EAG (compress) = 1; 
    439                                                 fixup_zval (&p->value TSRMLS_CC); 
    440  
    441                                                 if (strcmp (xkey, p->key) != 0) { 
    442                                                         if (use_shm) 
    443                                                                 eaccelerator_free (p); 
    444                                                         else 
    445                                                                 efree (p); 
    446                                                         EACCELERATOR_FLOCK (f, LOCK_UN); 
    447                                                         close (f); 
    448                                                         unlink (s); 
    449                                                         if (use_shm) 
    450                                                                 EACCELERATOR_PROTECT (); 
    451                                                         if (xlen != key_len) 
    452                                                                 efree (xkey); 
    453                                                         return 0; 
    454                                                 } 
    455  
    456                                                 memcpy (return_value, &p->value, sizeof (zval)); 
    457                                                 restore_zval (return_value TSRMLS_CC); 
    458                                                 ret = 1; 
    459                                                 if (use_shm) { 
    460                                                         /* put it into shared memory */ 
    461                                                         mm_user_cache_entry *q, *prev; 
    462  
    463                                                         p->hv = hv; 
    464                                                         EACCELERATOR_LOCK_RW (); 
    465                                                         p->next = eaccelerator_mm_instance->user_hash[slot]; 
    466                                                         eaccelerator_mm_instance->user_hash[slot] = p; 
    467                                                         eaccelerator_mm_instance->user_hash_cnt++; 
    468                                                         prev = p; 
    469                                                         q = p->next; 
    470                                                         while (q != NULL) { 
    471                                                                 if ((q->hv == hv) 
    472                                                                         && (strcmp (q->key, xkey) == 0)) { 
    473                                                                         prev->next = q->next; 
    474                                                                         eaccelerator_mm_instance->user_hash_cnt--; 
    475                                                                         eaccelerator_free_nolock (q); 
    476                                                                         break; 
    477                                                                 } 
    478                                                                 prev = q; 
    479                                                                 q = q->next; 
    480                                                         } 
    481                                                         EACCELERATOR_UNLOCK_RW (); 
    482                                                 } else { 
    483                                                         efree (p); 
    484                                                 } 
    485                                                 EACCELERATOR_FLOCK (f, LOCK_UN); 
    486                                                 close (f); 
    487                                         } else { 
    488                                                 if (use_shm) { 
    489                                                         eaccelerator_free (p); 
    490                                                 } else { 
    491                                                         efree (p); 
    492                                                 } 
    493                                                 EACCELERATOR_FLOCK (f, LOCK_UN); 
    494                                                 close (f); 
    495                                                 unlink (s); 
    496                                         } 
    497                                 } 
    498                                 if (use_shm) 
    499                                         EACCELERATOR_PROTECT (); 
    500                         } else { 
    501                                 EACCELERATOR_FLOCK (f, LOCK_UN); 
    502                                 close (f); 
    503                                 unlink (s); 
    504                         } 
    505                         if (xlen != key_len) { 
    506                                 efree (xkey); 
    507                         } 
    508                         return ret; 
    509                 } 
    510         } 
    511         if (xlen != key_len) { 
    512                 efree (xkey); 
    513         } 
    514         return 0; 
     326int eaccelerator_get(const char *key, int key_len, zval * return_value, 
     327                  eaccelerator_cache_place where TSRMLS_DC) 
     328
     329    unsigned int hv, slot; 
     330    char s[MAXPATHLEN]; 
     331    int xlen; 
     332    char *xkey; 
     333 
     334    xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
     335    hv = hash_mm(xkey, xlen); 
     336    slot = hv & MM_USER_HASH_MAX; 
     337 
     338    if (eaccelerator_mm_instance != NULL && (where == eaccelerator_shm_and_disk  
     339                || where == eaccelerator_shm || where == eaccelerator_shm_only)) { 
     340        mm_user_cache_entry *p, *q; 
     341        mm_user_cache_entry *x = NULL; 
     342        EACCELERATOR_UNPROTECT(); 
     343        EACCELERATOR_LOCK_RW(); 
     344        q = NULL; 
     345        p = eaccelerator_mm_instance->user_hash[slot]; 
     346        while (p != NULL) { 
     347            if ((p->hv == hv) && (strcmp(p->key, xkey) == 0)) { 
     348                x = p; 
     349                if (p->ttl != 0 && p->ttl < time(0)) { 
     350                    if (q == NULL) { 
     351                        eaccelerator_mm_instance->user_hash[slot] = p->next; 
     352                    } else { 
     353                        q->next = p->next; 
     354                    } 
     355                    eaccelerator_mm_instance->user_hash_cnt--; 
     356                    eaccelerator_free_nolock(x); 
     357                    x = NULL; 
     358                } 
     359                break; 
     360            } 
     361            q = p; 
     362            p = p->next; 
     363        } 
     364        EACCELERATOR_UNLOCK_RW(); 
     365        EACCELERATOR_PROTECT(); 
     366        if (x) { 
     367            memcpy(return_value, &x->value, sizeof(zval)); 
     368            restore_zval(return_value TSRMLS_CC); 
     369            if (xlen != key_len) { 
     370                efree(xkey); 
     371            } 
     372            return 1; 
     373        } 
     374    } 
     375 
     376    /* 
     377     * key is not found in shared memory try to load it from file  
     378     */ 
     379    if ((where == eaccelerator_shm_and_disk || where == eaccelerator_shm ||  
     380            where == eaccelerator_disk_only) &&  
     381            eaccelerator_md5(s, "/eaccelerator-user-", xkey TSRMLS_CC)) { 
     382        time_t t = time(0); 
     383        int use_shm = 1; 
     384        int ret = 0; 
     385        int f; 
     386 
     387        if ((f = open(s, O_RDONLY | O_BINARY)) > 0) { 
     388            mm_file_header hdr; 
     389 
     390            EACCELERATOR_FLOCK(f, LOCK_SH); 
     391            if (read(f, &hdr, sizeof(hdr)) != sizeof(hdr) || strncmp(hdr.magic, "EACCELERATOR", 8) != 0 ||  
     392                    hdr.eaccelerator_version != binary_eaccelerator_version || hdr.zend_version != binary_zend_version  
     393                    || hdr.php_version != binary_php_version) { 
     394                EACCELERATOR_FLOCK(f, LOCK_UN); 
     395                close(f); 
     396                unlink(s); 
     397                if (xlen != key_len) 
     398                    efree(xkey); 
     399                return 0; 
     400            } 
     401            if (hdr.mtime == 0 || hdr.mtime > t) { 
     402                /* 
     403                 * try to put it into shared memory  
     404                 */ 
     405                mm_user_cache_entry *p = NULL; 
     406                if (eaccelerator_mm_instance != NULL && (where == eaccelerator_shm_and_disk || where == eaccelerator_shm)) { 
     407                    if (eaccelerator_shm_max == 0 || hdr.size <= eaccelerator_shm_max) { 
     408                        EACCELERATOR_UNPROTECT(); 
     409                        p = eaccelerator_malloc(hdr.size); 
     410                        if (p == NULL) {