root/eaccelerator/branches/new-cache/eaccelerator.h

Revision 330, 14.3 kB (checked in by hans, 1 year ago)

* Changed crash handler error message format to Apache-style error log format as suggested in ticket #217
* Fixed ticket #274
* Performance: eliminated a bunch of time() syscalls
* Performance: eliminated calls to eaccelerator_gc when not build with either session, shm or user cache functionality (which are all off by default)
* Disable eaccelerator_list_keys function when not build with either session, shm or user cache functionality (which are all off by default)
* Disable 'User Cache' tab in control panel when not build with either session, shm or user cache functionality (which are all off by default)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2007 eAccelerator                               |
6    | http://eaccelerator.net                                                  |
7    +----------------------------------------------------------------------+
8    | This program is free software; you can redistribute it and/or        |
9    | modify it under the terms of the GNU General Public License          |
10    | as published by the Free Software Foundation; either version 2       |
11    | of the License, or (at your option) any later version.               |
12    |                                                                      |
13    | This program is distributed in the hope that it will be useful,      |
14    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
15    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
16    | GNU General Public License for more details.                         |
17    |                                                                      |
18    | You should have received a copy of the GNU General Public License    |
19    | along with this program; if not, write to the Free Software          |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
21    | MA  02111-1307, USA.                                                 |
22    |                                                                      |
23    | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
24    +----------------------------------------------------------------------+
25    $Id$
26 */
27
28 #ifndef INCLUDED_EACCELERATOR_H
29 #define INCLUDED_EACCELERATOR_H
30
31 #include "php.h"
32 #include "zend.h"
33 #include "zend_API.h"
34 #include "zend_extensions.h"
35
36 #if !defined(ZEND_WIN32) && defined(HAVE_CONFIG_H)
37 #  if ZEND_MODULE_API_NO >= 20001222
38 #    include "config.h"
39 #  else
40 #    include "php_config.h"
41 #  endif
42 #endif
43
44 #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1
45 #   define ZEND_ENGINE_2_1
46 #endif
47
48 #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2
49 #   define ZEND_ENGINE_2_2
50 #endif
51
52 /* fixes compile errors on php5.1 */
53 #ifdef STR_EMPTY_ALLOC
54 #       define empty_string STR_EMPTY_ALLOC()
55 #endif
56
57 #if !defined(ZEND_WIN32) && defined(WITH_EACCELERATOR_USE_INODE)
58 /* UnDefine if your filesystem doesn't support inodes */
59 #  define EACCELERATOR_USE_INODE
60 #endif
61
62 #ifdef WITH_EACCELERATOR_CRASH_DETECTION
63 #  include <signal.h>
64 #endif
65
66 #define EACCELERATOR_MM_FILE "/tmp/eaccelerator"
67
68 #ifdef EACCELERATOR_WITHOUT_FILE_LOCKING
69 #  ifndef LOCK_SH
70 #    define LOCK_SH 1
71 #    define LOCK_EX 2
72 #    define LOCK_UN 8
73 #  endif
74 #  define EACCELERATOR_FLOCK(FILE,OP)
75 #else
76 #  ifndef ZEND_WIN32
77 #    ifdef HAVE_FLOCK
78 #          include <sys/file.h>
79 #      define EACCELERATOR_FLOCK(FILE,OP) flock((FILE),(OP))
80 #    else
81 #      ifndef LOCK_SH
82 #        define LOCK_SH 1
83 #        define LOCK_EX 2
84 #        define LOCK_UN 8
85 #      endif
86 #      define EACCELERATOR_FLOCK(FILE,OP)
87 #    endif
88 #  else
89 #    define LOCK_SH 0
90 #    define LOCK_EX 1
91 #    define LOCK_UN 2
92 #    define EACCELERATOR_FLOCK(FILE,OP) {OVERLAPPED offset = {0,0,0,0,NULL};\
93                                    if ((OP) == LOCK_EX) {\
94                                      LockFileEx((HANDLE)_get_osfhandle(FILE), \
95                                        LOCKFILE_EXCLUSIVE_LOCK, 0,\
96                                        1, 0, &offset);\
97                                    } else if ((OP) == LOCK_SH) {\
98                                      LockFileEx((HANDLE)_get_osfhandle(FILE), \
99                                        0, 0,\
100                                        1, 0, &offset);\
101                                    } else if ((OP) == LOCK_UN) {\
102                                      UnlockFileEx((HANDLE)_get_osfhandle(FILE), \
103                                        0,\
104                                        1, 0, &offset);\
105                                    }}
106 #  endif
107 #endif
108
109 #if !defined(_INTPTR_T_DEFINED) && ZEND_WIN32
110         typedef intptr_t;
111         #define _INTPTR_T_DEFINED
112 #endif
113
114 #if !defined(ssize_t) && ZEND_WIN32
115         /* define ssize_t for Win32. */
116         #define ssize_t int
117 #endif
118
119 #ifdef HAVE_EACCELERATOR
120
121 #include "mm.h"
122
123 #ifdef ZEND_WIN32
124 #  include <process.h>
125 #  ifndef S_ISREG
126 #    define S_ISREG(mode) (((mode)&S_IFMT) & S_IFREG)
127 #  endif
128 #  ifndef S_IRUSR
129 #    define S_IRUSR S_IREAD
130 #  endif
131 #  ifndef S_IWUSR
132 #    define S_IWUSR S_IWRITE
133 #  endif
134 #else
135 #  include <dirent.h>
136 #endif
137
138 #ifdef ZTS
139 #  define ZTS_LOCK()    tsrm_mutex_lock(ea_mutex)
140 #  define ZTS_UNLOCK()  tsrm_mutex_unlock(ea_mutex)
141 #else
142 #  define ZTS_LOCK()
143 #  define ZTS_UNLOCK()
144 #endif
145
146 #if defined(EACCELERATOR_PROTECT_SHM)
147 #  define EACCELERATOR_PROTECT()    do {mm_protect(eaccelerator_mm_instance->mm, MM_PROT_READ);} while(0)
148 #  define EACCELERATOR_UNPROTECT()  do {mm_protect(eaccelerator_mm_instance->mm, MM_PROT_READ|MM_PROT_WRITE);} while(0)
149 #else
150 #  define EACCELERATOR_PROTECT()
151 #  define EACCELERATOR_UNPROTECT()
152 #endif
153
154 #define EACCELERATOR_LOCK_RW()    do {ZTS_LOCK(); mm_lock(eaccelerator_mm_instance->mm, MM_LOCK_RW);} while(0)
155 #define EACCELERATOR_LOCK_RD()    do {ZTS_LOCK(); mm_lock(eaccelerator_mm_instance->mm, MM_LOCK_RD);} while(0)
156 #define EACCELERATOR_UNLOCK()     do {mm_unlock(eaccelerator_mm_instance->mm); ZTS_UNLOCK();} while(0)
157 #define EACCELERATOR_UNLOCK_RW()  EACCELERATOR_UNLOCK()
158 #define EACCELERATOR_UNLOCK_RD()  EACCELERATOR_UNLOCK()
159
160 #define EACCELERATOR_BLOCK_INTERRUPTIONS()   HANDLE_BLOCK_INTERRUPTIONS()
161 #define EACCELERATOR_UNBLOCK_INTERRUPTIONS() HANDLE_UNBLOCK_INTERRUPTIONS()
162
163 #define EACCELERATOR_HASH_LEVEL 2
164 #define EA_HASH_SIZE      512
165 #define EA_USER_HASH_SIZE 512
166
167 #define EA_HASH_MAX       (EA_HASH_SIZE-1)
168 #define EA_USER_HASH_MAX  (EA_USER_HASH_SIZE-1)
169
170 #define eaccelerator_malloc(size)        mm_malloc_lock(eaccelerator_mm_instance->mm, size)
171 #define eaccelerator_free(x)             mm_free_lock(eaccelerator_mm_instance->mm, x)
172 #define eaccelerator_malloc_nolock(size) mm_malloc_nolock(eaccelerator_mm_instance->mm, size)
173 #define eaccelerator_free_nolock(x)      mm_free_nolock(eaccelerator_mm_instance->mm, x)
174
175 #if (defined (__GNUC__) && __GNUC__ >= 2)
176 #define EACCELERATOR_PLATFORM_ALIGNMENT (__alignof__ (align_test))
177 #else
178 #define EACCELERATOR_PLATFORM_ALIGNMENT (sizeof(align_union))
179 #endif
180
181 #define EACCELERATOR_ALIGN(n) (n) = (void*)((((size_t)(n)-1) & ~(EACCELERATOR_PLATFORM_ALIGNMENT-1)) + EACCELERATOR_PLATFORM_ALIGNMENT)
182 #define EA_SIZE_ALIGN(n) (n) = ((((size_t)(n)-1) & ~(EACCELERATOR_PLATFORM_ALIGNMENT-1)) + EACCELERATOR_PLATFORM_ALIGNMENT)
183
184
185 #define MAX_DUP_STR_LEN 256
186
187 /******************************************************************************/
188
189
190 #ifndef offsetof
191 #  define offsetof(str,fld) ((size_t)&(((str*)NULL)->fld))
192 #endif
193
194 typedef struct _eaccelerator_op_array {
195         zend_uchar type;
196 #ifdef ZEND_ENGINE_2
197         zend_bool uses_this;
198 #else
199         zend_bool uses_globals;
200 #endif
201         zend_bool return_reference;
202 #ifdef ZEND_ENGINE_2
203         zend_uint num_args;
204         zend_uint required_num_args;
205         zend_arg_info *arg_info;
206         zend_bool pass_rest_by_reference;
207 #else
208         zend_uchar *arg_types;
209 #endif
210         char *function_name;
211 #ifdef ZEND_ENGINE_2
212         char *scope_name;
213         int scope_name_len;
214         zend_uint fn_flags;
215 #endif
216         zend_op *opcodes;
217         zend_uint last;
218 #ifdef ZEND_ENGINE_2_1
219         zend_compiled_variable *vars;
220     int last_var;
221 #endif
222         zend_uint T;
223         zend_brk_cont_element *brk_cont_array;
224         zend_uint last_brk_cont;
225 #ifdef ZEND_ENGINE_2
226         zend_try_catch_element *try_catch_array;
227         int last_try_catch;
228 #endif
229         HashTable *static_variables;
230         char *filename;
231 #ifdef ZEND_ENGINE_2
232         zend_uint line_start;
233         zend_uint line_end;
234 #ifdef INCLUDE_DOC_COMMENTS
235     char *doc_comment;
236     zend_uint doc_comment_len;
237 #endif
238 #endif
239 } ea_op_array;
240
241 typedef struct _eaccelerator_class_entry {
242         char type;
243         char *name;
244         zend_uint name_length;
245         char *parent;
246         HashTable function_table;
247         HashTable default_properties;
248 #ifdef ZEND_ENGINE_2
249         HashTable properties_info;
250 #  ifdef ZEND_ENGINE_2_1
251         HashTable default_static_members;
252 #  endif
253         HashTable *static_members;
254         HashTable constants_table;
255         zend_uint ce_flags;
256         zend_uint num_interfaces;
257
258         char *filename;
259         zend_uint line_start;
260         zend_uint line_end;
261 #  ifdef INCLUDE_DOC_COMMENTS
262     char *doc_comment;
263     zend_uint doc_comment_len;
264 #  endif
265 #endif
266 } ea_class_entry;
267
268 /*
269  * To cache functions and classes.
270  */
271 typedef struct _ea_fc_entry {
272         void *fc;
273         struct _ea_fc_entry *next;
274         int htablen;
275         char htabkey[1];                        /* must be last element */
276 } ea_fc_entry;
277
278
279 /*
280  * A mm_cache_entry is a bucket for one PHP script file.
281  * Nested  functions and classes which defined in the file goes
282  * into the list of mm_fc_entry.
283  */
284 typedef struct _ea_cache_entry {
285         struct _ea_cache_entry *next;
286 #ifdef EACCELERATOR_USE_INODE
287         dev_t st_dev;                           /* file's device                     */
288         ino_t st_ino;                           /* file's inode                      */
289 #else
290         unsigned int hv;                        /* hash value                        */
291 #endif
292         off_t filesize;                         /* file size */
293         time_t mtime;                           /* file last modification time       */
294         time_t ttl;                                     /* expiration time                   */
295         int size;                                       /* entry size (bytes)                */
296         int nhits;                                      /* hits count                        */
297         int nreloads;                           /* count of reloads                  */
298         int use_cnt;                            /* how many processes uses the entry */
299         ea_op_array *op_array;  /* script's global scope code        */
300         ea_fc_entry *f_head;            /* list of nested functions          */
301         ea_fc_entry *c_head;            /* list of nested classes            */
302         zend_bool removed;                      /* the entry is scheduled to remove  */
303         char realfilename[1];           /* real file name (must be last el.) */
304 } ea_cache_entry;
305
306 /*
307  * bucket for user's cache
308  */
309 typedef struct _ea_user_cache_entry {
310         struct _ea_user_cache_entry *next;
311         unsigned int hv;                        /* hash value                  */
312         long ttl;                                       /* expiration time             */
313         long create;
314         int size;
315         zval value;                                     /* value                       */
316         char key[1];                            /* key value (must be last el) */
317 } ea_user_cache_entry;
318
319 /*
320  * Linked list of mm_cache_entry which are used by process/thread
321  */
322 typedef struct _ea_used_entry {
323         struct _ea_used_entry *next;
324         ea_cache_entry *entry;
325 } ea_used_entry;
326
327 /*
328  * Linked list of locks
329  */
330 typedef struct _ea_lock_entry {
331         struct _ea_lock_entry *next;
332         pid_t pid;
333 #ifdef ZTS
334         THREAD_T thread;
335 #endif
336         char key[1];
337 } ea_lock_entry;
338
339 typedef struct _ea_file_header {
340         char magic[8];                          /* "EACCELERATOR" */
341         int eaccelerator_version[2];
342         int zend_version[2];
343         int php_version[2];
344         int size;
345         time_t mtime;
346         unsigned int crc32;
347 } ea_file_header;
348
349 int check_header(ea_file_header *hdr);
350 void init_header(ea_file_header *hdr);
351
352 typedef struct {
353         MM *mm;
354         pid_t owner;
355         size_t total;
356         unsigned int hash_cnt;
357         unsigned int user_hash_cnt;
358         zend_bool enabled;
359         zend_bool optimizer_enabled;
360         unsigned int rem_cnt;
361         time_t last_prune;
362         ea_cache_entry *removed;
363         ea_lock_entry *locks;
364
365         ea_cache_entry *hash[EA_HASH_SIZE];
366         ea_user_cache_entry *user_hash[EA_USER_HASH_SIZE];
367 } eaccelerator_mm;
368
369 /*
370  * Where to cache
371  */
372 typedef enum _ea_cache_place {
373         ea_shm_and_disk,        /* in shm and in disk */
374         ea_shm,                         /* in shm, but if it is not possible then on disk */
375         ea_shm_only,            /* in shm only  */
376         ea_disk_only,           /* on disk only */
377         ea_none                         /* don't cache  */
378 } ea_cache_place;
379
380 typedef union align_union {
381   double d;
382   void *v;
383   int (*func)(int);
384   long l;
385 } align_union;
386
387 #ifdef ZEND_ENGINE_2_2
388 typedef union _align_test {
389   void *ptr;
390   double dbl;
391   long lng;
392 } align_test;
393 #endif
394
395 /******************************************************************************/
396
397 #ifdef ZTS
398 #  ifdef __APPLE__
399 /* Workaround to prevent 'multiple definitions of symbol' during build on OSX */
400 static MUTEX_T ea_mutex;
401 #  else
402 MUTEX_T ea_mutex;
403 #  endif
404 #endif
405
406 /* needed to compile eA as a static php module */
407 extern zend_module_entry eaccelerator_module_entry;
408 #define phpext_eaccelerator_ptr &eaccelerator_module_entry
409
410
411 void format_size (char *s, unsigned int size, int legend);
412 void eaccelerator_prune (time_t t);
413
414 int eaccelerator_lock (const char *key, int key_len TSRMLS_DC);
415 int eaccelerator_unlock (const char *key, int key_len TSRMLS_DC);
416
417 void *eaccelerator_malloc2 (size_t size TSRMLS_DC);
418
419 unsigned int eaccelerator_crc32 (const char *p, size_t n);
420 int eaccelerator_md5 (char *s, const char *prefix, const char *key TSRMLS_DC);
421
422 #  ifdef WITH_EACCELERATOR_OPTIMIZER
423 void eaccelerator_optimize (zend_op_array * op_array);
424 #  endif
425
426 #ifdef ZTS
427 #  define EAG(v) TSRMG(eaccelerator_globals_id, zend_eaccelerator_globals*, v)
428 #else
429 #  define EAG(v) (eaccelerator_globals.v)
430 #endif
431
432 struct ea_pattern_t {
433   struct ea_pattern_t *next;
434   char *pattern;
435 };
436
437 /*
438  * Globals (different for each process/thread)
439  */
440 ZEND_BEGIN_MODULE_GLOBALS (eaccelerator)
441 void *used_entries;                     /* list of files which are used     */
442                                         /* by process/thread                */
443 zend_bool enabled;
444 zend_bool optimizer_enabled;
445 zend_bool compression_enabled;
446 zend_bool compiler;
447 zend_bool compress;
448 zend_bool compress_content;
449 zend_bool in_request;
450 zend_llist *content_headers;
451 long compress_level;
452 char *cache_dir;
453 char *eaccelerator_log_file;
454 char *name_space;
455 char *mem;
456 char *allowed_admin_path;
457 time_t req_start;                       /* time of request start (set in RINIT) */
458 HashTable strings;
459 HashTable restored;
460 zend_class_entry *class_entry;
461 zend_uint refcount_helper;
462 #if defined(WITH_EACCELERATOR_CONTENT_CACHING) || defined(WITH_EACCELERATOR_SESSIONS) || defined(WITH_EACCELERATOR_SHM)
463 char hostname[32];
464 #endif
465 struct ea_pattern_t *pattern_list;
466 #ifdef WITH_EACCELERATOR_CRASH_DETECTION
467 #ifdef SIGSEGV
468 void (*original_sigsegv_handler) (int);
469 #endif
470 #ifdef SIGFPE
471 void (*original_sigfpe_handler) (int);
472 #endif
473 #ifdef SIGBUS
474 void (*original_sigbus_handler) (int);
475 #endif
476 #ifdef SIGILL
477 void (*original_sigill_handler) (int);
478 #endif
479 #ifdef SIGABRT
480 void (*original_sigabrt_handler) (int);
481 #endif
482 #endif
483 #ifdef DEBUG
484 int xpad;
485 int profile_level;
486 long self_time[256];
487 #endif
488 #ifdef WITH_EACCELERATOR_SESSIONS
489 char *session;
490 #endif
491 ZEND_END_MODULE_GLOBALS (eaccelerator)
492
493 ZEND_EXTERN_MODULE_GLOBALS (eaccelerator)
494
495 #define EACCELERATOR_EXTENSION_NAME "eAccelerator"
496
497 #define EA_MAGIC "EACCELERATOR"
498
499 #define EACCELERATOR_VERSION_GUID   "PHPE8EDA1B6-806A-4851-B1C8-A6B4712F44FB"
500 #define EACCELERATOR_LOGO_GUID      "PHPE6F78DE9-13E4-4dee-8518-5FA2DACEA803"
501 #define EACCELERATOR_VERSION_STRING ("eAccelerator " EACCELERATOR_VERSION " (PHP " PHP_VERSION ")")
502
503 #endif          /* HAVE_EACCELERATOR */
504 #endif          /* #ifndef INCLUDED_EACCELERATOR_H */
Note: See TracBrowser for help on using the browser.