Changeset 64
- Timestamp:
- 04/26/05 16:48:00 (3 years ago)
- Files:
-
- eaccelerator/trunk/Makefile.in (modified) (1 diff)
- eaccelerator/trunk/cache.c (added)
- eaccelerator/trunk/cache.h (added)
- eaccelerator/trunk/config.m4 (modified) (2 diffs)
- eaccelerator/trunk/content.c (modified) (3 diffs)
- eaccelerator/trunk/content.h (added)
- eaccelerator/trunk/debug.c (added)
- eaccelerator/trunk/debug.h (added)
- eaccelerator/trunk/eaccelerator.c (modified) (59 diffs)
- eaccelerator/trunk/eaccelerator.h (modified) (6 diffs)
- eaccelerator/trunk/session.c (added)
- eaccelerator/trunk/session.h (added)
- eaccelerator/trunk/shm.c (added)
- eaccelerator/trunk/shm.h (added)
- eaccelerator/trunk/webui.c (added)
- eaccelerator/trunk/webui.h (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
eaccelerator/trunk/Makefile.in
r4 r64 1 1 LTLIBRARY_NAME = libeaccelerator.la 2 LTLIBRARY_SOURCES = eaccelerator.c optimize.c execute.c encoder.c loader.c opcodes.c content.c mm.c 2 LTLIBRARY_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 3 3 LTLIBRARY_SHARED_NAME = eaccelerator.la 4 4 eaccelerator/trunk/config.m4
r4 r64 30 30 ],[ 31 31 eaccelerator_loader=yes 32 ]) 33 34 AC_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 41 AC_ARG_WITH(eaccelerator-webui, 42 [ --without-eaccelerator-webui Do not include the eaccelerator WebUI],[ 43 eaccelerator_webui=$withval 44 ],[ 45 eaccelerator_webui=yes 32 46 ]) 33 47 … … 76 90 if test "$eaccelerator_loader" = "yes"; then 77 91 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]) 78 98 fi 79 99 if test "$eaccelerator_sessions" = "yes"; then eaccelerator/trunk/content.c
r21 r64 3 3 | eAccelerator project | 4 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 2004 eAccelerator|6 | http://eaccelerator. sourceforge.net|5 | Copyright (c) 2004 - 2005 eAccelerator | 6 | http://eaccelerator.net | 7 7 +----------------------------------------------------------------------+ 8 8 | This program is free software; you can redistribute it and/or | … … 33 33 #ifdef WITH_EACCELERATOR_CONTENT_CACHING 34 34 35 #include "cache.h" 36 #include "content.h" 35 37 #include "SAPI.h" 36 38 37 39 #define EACCELERATOR_COMPRESS_MIN 128 38 40 41 eaccelerator_cache_place eaccelerator_content_cache_place = eaccelerator_shm_and_disk; 42 39 43 static int (*eaccelerator_old_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); 44 45 PHP_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 } 40 74 41 75 static int eaccelerator_check_compression(sapi_header_struct *sapi_header TSRMLS_DC) { … … 131 165 add_next_index_stringl(headers, s, h->header_len+1, 0); 132 166 p = p->next; 167 efree(s); 133 168 } 134 169 add_assoc_zval(&cache_array, "headers", headers); eaccelerator/trunk/eaccelerator.c
r60 r64 3 3 | eAccelerator project | 4 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 2004 eAccelerator|6 | http://eaccelerator. sourceforge.net|5 | Copyright (c) 2004 - 2005 eAccelerator | 6 | http://eaccelerator.net | 7 7 +----------------------------------------------------------------------+ 8 8 | This program is free software; you can redistribute it and/or | … … 41 41 #include "zend_extensions.h" 42 42 43 #include "webui.h" 44 #include "debug.h" 45 #include "shm.h" 46 #include "session.h" 47 #include "content.h" 48 43 49 #include <sys/types.h> 44 50 #include <sys/stat.h> … … 96 102 #include "SAPI.h" 97 103 98 #undef HAVE_PHP_SESSIONS_SUPPORT99 #ifdef HAVE_EXT_SESSION_PHP_SESSION_H100 # include "ext/session/php_session.h"101 # ifdef PHP_SESSION_API102 # if PHP_SESSION_API >= 20020306103 # define HAVE_PHP_SESSIONS_SUPPORT104 static int eaccelerator_sessions_registered = 0;105 # ifdef PS_CREATE_SID_ARGS106 # include "ext/standard/php_lcg.h"107 # endif108 # endif109 # endif110 #endif111 112 104 #define MAX_DUP_STR_LEN 256 113 105 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) */ 365 107 ZEND_DECLARE_MODULE_GLOBALS(eaccelerator) 366 108 367 /* 368 * Globals (common for each process/thread) 369 */ 109 /* Globals (common for each process/thread) */ 370 110 static long eaccelerator_shm_size = 0; 371 staticlong eaccelerator_shm_max = 0;111 long eaccelerator_shm_max = 0; 372 112 static long eaccelerator_shm_ttl = 0; 373 113 static long eaccelerator_shm_prune_period = 0; … … 375 115 static zend_bool eaccelerator_check_mtime = 1; 376 116 static 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 118 eaccelerator_mm* eaccelerator_mm_instance = NULL; 382 119 static int eaccelerator_is_zend_extension = 0; 383 120 static int eaccelerator_is_extension = 0; … … 390 127 static HashTable eaccelerator_global_class_table; 391 128 392 static int binary_eaccelerator_version; 393 static int binary_php_version; 394 static int binary_zend_version; 129 int binary_eaccelerator_version; 130 int binary_php_version; 131 int binary_zend_version; 132 133 FILE *F_fp; 395 134 396 135 /* saved original functions */ … … 407 146 ZEND_DLEXPORT zend_op_array* eaccelerator_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); 408 147 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. */ 156 inline unsigned int hash_mm(const char *data, int len) { 461 157 unsigned int h; 462 158 const char *e = data + len; … … 468 164 } 469 165 166 /* Find a script entry with the given hash key */ 470 167 static mm_cache_entry* hash_find_mm(const char *key, 471 168 struct stat *buf, … … 538 235 } 539 236 237 /* Add a new entry to the hashtable */ 540 238 static void hash_add_mm(mm_cache_entry *x) { 541 239 mm_cache_entry *p,*q; … … 585 283 } 586 284 285 /* Initialise the shared memory */ 587 286 static int init_mm(TSRMLS_D) { 588 287 pid_t owner = getpid(); … … 620 319 #endif 621 320 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)); 623 322 if (!eaccelerator_mm_instance) { 624 323 return FAILURE; … … 641 340 } 642 341 342 /* Clean up the shared memory */ 643 343 static void shutdown_mm(TSRMLS_D) { 644 344 if (eaccelerator_mm_instance) { … … 668 368 } 669 369 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_WIN32679 OutputDebugString(output_buf);680 /* zend_printf("EACCELERATOR: %s<br>\n",output_buf);*/681 #else682 fputs(output_buf, stderr);683 #endif684 }685 686 370 /******************************************************************************/ 371 /* Prepare values to cache them */ 372 /******************************************************************************/ 687 373 688 374 #define FIXUP(x) if((x)!=NULL) {(x) = (void*)(((char*)(x)) + ((long)(MMCG(mem))));} 689 690 static void fixup_zval(zval* z TSRMLS_DC);691 375 692 376 typedef void (*fixup_bucket_t)(void* TSRMLS_DC); … … 701 385 #endif 702 386 703 static void fixup_hash(HashTable* source, fixup_bucket_t fixup_bucket TSRMLS_DC) { 387 /* Prepare a zend HashTable for caching */ 388 static void fixup_hash(HashTable* source, fixup_bucket_t fixup_bucket TSRMLS_DC) 389 { 704 390 unsigned int i; 705 391 Bucket *p; … … 737 423 } 738 424 739 static void fixup_zval(zval* zv TSRMLS_DC) { 425 /* Prepare a zval for caching */ 426 void fixup_zval(zval* zv TSRMLS_DC) { 740 427 switch (zv->type & ~IS_CONSTANT_INDEX) { 741 428 case IS_CONSTANT: … … 773 460 } 774 461 462 /* Prepare an opcode array for caching */ 775 463 static void fixup_op_array(eaccelerator_op_array* from TSRMLS_DC) { 776 464 zend_op *opline; … … 828 516 FIXUP(from->brk_cont_array); 829 517 #ifdef ZEND_ENGINE_2 830 /* HOESH: try & catch support */ 831 FIXUP(from->try_catch_array); 518 FIXUP(from->try_catch_array); 832 519 #endif 833 520 if (from->static_variables != NULL) { … … 841 528 } 842 529 530 /* Prepare a class entry for caching */ 843 531 static void fixup_class_entry(eaccelerator_class_entry* from TSRMLS_DC) { 844 532 FIXUP(from->name); … … 860 548 } 861 549 550 /* Prepare a cache entry for caching */ 862 551 static void eaccelerator_fixup(mm_cache_entry *p TSRMLS_DC) { 863 552 mm_fc_entry* q; … … 948 637 #endif 949 638 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 */ 640 int eaccelerator_md5(char* s, const char* prefix, const char* key TSRMLS_DC) { 951 641 #if defined(PHP_MAJOR_VERSION) && defined(PHP_MINOR_VERSION) && \ 952 642 ((PHP_MAJOR_VERSION > 4) || (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION > 1)) … … 957 647 md5str[0] = '\0'; 958 648 PHP_MD5Init(&context); 959 PHP_MD5Update(&context, key, strlen(key));649 PHP_MD5Update(&context, (unsigned char*)key, strlen(key)); 960 650 PHP_MD5Final(digest, &context); 961 651 make_digest(md5str, digest); … … 986 676 } 987 677 988 static void eaccelerator_prune(time_t t) { 678 /* Remove expired keys, content and scripts from the cache */ 679 void eaccelerator_prune(time_t t) { 989 680 unsigned int i; 990 681 … … 1015 706 } 1016 707 1017 static void* eaccelerator_malloc2(size_t size TSRMLS_DC) { 708 /* Allocate a new cache chunk */ 709 void* eaccelerator_malloc2(size_t size TSRMLS_DC) { 1018 710 void *p = NULL; 1019 711 time_t t; … … 1112 804 } 1113 805 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 */ 1114 812 static mm_cache_entry* hash_find_file(const char *key, 1115 813 struct stat *buf TSRMLS_DC) { … … 1216 914 } 1217 915 916 /* Add a cache entry to the cache directory */ 1218 917 static int hash_add_file(mm_cache_entry *p TSRMLS_DC) { 1219 918 int f; … … 1268 967 1269 968 /******************************************************************************/ 969 /* Functions to calculate the size of different structure that a compiled php */ 970 /* script contains. */ 971 /******************************************************************************/ 1270 972 1271 973 #ifndef DEBUG … … 1280 982 } 1281 983 1282 static void calc_zval(zval* z TSRMLS_DC);1283 984 static void calc_class_entry(zend_class_entry* from TSRMLS_DC); 1284 985 … … 1311 1012 } 1312 1013 1014 /* Calculate the size of a point to a class entry */ 1313 1015 static void calc_class_entry_ptr(zend_class_entry** from TSRMLS_DC) { 1314 1016 calc_class_entry(*from TSRMLS_CC); … … 1316 1018 #endif 1317 1019 1020 /* Calculate the size of an HashTable */ 1318 1021 static void calc_hash_int(HashTable* source, Bucket* start, calc_bucket_t calc_bucket TSRMLS_DC) { 1319 1022 Bucket* p; … … 1334 1037 } 1335 1038 1336 staticvoid calc_zval(zval* zv TSRMLS_DC) {1039 void calc_zval(zval* zv TSRMLS_DC) { 1337 1040 switch (zv->type & ~IS_CONSTANT_INDEX) { 1338 1041 case IS_CONSTANT: … … 1386 1089 } 1387 1090 1091 /* Calculate the size of an op_array */ 1388 1092 static void calc_op_array(zend_op_array* from TSRMLS_DC) { 1389 1093 zend_op *opline; … … 1485 1189 } 1486 1190 1191 /* Calculate the size of a class entry */ 1487 1192 static void calc_class_entry(zend_class_entry* from TSRMLS_DC) { 1488 1193 int i; … … 1538 1243 } 1539 1244 1245 /* Calculate the size of a cache entry with its given op_array and function and 1246 class bucket */ 1540 1247 static int calc_size(char* key, zend_op_array* op_array, 1541 1248 Bucket* f, Bucket *c TSRMLS_DC) { … … 1583 1290 } 1584 1291 1292 /******************************************************************************/ 1293 /* Functions to store/cache data from the compiled script */ 1585 1294 /******************************************************************************/ 1586 1295 … … 1604 1313 } 1605 1314 1606 static void store_zval(zval* z TSRMLS_DC);1607 1315 static eaccelerator_class_entry* store_class_entry(zend_class_entry* from TSRMLS_DC); 1608 1316 … … 1714 1422 } 1715 1423 1716 staticvoid store_zval(zval* zv TSRMLS_DC) {1424 void store_zval(zval* zv TSRMLS_DC) { 1717 1425 switch (zv->type & ~IS_CONSTANT_INDEX) { 1718 1426 case IS_CONSTANT: … … 2043 1751 } 2044 1752 1753 /* Create a cache entry from the given op_array, functions and classes of a 1754 script */ 2045 1755 static mm_cache_entry* eaccelerator_store_int( 2046 1756 char* key, int len, … … 2073 1783 while (c != NULL) { 2074 1784 #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); 2076 1786 #endif 2077 1787 EACCELERATOR_ALIGN(MMCG(mem)); … … 2100 1810 while (f != NULL) { 2101 1811 #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); 2103 1813 #endif 2104 1814 EACCELERATOR_ALIGN(MMCG(mem)); … … 2142 1852 2143 1853 /* called after succesful compilation, from eaccelerator_compile file */ 1854 /* Adds the data from the compilation of the script to the cache */ 2144 1855 static int eaccelerator_store(char* key, struct stat *buf, int nreloads, 2145 1856 zend_op_array* op_array, … … 2201 1912 2202 1913 /******************************************************************************/ 2203 2204 static void restore_zval(zval * TSRMLS_DC); 1914 /* Functions to restore a php script from shared memory */ 1915 /******************************************************************************/ 1916 2205 1917 static zend_class_entry* restore_class_entry(zend_class_entry* to, eaccelerator_class_entry *from TSRMLS_DC); 2206 1918 … … 2292 2004 } 2293 2005 2294 staticvoid restore_zval(zval *zv TSRMLS_DC)2006 void restore_zval(zval *zv TSRMLS_DC) 2295 2007 { 2296 2008 switch (zv->type & ~IS_CONSTANT_INDEX) { … … 2669 2381 to->filename = from->filename; 2670 2382 #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; 2674 2386 to->uses_this = from->uses_this; 2675 2387 … … 2986 2698 } 2987 2699 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 */ 2991 2702 static zend_op_array* eaccelerator_restore(char *realname, struct stat *buf, 2992 2703 int *nreloads, time_t compile_time TSRMLS_DC) { … … 3029 2740 * TODO - check the algorithm (fl) 3030 2741 */ 3031 3032 2742 static int match(const char* name, const char* pat) { 3033 2743 char p,k; … … 3098 2808 } 3099 2809 2810 /* Check if the file is ok to cache */ 3100 2811 static int eaccelerator_ok_to_cache(char *realname TSRMLS_DC) { 3101 2812 mm_cond_entry *p; … … 3351 3062 // it makes just in time to every time. 3352 3063 #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); 3356 3067 zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); 3357 3068 zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC); 3358 3069 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); 3360 3071 #endif 3361 3072 if (t != NULL) { … … 3691 3402 3692 3403 /* Format Bytes */ 3693 staticvoid format_size(char* s, unsigned int size, int legend) {3404 void format_size(char* s, unsigned int size, int legend) { 3694 3405 unsigned int i = 0; 3695 3406 unsigned int n = 0; … … 3716 3427 } 3717 3428 3429 /* eAccelerator entry for phpinfo() */ 3718 3430 PHP_MINFO_FUNCTION(eaccelerator) { 3719 3431 char s[32]; … … 3751 3463 } 3752 3464 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