Changeset 64

Show
Ignore:
Timestamp:
04/26/05 16:48:00 (3 years ago)
Author:
zoeloelip
Message:

* This commit contains the first part of the code refactoring. In this part

the monolitic eaccelerator.c file has been split up in more logical blocks.

cache.c/cache.h contains the procedure for shm.c/session.c/content.c to add user_cache entries to the ea cache
shm.c/shm.h contains the eaccelerator shared memory functions
session.c/session.h contains the session related stuff
webui.c/webui.h contains all stuff related to the webinterface and disassembler
debug.c/debug.h contains some procedures to print debug information
content.h contains the php content caching prototype instead of eaccelerator.h

* Added --without-eaccelerator-shared-memory and --without-eaccelerator-webui configure switches

Bugfixes included:
* Patch 1188510 eaccelerator_compile_file typos
* Patch 1189792 session life time patch
* Patch 1167069 HAS_ATTRIBUTE fix with FreeBSD 4.x
* Patch 1166707 loader patch for OOP functions in PHP5 (only rapidly tested but also seemed ok to segv)
* string in eaccelerator_put_page (content.c line 162) which wasn't freed (Thanks to The_Surfer)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/Makefile.in

    r4 r64  
    11LTLIBRARY_NAME        = libeaccelerator.la 
    2 LTLIBRARY_SOURCES     = eaccelerator.c optimize.c execute.c encoder.c loader.c opcodes.c content.c mm.c 
     2LTLIBRARY_SOURCES     = eaccelerator.c optimize.c execute.c encoder.c loader.c opcodes.c content.c mm.c webui.c session.c shm.c debug.c cache.c 
    33LTLIBRARY_SHARED_NAME = eaccelerator.la 
    44 
  • eaccelerator/trunk/config.m4

    r4 r64  
    3030],[ 
    3131  eaccelerator_loader=yes 
     32]) 
     33 
     34AC_ARG_WITH(eaccelerator-shared-memory, 
     35[  --without-eaccelerator-shared-memory    Do not include eaccelerator shared memory functions],[ 
     36  eaccelerator_shm=$withval 
     37],[ 
     38  eaccelerator_shm=yes 
     39]) 
     40 
     41AC_ARG_WITH(eaccelerator-webui, 
     42[  --without-eaccelerator-webui        Do not include the eaccelerator WebUI],[ 
     43  eaccelerator_webui=$withval 
     44],[ 
     45  eaccelerator_webui=yes 
    3246]) 
    3347 
     
    7690  if test "$eaccelerator_loader" = "yes"; then 
    7791    AC_DEFINE(WITH_EACCELERATOR_LOADER, 1, [Define if you like to load files encoded by eAccelerator encoder]) 
     92  fi 
     93  if test "$eaccelerator_shm" = "yes"; then 
     94    AC_DEFINE(WITH_EACCELERATOR_SHM, 1, [Define if you like to use the eAccelerator functions to store keys in shared memory]) 
     95  fi 
     96  if test "$eaccelerator_webui" = "yes"; then 
     97    AC_DEFINE(WITH_EACCELERATOR_WEBUI, 1, [Define if you like to use the eAccelerator WebUI]) 
    7898  fi 
    7999  if test "$eaccelerator_sessions" = "yes"; then 
  • eaccelerator/trunk/content.c

    r21 r64  
    33   | eAccelerator project                                                 | 
    44   +----------------------------------------------------------------------+ 
    5    | Copyright (c) 2004 eAccelerator                                      | 
    6    | http://eaccelerator.sourceforge.net                                  | 
     5   | Copyright (c) 2004 - 2005 eAccelerator                               | 
     6   | http://eaccelerator.net                                                     | 
    77   +----------------------------------------------------------------------+ 
    88   | This program is free software; you can redistribute it and/or        | 
     
    3333#ifdef WITH_EACCELERATOR_CONTENT_CACHING 
    3434 
     35#include "cache.h" 
     36#include "content.h" 
    3537#include "SAPI.h" 
    3638 
    3739#define EACCELERATOR_COMPRESS_MIN 128 
    3840 
     41eaccelerator_cache_place eaccelerator_content_cache_place = eaccelerator_shm_and_disk; 
     42 
    3943static int (*eaccelerator_old_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); 
     44 
     45PHP_INI_MH (eaccelerator_OnUpdateContentCachePlace) 
     46{ 
     47        if (strncasecmp ("shm_and_disk", new_value,  
     48                sizeof ("shm_and_disk")) == 0) 
     49        { 
     50                eaccelerator_content_cache_place = eaccelerator_shm_and_disk; 
     51        } 
     52        else if (strncasecmp ("shm", new_value,  
     53                sizeof ("shm")) == 0) 
     54        { 
     55                eaccelerator_content_cache_place = eaccelerator_shm; 
     56        } 
     57        else if (strncasecmp ("shm_only", new_value,  
     58                sizeof ("shm_only")) == 0) 
     59        { 
     60                eaccelerator_content_cache_place = eaccelerator_shm_only; 
     61        } 
     62        else if (strncasecmp ("disk_only", new_value,  
     63                sizeof ("disk_only")) == 0) 
     64        { 
     65                eaccelerator_content_cache_place = eaccelerator_disk_only; 
     66        } 
     67        else if (strncasecmp ("none", new_value,  
     68                sizeof ("none")) == 0) 
     69        { 
     70                eaccelerator_content_cache_place = eaccelerator_none; 
     71        } 
     72        return SUCCESS; 
     73} 
    4074 
    4175static int eaccelerator_check_compression(sapi_header_struct *sapi_header TSRMLS_DC) { 
     
    131165      add_next_index_stringl(headers, s, h->header_len+1, 0); 
    132166      p = p->next; 
     167      efree(s); 
    133168    } 
    134169    add_assoc_zval(&cache_array, "headers", headers); 
  • eaccelerator/trunk/eaccelerator.c

    r60 r64  
    33   | eAccelerator project                                                 | 
    44   +----------------------------------------------------------------------+ 
    5    | Copyright (c) 2004 eAccelerator                                      | 
    6    | http://eaccelerator.sourceforge.net                                  | 
     5   | Copyright (c) 2004 - 2005 eAccelerator                               | 
     6   | http://eaccelerator.net                                                     | 
    77   +----------------------------------------------------------------------+ 
    88   | This program is free software; you can redistribute it and/or        | 
     
    4141#include "zend_extensions.h" 
    4242 
     43#include "webui.h" 
     44#include "debug.h" 
     45#include "shm.h" 
     46#include "session.h" 
     47#include "content.h" 
     48 
    4349#include <sys/types.h> 
    4450#include <sys/stat.h> 
     
    96102#include "SAPI.h" 
    97103 
    98 #undef HAVE_PHP_SESSIONS_SUPPORT 
    99 #ifdef HAVE_EXT_SESSION_PHP_SESSION_H 
    100 #  include "ext/session/php_session.h" 
    101 #   ifdef PHP_SESSION_API 
    102 #     if PHP_SESSION_API >= 20020306 
    103 #       define HAVE_PHP_SESSIONS_SUPPORT 
    104 static int eaccelerator_sessions_registered = 0; 
    105 #       ifdef PS_CREATE_SID_ARGS 
    106 #         include "ext/standard/php_lcg.h" 
    107 #       endif 
    108 #     endif 
    109 #   endif 
    110 #endif 
    111  
    112104#define MAX_DUP_STR_LEN 256 
    113105 
    114 #define offsetof(str,fld) ((size_t)&(((str*)NULL)->fld)) 
    115  
    116 #ifdef EACCELERATOR_WITHOUT_FILE_LOCKING 
    117 #  ifndef LOCK_SH 
    118 #    define LOCK_SH 1 
    119 #    define LOCK_EX 2 
    120 #    define LOCK_UN 8 
    121 #  endif 
    122 #  define EACCELERATOR_FLOCK(FILE,OP) 
    123 #else 
    124 #  ifndef ZEND_WIN32 
    125 #    ifdef HAVE_FLOCK 
    126 #      define EACCELERATOR_FLOCK(FILE,OP) flock((FILE),(OP)) 
    127 #    else 
    128 #      ifndef LOCK_SH 
    129 #        define LOCK_SH 1 
    130 #        define LOCK_EX 2 
    131 #        define LOCK_UN 8 
    132 #      endif 
    133 #      define EACCELERATOR_FLOCK(FILE,OP) 
    134 #    endif 
    135 #  else 
    136 #    define LOCK_SH 0 
    137 #    define LOCK_EX 1 
    138 #    define LOCK_UN 2 
    139 #    define EACCELERATOR_FLOCK(FILE,OP) {OVERLAPPED offset = {0,0,0,0,NULL};\ 
    140                                    if ((OP) == LOCK_EX) {\ 
    141                                      LockFileEx((HANDLE)_get_osfhandle(FILE), \ 
    142                                        LOCKFILE_EXCLUSIVE_LOCK, 0,\ 
    143                                        1, 0, &offset);\ 
    144                                    } else if ((OP) == LOCK_SH) {\ 
    145                                      LockFileEx((HANDLE)_get_osfhandle(FILE), \ 
    146                                        0, 0,\ 
    147                                        1, 0, &offset);\ 
    148                                    } else if ((OP) == LOCK_UN) {\ 
    149                                      UnlockFileEx((HANDLE)_get_osfhandle(FILE), \ 
    150                                        0,\ 
    151                                        1, 0, &offset);\ 
    152                                    }} 
    153 #  endif 
    154 #endif 
    155  
    156  
    157 typedef struct _eaccelerator_op_array { 
    158   zend_uchar type; 
    159 #ifdef ZEND_ENGINE_2 
    160   zend_bool uses_this; 
    161 #else 
    162   zend_bool uses_globals; 
    163 #endif 
    164   zend_bool return_reference; 
    165 #ifdef ZEND_ENGINE_2 
    166   zend_uint num_args; 
    167   zend_uint required_num_args; 
    168   zend_arg_info *arg_info; 
    169   zend_bool pass_rest_by_reference; 
    170 #else 
    171   zend_uchar *arg_types; 
    172 #endif 
    173   char *function_name; 
    174   char *function_name_lc; 
    175 #ifdef ZEND_ENGINE_2 
    176   char* scope_name; 
    177   int   scope_name_len; 
    178   zend_uint fn_flags; 
    179 #endif 
    180   zend_op *opcodes; 
    181   zend_uint last; 
    182   zend_uint T; 
    183   zend_brk_cont_element *brk_cont_array; 
    184   zend_uint last_brk_cont; 
    185 #ifdef ZEND_ENGINE_2 
    186         /* HOESH: try & catch support */ 
    187         zend_try_catch_element* try_catch_array; 
    188         int last_try_catch; 
    189 #endif 
    190   HashTable *static_variables; 
    191   char *filename; 
    192 #ifdef ZEND_ENGINE_2 
    193   zend_uint line_start; 
    194   zend_uint line_end; 
    195   char *doc_comment; 
    196   zend_uint doc_comment_len; 
    197 #endif 
    198 } eaccelerator_op_array; 
    199  
    200 typedef struct _eaccelerator_class_entry { 
    201   char type; 
    202   char *name; 
    203   char *name_lc; 
    204   uint name_length; 
    205   char *parent; 
    206   HashTable function_table; 
    207   HashTable default_properties; 
    208 #ifdef ZEND_ENGINE_2 
    209   zend_uint ce_flags; 
    210   HashTable *static_members; 
    211   HashTable properties_info; 
    212   HashTable constants_table; 
    213   zend_uint num_interfaces; 
    214   char **interfaces; 
    215   zend_class_iterator_funcs iterator_funcs; 
    216  
    217   zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC); 
    218   zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object TSRMLS_DC); 
    219   int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */ 
    220      
    221   char *filename; 
    222   zend_uint line_start; 
    223   zend_uint line_end; 
    224   char *doc_comment; 
    225   zend_uint doc_comment_len; 
    226 #endif 
    227 } eaccelerator_class_entry; 
    228  
    229 /* 
    230  * To cache functions and classes. 
    231  */ 
    232 typedef struct _mm_fc_entry { 
    233   void   *fc; 
    234   struct _mm_fc_entry *next; 
    235   int    htablen; 
    236   char   htabkey[1];         /* must be last element */ 
    237 } mm_fc_entry; 
    238  
    239 /* 
    240  * A mm_cache_entry is a bucket for one PHP script file. 
    241  * Nested  functions and classes which defined in the file goes 
    242  * into the list of mm_fc_entry. 
    243  */ 
    244 typedef struct _mm_cache_entry { 
    245   struct _mm_cache_entry *next; 
    246 #ifdef EACCELERATOR_USE_INODE 
    247   dev_t                  st_dev;         /* file's device                     */ 
    248   ino_t                  st_ino;         /* file's inode                      */ 
    249 #else 
    250   unsigned int           hv;             /* hash value                        */ 
    251 #endif 
    252   off_t                  filesize;       /* file size */ 
    253   time_t                 mtime;          /* file last modification time       */ 
    254   time_t                 ttl;            /* expiration time                   */ 
    255   int                    size;           /* entry size (bytes)                */ 
    256   int                    nhits;          /* hits count                        */ 
    257   int                    nreloads;       /* count of reloads                  */ 
    258   int                    use_cnt;        /* how many processes uses the entry */ 
    259   eaccelerator_op_array       *op_array;      /* script's global scope code        */ 
    260   mm_fc_entry            *f_head;        /* list of nested functions          */ 
    261   mm_fc_entry            *c_head;        /* list of nested classes            */ 
    262   zend_bool              removed;        /* the entry is scheduled to remove  */ 
    263   char                   realfilename[1];/* real file name (must be last el.) */ 
    264 } mm_cache_entry; 
    265  
    266 /* 
    267  * bucket for user's cache 
    268  */ 
    269 typedef struct _mm_user_cache_entry { 
    270   struct _mm_user_cache_entry *next; 
    271   unsigned int           hv;            /* hash value                  */ 
    272   long                   ttl;           /* expiration time             */ 
    273   int                    size; 
    274   zval                   value;         /* value                       */ 
    275   char                   key[1];        /* key value (must be last el) */ 
    276 } mm_user_cache_entry; 
    277  
    278 /* 
    279  * Linked list of mm_cache_entry which are used by process/thread 
    280  */ 
    281 typedef struct _mm_used_entry { 
    282   struct _mm_used_entry *next; 
    283   mm_cache_entry        *entry; 
    284 } mm_used_entry; 
    285  
    286 /* 
    287  * Linked list of locks 
    288  */ 
    289 typedef struct _mm_lock_entry { 
    290   struct _mm_lock_entry *next; 
    291   pid_t  pid; 
    292 #ifdef ZTS 
    293   THREAD_T thread; 
    294 #endif 
    295   char                  key[1]; 
    296 } mm_lock_entry; 
    297  
    298 typedef struct _mm_file_header { 
    299   char   magic[8];        /* "EACCELERATOR" */ 
    300   int    eaccelerator_version; 
    301   int    zend_version; 
    302   int    php_version; 
    303   int    size; 
    304   time_t mtime; 
    305   unsigned int crc32; 
    306 } mm_file_header; 
    307  
    308 #ifdef ZTS 
    309 #  define ZTS_LOCK()    tsrm_mutex_lock(mm_mutex) 
    310 #  define ZTS_UNLOCK()  tsrm_mutex_unlock(mm_mutex) 
    311 #else 
    312 #  define ZTS_LOCK() 
    313 #  define ZTS_UNLOCK() 
    314 #endif 
    315  
    316 #include "mm.h" 
    317  
    318 #if defined(EACCELERATOR_PROTECT_SHM) 
    319 #  define EACCELERATOR_PROTECT()    do {mm_protect(eaccelerator_mm_instance->mm, MM_PROT_READ);} while(0) 
    320 #  define EACCELERATOR_UNPROTECT()  do {mm_protect(eaccelerator_mm_instance->mm, MM_PROT_READ|MM_PROT_WRITE);} while(0) 
    321 #else 
    322 #  define EACCELERATOR_PROTECT() 
    323 #  define EACCELERATOR_UNPROTECT() 
    324 #endif 
    325  
    326 #define EACCELERATOR_LOCK_RW()    do {ZTS_LOCK(); mm_lock(eaccelerator_mm_instance->mm, MM_LOCK_RW);} while(0) 
    327 #define EACCELERATOR_LOCK_RD()    do {ZTS_LOCK(); mm_lock(eaccelerator_mm_instance->mm, MM_LOCK_RD);} while(0) 
    328 #define EACCELERATOR_UNLOCK()     do {mm_unlock(eaccelerator_mm_instance->mm); ZTS_UNLOCK();} while(0) 
    329 #define EACCELERATOR_UNLOCK_RW()  EACCELERATOR_UNLOCK() 
    330 #define EACCELERATOR_UNLOCK_RD()  EACCELERATOR_UNLOCK() 
    331  
    332 #define EACCELERATOR_BLOCK_INTERRUPTIONS()   HANDLE_BLOCK_INTERRUPTIONS() 
    333 #define EACCELERATOR_UNBLOCK_INTERRUPTIONS() HANDLE_UNBLOCK_INTERRUPTIONS() 
    334  
    335 #define MM_HASH_SIZE      256 
    336 #define MM_USER_HASH_SIZE 256 
    337 #define MM_HASH_MAX       (MM_HASH_SIZE-1) 
    338 #define MM_USER_HASH_MAX  (MM_USER_HASH_SIZE-1) 
    339  
    340 #define eaccelerator_malloc(size)        mm_malloc(eaccelerator_mm_instance->mm, size) 
    341 #define eaccelerator_free(x)             mm_free(eaccelerator_mm_instance->mm, x) 
    342 #define eaccelerator_malloc_nolock(size) mm_malloc_nolock(eaccelerator_mm_instance->mm, size) 
    343 #define eaccelerator_free_nolock(x)      mm_free_nolock(eaccelerator_mm_instance->mm, x) 
    344  
    345 typedef struct { 
    346   MM             *mm; 
    347   pid_t          owner; 
    348   size_t         total; 
    349   unsigned int   hash_cnt; 
    350   unsigned int   user_hash_cnt; 
    351   zend_bool      enabled; 
    352   zend_bool      optimizer_enabled; 
    353   unsigned int   rem_cnt; 
    354   time_t         last_prune; 
    355   mm_cache_entry *removed; 
    356   mm_lock_entry  *locks; 
    357  
    358   mm_cache_entry      *hash[MM_HASH_SIZE]; 
    359   mm_user_cache_entry *user_hash[MM_USER_HASH_SIZE]; 
    360 } eaccelerator_mm; 
    361  
    362 /* 
    363  * Globals (different for each process/thread) 
    364  */ 
     106/* Globals (different for each process/thread) */ 
    365107ZEND_DECLARE_MODULE_GLOBALS(eaccelerator) 
    366108 
    367 /* 
    368  * Globals (common for each process/thread) 
    369  */ 
     109/* Globals (common for each process/thread) */ 
    370110static long eaccelerator_shm_size = 0; 
    371 static long eaccelerator_shm_max = 0; 
     111long eaccelerator_shm_max = 0; 
    372112static long eaccelerator_shm_ttl = 0; 
    373113static long eaccelerator_shm_prune_period = 0; 
     
    375115static zend_bool eaccelerator_check_mtime = 1; 
    376116static zend_bool eaccelerator_scripts_shm_only = 0; 
    377 static eaccelerator_cache_place eaccelerator_keys_cache_place     = eaccelerator_shm_and_disk; 
    378 static eaccelerator_cache_place eaccelerator_sessions_cache_place = eaccelerator_shm_and_disk; 
    379        eaccelerator_cache_place eaccelerator_content_cache_place  = eaccelerator_shm_and_disk; 
    380  
    381 static eaccelerator_mm* eaccelerator_mm_instance = NULL; 
     117 
     118eaccelerator_mm* eaccelerator_mm_instance = NULL; 
    382119static int eaccelerator_is_zend_extension = 0; 
    383120static int eaccelerator_is_extension      = 0; 
     
    390127static HashTable eaccelerator_global_class_table; 
    391128 
    392 static int binary_eaccelerator_version; 
    393 static int binary_php_version; 
    394 static int binary_zend_version; 
     129int binary_eaccelerator_version; 
     130int binary_php_version; 
     131int binary_zend_version; 
     132 
     133FILE *F_fp; 
    395134 
    396135/* saved original functions */ 
     
    407146ZEND_DLEXPORT zend_op_array* eaccelerator_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); 
    408147 
    409  
    410 #if defined(DEBUG) || defined(TEST_PERFORMANCE)  || defined(PROFILE_OPCODES) 
    411 #include <ctype.h> 
    412 #include <stdio.h> 
    413 static FILE *F_fp; 
    414  
    415 static void binary_print(char *p, int len) { 
    416   while (len--) { 
    417     fputc(*p++, F_fp); 
    418   } 
    419   fputc('\n', F_fp); 
    420 
    421  
    422 static void log_hashkeys(char *p, HashTable *ht) 
    423 
    424   Bucket *b; 
    425   int i = 0; 
    426  
    427   b = ht->pListHead; 
    428  
    429   fputs(p, F_fp); 
    430   while (b) { 
    431     fprintf(F_fp, "[%d] ", i); 
    432     binary_print(b->arKey, b->nKeyLength); 
    433  
    434     b = b->pListNext; 
    435     i++; 
    436   } 
    437 
    438  
    439 static void pad(TSRMLS_D) { 
    440   int i = MMCG(xpad); 
    441   while (i-- > 0) { 
    442     fputc('\t', F_fp); 
    443   } 
    444 
    445  
    446 static void start_time(struct timeval *tvstart) { 
    447   gettimeofday(tvstart, NULL); 
    448 
    449  
    450 static long elapsed_time(struct timeval *tvstart) { 
    451   struct timeval tvend; 
    452   int sec, usec; 
    453   gettimeofday(&tvend, NULL); 
    454   sec = tvend.tv_sec - tvstart->tv_sec; 
    455   usec = tvend.tv_usec - tvstart->tv_usec; 
    456   return sec * 1000000 + usec; 
    457 
    458 #endif  /* #if defined(DEBUG) || defined(TEST_PERFORMANCE)  || defined(PROFILE_OPCODES) */ 
    459  
    460 static inline unsigned int hash_mm(const char *data, int len) { 
     148/******************************************************************************/ 
     149/* hash mm functions                                                                                                              */ 
     150/* TODO: insert items sorted in buckets, so searching in buckets goes from        */ 
     151/*                      O(n) to O(log n) 
     152/******************************************************************************/ 
     153 
     154/* Create a key for the scripts hashtable. This is only used when eA can't use 
     155   inodes. */ 
     156inline unsigned int hash_mm(const char *data, int len) { 
    461157  unsigned int h; 
    462158  const char *e = data + len; 
     
    468164} 
    469165 
     166/* Find a script entry with the given hash key */ 
    470167static mm_cache_entry* hash_find_mm(const char  *key, 
    471168                                    struct stat *buf, 
     
    538235} 
    539236 
     237/* Add a new entry to the hashtable */ 
    540238static void hash_add_mm(mm_cache_entry *x) { 
    541239  mm_cache_entry *p,*q; 
     
    585283} 
    586284 
     285/* Initialise the shared memory */ 
    587286static int init_mm(TSRMLS_D) { 
    588287  pid_t  owner = getpid(); 
     
    620319#endif 
    621320  total = mm_available(mm); 
    622   eaccelerator_mm_instance = mm_malloc(mm, sizeof(*eaccelerator_mm_instance)); 
     321  eaccelerator_mm_instance = mm_malloc_lock(mm, sizeof(*eaccelerator_mm_instance)); 
    623322  if (!eaccelerator_mm_instance) { 
    624323    return FAILURE; 
     
    641340} 
    642341 
     342/* Clean up the shared memory */ 
    643343static void shutdown_mm(TSRMLS_D) { 
    644344  if (eaccelerator_mm_instance) { 
     
    668368} 
    669369 
    670 static void debug_printf(char *format, ...) { 
    671   char output_buf[512]; 
    672   va_list args; 
    673  
    674   va_start(args, format); 
    675   vsnprintf(output_buf, sizeof(output_buf), format, args); 
    676   va_end(args); 
    677  
    678 #ifdef ZEND_WIN32 
    679   OutputDebugString(output_buf); 
    680 /*  zend_printf("EACCELERATOR: %s<br>\n",output_buf);*/ 
    681 #else 
    682   fputs(output_buf, stderr); 
    683 #endif 
    684 } 
    685  
    686370/******************************************************************************/ 
     371/* Prepare values to cache them                                                                                           */ 
     372/******************************************************************************/ 
    687373 
    688374#define FIXUP(x) if((x)!=NULL) {(x) = (void*)(((char*)(x)) + ((long)(MMCG(mem))));} 
    689  
    690 static void fixup_zval(zval* z TSRMLS_DC); 
    691375 
    692376typedef void (*fixup_bucket_t)(void* TSRMLS_DC); 
     
    701385#endif 
    702386 
    703 static void fixup_hash(HashTable* source, fixup_bucket_t fixup_bucket TSRMLS_DC) { 
     387/* Prepare a zend HashTable for caching */ 
     388static void fixup_hash(HashTable* source, fixup_bucket_t fixup_bucket TSRMLS_DC)  
     389
    704390  unsigned int i; 
    705391  Bucket *p; 
     
    737423} 
    738424 
    739 static void fixup_zval(zval* zv TSRMLS_DC) { 
     425/* Prepare a zval for caching */ 
     426void fixup_zval(zval* zv TSRMLS_DC) { 
    740427  switch (zv->type & ~IS_CONSTANT_INDEX) { 
    741428    case IS_CONSTANT: 
     
    773460} 
    774461 
     462/* Prepare an opcode array for caching */ 
    775463static void fixup_op_array(eaccelerator_op_array* from TSRMLS_DC) { 
    776464  zend_op *opline; 
     
    828516  FIXUP(from->brk_cont_array); 
    829517#ifdef ZEND_ENGINE_2 
    830         /* HOESH: try & catch support */ 
    831         FIXUP(from->try_catch_array); 
     518  FIXUP(from->try_catch_array); 
    832519#endif 
    833520  if (from->static_variables != NULL) { 
     
    841528} 
    842529 
     530/* Prepare a class entry for caching */ 
    843531static void fixup_class_entry(eaccelerator_class_entry* from TSRMLS_DC) { 
    844532  FIXUP(from->name); 
     
    860548} 
    861549 
     550/* Prepare a cache entry for caching */ 
    862551static void eaccelerator_fixup(mm_cache_entry *p TSRMLS_DC) { 
    863552  mm_fc_entry* q; 
     
    948637#endif 
    949638 
    950 static int eaccelerator_md5(char* s, const char* prefix, const char* key TSRMLS_DC) { 
     639/* Function to create a hash key when filenames are used */ 
     640int eaccelerator_md5(char* s, const char* prefix, const char* key TSRMLS_DC) { 
    951641#if defined(PHP_MAJOR_VERSION) && defined(PHP_MINOR_VERSION) && \ 
    952642    ((PHP_MAJOR_VERSION > 4) || (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION > 1)) 
     
    957647  md5str[0] = '\0'; 
    958648  PHP_MD5Init(&context); 
    959   PHP_MD5Update(&context, key, strlen(key)); 
     649  PHP_MD5Update(&context, (unsigned char*)key, strlen(key)); 
    960650  PHP_MD5Final(digest, &context); 
    961651  make_digest(md5str, digest); 
     
    986676} 
    987677 
    988 static void eaccelerator_prune(time_t t) { 
     678/* Remove expired keys, content and scripts from the cache */ 
     679void eaccelerator_prune(time_t t) { 
    989680  unsigned int i; 
    990681 
     
    1015706} 
    1016707 
    1017 static void* eaccelerator_malloc2(size_t size TSRMLS_DC) { 
     708/* Allocate a new cache chunk */ 
     709void* eaccelerator_malloc2(size_t size TSRMLS_DC) { 
    1018710  void *p = NULL; 
    1019711  time_t t; 
     
    1112804} 
    1113805 
     806/******************************************************************************/ 
     807/* Cache file functions.                                                                                                          */ 
     808/* TODO: create cache subdirectories -> speed improvement highly used servers */ 
     809/******************************************************************************/ 
     810 
     811/* Retrieve a cache entry from the cache directory */ 
    1114812static mm_cache_entry* hash_find_file(const char  *key, 
    1115813                                      struct stat *buf TSRMLS_DC) { 
     
    1216914} 
    1217915 
     916/* Add a cache entry to the cache directory */ 
    1218917static int hash_add_file(mm_cache_entry *p TSRMLS_DC) { 
    1219918  int f; 
     
    1268967 
    1269968/******************************************************************************/ 
     969/* Functions to calculate the size of different structure that a compiled php */ 
     970/* script contains.                                                                                                                       */ 
     971/******************************************************************************/ 
    1270972 
    1271973#ifndef DEBUG 
     
    1280982} 
    1281983 
    1282 static void calc_zval(zval* z TSRMLS_DC); 
    1283984static void calc_class_entry(zend_class_entry* from TSRMLS_DC); 
    1284985 
     
    13111012} 
    13121013 
     1014/* Calculate the size of a point to a class entry */ 
    13131015static void calc_class_entry_ptr(zend_class_entry** from TSRMLS_DC) { 
    13141016  calc_class_entry(*from TSRMLS_CC); 
     
    13161018#endif 
    13171019 
     1020/* Calculate the size of an HashTable */ 
    13181021static void calc_hash_int(HashTable* source, Bucket* start, calc_bucket_t calc_bucket TSRMLS_DC) { 
    13191022  Bucket* p; 
     
    13341037} 
    13351038 
    1336 static void calc_zval(zval* zv TSRMLS_DC) { 
     1039void calc_zval(zval* zv TSRMLS_DC) { 
    13371040  switch (zv->type & ~IS_CONSTANT_INDEX) { 
    13381041    case IS_CONSTANT: 
     
    13861089} 
    13871090 
     1091/* Calculate the size of an op_array */ 
    13881092static void calc_op_array(zend_op_array* from TSRMLS_DC) { 
    13891093  zend_op *opline; 
     
    14851189} 
    14861190 
     1191/* Calculate the size of a class entry */ 
    14871192static void calc_class_entry(zend_class_entry* from TSRMLS_DC) { 
    14881193  int i; 
     
    15381243} 
    15391244 
     1245/* Calculate the size of a cache entry with its given op_array and function and 
     1246   class bucket */ 
    15401247static int calc_size(char* key, zend_op_array* op_array, 
    15411248                     Bucket* f, Bucket *c TSRMLS_DC) { 
     
    15831290} 
    15841291 
     1292/******************************************************************************/ 
     1293/* Functions to store/cache data from the compiled script                                         */ 
    15851294/******************************************************************************/ 
    15861295 
     
    16041313} 
    16051314 
    1606 static void store_zval(zval* z TSRMLS_DC); 
    16071315static eaccelerator_class_entry* store_class_entry(zend_class_entry* from TSRMLS_DC); 
    16081316 
     
    17141422} 
    17151423 
    1716 static void store_zval(zval* zv TSRMLS_DC) { 
     1424void store_zval(zval* zv TSRMLS_DC) { 
    17171425  switch (zv->type & ~IS_CONSTANT_INDEX) { 
    17181426    case IS_CONSTANT: 
     
    20431751} 
    20441752 
     1753/* Create a cache entry from the given op_array, functions and classes of a  
     1754   script */ 
    20451755static mm_cache_entry* eaccelerator_store_int( 
    20461756                         char* key, int len, 
     
    20731783  while (c != NULL) { 
    20741784#ifdef DEBUG 
    2075   pad(TSRMLS_C); fprintf(F_fp, "[%d] eaccelerator_store_int:     class hashkey=", getpid()); binary_print(c->arKey, c->nKeyLength); fflush(F_fp); 
     1785    pad(TSRMLS_C); fprintf(F_fp, "[%d] eaccelerator_store_int:     class hashkey=", getpid()); binary_print(c->arKey, c->nKeyLength); fflush(F_fp); 
    20761786#endif 
    20771787    EACCELERATOR_ALIGN(MMCG(mem)); 
     
    21001810  while (f != NULL) { 
    21011811#ifdef DEBUG 
    2102   pad(TSRMLS_C); fprintf(F_fp, "[%d] eaccelerator_store_int:     function hashkey='%s'\n", getpid(), f->arKey); fflush(F_fp); 
     1812    pad(TSRMLS_C); fprintf(F_fp, "[%d] eaccelerator_store_int:     function hashkey='%s'\n", getpid(), f->arKey); fflush(F_fp); 
    21031813#endif 
    21041814    EACCELERATOR_ALIGN(MMCG(mem)); 
     
    21421852 
    21431853/* called after succesful compilation, from eaccelerator_compile file */ 
     1854/* Adds the data from the compilation of the script to the cache */ 
    21441855static int eaccelerator_store(char* key, struct stat *buf, int nreloads, 
    21451856                         zend_op_array* op_array, 
     
    22011912 
    22021913/******************************************************************************/ 
    2203  
    2204 static void restore_zval(zval * TSRMLS_DC); 
     1914/* Functions to restore a php script from shared memory                                           */ 
     1915/******************************************************************************/ 
     1916 
    22051917static zend_class_entry* restore_class_entry(zend_class_entry* to, eaccelerator_class_entry *from TSRMLS_DC); 
    22061918 
     
    22922004} 
    22932005 
    2294 static void restore_zval(zval *zv TSRMLS_DC) 
     2006void restore_zval(zval *zv TSRMLS_DC) 
    22952007{ 
    22962008  switch (zv->type & ~IS_CONSTANT_INDEX) { 
     
    26692381  to->filename         = from->filename; 
    26702382#ifdef ZEND_ENGINE_2 
    2671        /* HOESH: try & catch support */ 
    2672        to->try_catch_array   = from->try_catch_array; 
    2673        to->last_try_catch    = from->last_try_catch; 
     2383  /* HOESH: try & catch support */ 
     2384  to->try_catch_array   = from->try_catch_array; 
     2385  to->last_try_catch    = from->last_try_catch; 
    26742386  to->uses_this        = from->uses_this; 
    26752387 
     
    29862698} 
    29872699 
    2988 /* 
    2989  * Try to restore a file from the cache. 
    2990  */ 
     2700/* Try to restore a file from the cache. If the file isn't found in memory, the  
     2701   the disk cache is checked */ 
    29912702static zend_op_array* eaccelerator_restore(char *realname, struct stat *buf, 
    29922703                                      int *nreloads, time_t compile_time TSRMLS_DC) { 
     
    30292740 * TODO - check the algorithm (fl) 
    30302741 */ 
    3031  
    30322742static int match(const char* name, const char* pat) { 
    30332743  char p,k; 
     
    30982808} 
    30992809 
     2810/* Check if the file is ok to cache */ 
    31002811static int eaccelerator_ok_to_cache(char *realname TSRMLS_DC) { 
    31012812  mm_cond_entry *p; 
     
    33513062//         it makes just in time to every time. 
    33523063#ifdef ZEND_ENGINE_2 
    3353   zend_is_auto_global("_GET", sizeof("_SERVER")-1 TSRMLS_CC); 
    3354   zend_is_auto_global("_POST", sizeof("_SERVER")-1 TSRMLS_CC); 
    3355   zend_is_auto_global("_COOKIE", sizeof("_SERVER")-1 TSRMLS_CC); 
     3064  zend_is_auto_global("_GET", sizeof("_GET")-1 TSRMLS_CC); 
     3065  zend_is_auto_global("_POST", sizeof("_POST")-1 TSRMLS_CC); 
     3066  zend_is_auto_global("_COOKIE", sizeof("_COOKIE")-1 TSRMLS_CC); 
    33563067  zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); 
    33573068  zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC); 
    33583069  zend_is_auto_global("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC); 
    3359   zend_is_auto_global("_FILES", sizeof("_SERVER")-1 TSRMLS_CC); 
     3070  zend_is_auto_global("_FILES", sizeof("_FILES")-1 TSRMLS_CC); 
    33603071#endif 
    33613072  if (t != NULL) { 
     
    36913402 
    36923403/* Format Bytes */ 
    3693 static void format_size(char* s, unsigned int size, int legend) { 
     3404void format_size(char* s, unsigned int size, int legend) { 
    36943405  unsigned int i = 0; 
    36953406  unsigned int n = 0; 
     
    37163427} 
    37173428 
     3429/* eAccelerator entry for phpinfo() */ 
    37183430PHP_MINFO_FUNCTION(eaccelerator) { 
    37193431  char s[32]; 
     
    37513463} 
    37523464 
    3753 /* User Cache Routines (put, get, rm, gc) */ 
    3754  
    3755 static char* build_key(const char* key, int key_len, int *xlen TSRMLS_DC) { 
    3756   int len; 
    3757  
    3758   /* namespace */ 
    3759   len = strlen(MMCG(name_space)); 
    3760   if (len > 0) { 
    3761     char* xkey; 
    3762     *xlen = len + key_len + 1; 
    3763     xkey = emalloc((*xlen)+1); 
    3764     memcpy(xkey, MMCG(name_space), len); 
    3765     xkey[len] = ':'; 
    3766     memcpy(xkey+len+1, key, key_len+1); 
    3767     return xkey; 
    3768   } 
    3769  
    3770   /* hostname */ 
    3771   len = strlen(MMCG(hostname)); 
    3772   if (len > 0) { 
    3773     char* xkey; 
    3774     *xlen = len + key_len + 1; 
    3775     xkey = emalloc((*xlen)+1); 
    3776     memcpy(xkey, MMCG(hostname), len); 
    3777     xkey[len] = ':'; 
    3778     memcpy(xkey+len+1, key, key_len+1); 
    3779     return xkey; 
    3780   } else { 
    3781     *xlen = key_len; 
    3782     return (char*)key; 
    3783   } 
    3784 
    3785  
    3786 static int eaccelerator_lock(const char* key, int key_len TSRMLS_DC) { 
    3787   int xlen; 
    3788   char* xkey; 
    3789   mm_lock_entry* x; 
    3790   mm_lock_entry** p; 
    3791   int ok = 0; 
    3792  
    3793   if (eaccelerator_mm_instance == NULL) { 
    3794     return 0; 
    3795   } 
    3796   xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
    3797   EACCELERATOR_UNPROTECT(); 
    3798   x = eaccelerator_malloc(offsetof(mm_lock_entry,key)+xlen+1); 
    3799   if (x == NULL) { 
    3800     EACCELERATOR_PROTECT(); 
    3801     if (xlen != key_len) {efree(xkey);} 
    3802     return 0; 
    3803   } 
    3804   x->pid = getpid(); 
    3805 #ifdef ZTS 
    3806   x->thread = tsrm_thread_id(); 
    3807 #endif 
    3808   x->next = NULL; 
    3809   memcpy(x->key, xkey, xlen+1); 
    3810   while (1) { 
    3811     EACCELERATOR_LOCK_RW(); 
    3812     p = &eaccelerator_mm_instance->locks; 
    3813     while ((*p) != NULL) { 
    3814       if (strcmp((*p)->key,x->key) == 0) { 
    3815 #ifdef ZTS 
    3816         if (x->pid == (*p)->pid && x->thread == (*p)->thread) { 
    3817 #else 
    3818         if (x->pid == (*p)->pid) { 
    3819 #endif 
    3820           ok = 1; 
    3821           eaccelerator_free_nolock(x); 
    3822         } 
    3823         break; 
    3824       } 
    3825       p = &(*p)->next; 
    3826     } 
    3827     if ((*p) == NULL) { 
    3828       *p = x; 
    3829       ok = 1; 
    3830     } 
    3831     EACCELERATOR_UNLOCK_RW(); 
    3832     if (ok) { 
    3833       break; 
    3834     } else { 
    3835 #ifdef ZEND_WIN32 
    3836       Sleep(100); 
    3837 /*??? 
    3838 #elif defined(HAVE_SCHED_YIELD) 
    3839       sched_yield(); 
    3840 */ 
    3841 #else 
    3842       struct timeval t; 
    3843       t.tv_sec = 0; 
    3844       t.tv_usec = 100; 
    3845       select(0, NULL, NULL, NULL, &t); 
    3846 #endif 
    3847     } 
    3848   } 
    3849   EACCELERATOR_PROTECT(); 
    3850   if (xlen != key_len) {efree(xkey);} 
    3851   return 1; 
    3852 
    3853  
    3854 static int eaccelerator_unlock(const char* key, int key_len TSRMLS_DC) { 
    3855   int xlen; 
    3856   char* xkey; 
    3857   mm_lock_entry** p; 
    3858  
    3859   if (eaccelerator_mm_instance == NULL) { 
    3860     return 0; 
    3861   } 
    3862   xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
    3863   EACCELERATOR_UNPROTECT(); 
    3864   EACCELERATOR_LOCK_RW(); 
    3865   p = &eaccelerator_mm_instance->locks; 
    3866   while ((*p) != NULL) { 
    3867     if (strcmp((*p)->key,xkey) == 0) { 
    3868 #ifdef ZTS 
    3869       if ((*p)->pid == getpid() && (*p)->thread == tsrm_thread_id()) { 
    3870 #else 
    3871       if ((*p)->pid == getpid()) { 
    3872 #endif 
    3873          mm_lock_entry *x = (*p); 
    3874         *p = (*p)->next; 
    3875         eaccelerator_free_nolock(x); 
    3876       } else { 
    3877         EACCELERATOR_UNLOCK_RW(); 
    3878         EACCELERATOR_PROTECT(); 
    3879         if (xlen != key_len) {efree(xkey);} 
    3880         return 0; 
    3881       } 
    3882       break; 
    3883     } 
    3884     p = &(*p)->next; 
    3885   } 
    3886   EACCELERATOR_UNLOCK_RW(); 
    3887   EACCELERATOR_PROTECT(); 
    3888   if (xlen != key_len) {efree(xkey);} 
    3889   return 1; 
    3890 
    3891  
    3892 int eaccelerator_put(const char* key, int key_len, zval* val, time_t ttl, eaccelerator_cache_place where TSRMLS_DC) { 
    3893   mm_user_cache_entry *p, *q; 
    3894   unsigned int slot; 
    3895   long size; 
    3896   int use_shm = 1; 
    3897   int ret = 0; 
    3898   char s[MAXPATHLEN]; 
    3899   int xlen; 
    3900   char* xkey; 
    3901  
    3902   xkey = build_key(key, key_len, &xlen TSRMLS_CC); 
    3903   MMCG(compress) = 1; 
    3904   MMCG(mem) = NULL; 
    3905   zend_hash_init(&MMCG(strings), 0, NULL, NULL, 0); 
    3906   EACCELERATOR_ALIGN(MMCG(mem)); 
    3907   MMCG(mem) += offsetof(mm_user_cache_entry, key)+xlen+1; 
    3908   calc_zval(val TSRMLS_CC); 
    3909   zend_hash_destroy(&MMCG(strings)); 
    3910  
    3911   size = (long)MMCG(mem); 
    3912  
    3913   MMCG(mem) = NULL; 
    3914   if (eaccelerator_mm_instance != NULL && 
    3915       (where == eaccelerator_shm_and_disk || 
    3916        where == eaccelerator_shm || 
    3917        where == eaccelerator_shm_only)) { 
    3918     EACCELERATOR_UNPROTECT(); 
    3919     if (eaccelerator_shm_max == 0 || size <= eaccelerator_shm_max) { 
    3920       MMCG(mem) = eaccelerator_malloc(size); 
    3921       if (MMCG(mem) == NULL) { 
    3922         MMCG(mem) = eaccelerator_malloc2(size TSRMLS_CC); 
    3923       } 
    3924     } 
    3925     if (MMCG(mem) == NULL) { 
    3926       EACCELERATOR_PROTECT(); 
    3927     } 
    3928   } 
    3929   if (MMCG(mem) == NULL && 
    3930       (where == eaccelerator_shm_and_disk || 
    3931        where == eaccelerator_shm || 
    3932        where == eaccelerator_disk_only)) { 
    3933     use_shm = 0; 
    3934     MMCG(mem) = emalloc(size); 
    3935   } 
    3936   if (MMCG(mem)) { 
    3937     zend_hash_init(&MMCG(strings), 0, NULL, NULL, 0); 
    3938     EACCELERATOR_ALIGN(MMCG(mem)); 
    3939     q = (mm_user_cache_entry*)MMCG(mem); 
    3940     q->size = size; 
    3941     MMCG(mem) += offsetof(mm_user_cache_entry,key)+xlen+1; 
    3942     q->hv = hash_mm(xkey, xlen);; 
    3943     memcpy(q->key, xkey, xlen+1); 
    3944     memcpy(&q->value, val, sizeof(zval)); 
    3945     q->ttl = ttl?time(0)+ttl:0; 
    3946     store_zval(&q->value TSRMLS_CC); 
    3947     zend_hash_destroy(&MMCG(strings)); 
    3948  
    3949     /* storing to file */ 
    3950     if ((where == eaccelerator_shm_and_disk || 
    3951          ((where == eaccelerator_shm) && !use_shm) || 
    3952          where == eaccelerator_disk_only) && 
    3953         eaccelerator_md5(s, "/eaccelerator-user-", q->key TSRMLS_CC)) { 
    3954       int f; 
    3955       unlink(s); 
    3956       f = open(s, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR); 
    3957       if (f > 0) { 
    3958         mm_file_header hdr; 
    3959         EACCELERATOR_FLOCK(f, LOCK_EX); 
    3960         strcpy(hdr.magic,"EACCELERATOR"); 
    3961         hdr.eaccelerator_version = binary_eaccelerator_version; 
    3962         hdr.zend_version    = binary_zend_version; 
    3963         hdr.php_version     = binary_php_version; 
    3964         hdr.size  = q->size; 
    3965         hdr.mtime = q->ttl; 
    3966         q->next = q; 
    3967         hdr.crc32 = eaccelerator_crc32((const char*)q,q->size); 
    3968         if (write(f, &hdr, sizeof(hdr)) == sizeof(hdr)) { 
    3969           write(f, q, q->size); 
    3970           EACCELERATOR_FLOCK(f, LOCK_UN); 
    3971           close(f); 
    3972