d11859e2e16d25b1cfecb5313c9451b0a73d9068
[openwrt/svn-archive/archive.git] / lang / php5 / patches / 005-APC.patch
1 diff -Naur php-5.3.1.orig/ext/apc/apc_bin.c php-5.3.1/ext/apc/apc_bin.c
2 --- php-5.3.1.orig/ext/apc/apc_bin.c 1970-01-01 01:00:00.000000000 +0100
3 +++ php-5.3.1/ext/apc/apc_bin.c 1970-01-01 10:13:08.000000000 +0100
4 @@ -0,0 +1,946 @@
5 +/*
6 + +----------------------------------------------------------------------+
7 + | APC |
8 + +----------------------------------------------------------------------+
9 + | Copyright (c) 2009 The PHP Group |
10 + +----------------------------------------------------------------------+
11 + | This source file is subject to version 3.01 of the PHP license, |
12 + | that is bundled with this package in the file LICENSE, and is |
13 + | available through the world-wide-web at the following url: |
14 + | http://www.php.net/license/3_01.txt. |
15 + | If you did not receive a copy of the PHP license and are unable to |
16 + | obtain it through the world-wide-web, please send a note to |
17 + | license@php.net so we can mail you a copy immediately. |
18 + +----------------------------------------------------------------------+
19 + | Authors: Brian Shire <shire@php.net> |
20 + +----------------------------------------------------------------------+
21 +
22 + */
23 +
24 +/* $Id: apc_bin.c 284580 2009-07-22 06:05:31Z kalle $ */
25 +
26 +/* Creates a binary architecture specific output to a string or file containing
27 + * the current cache contents for both fies and user variables. This is accomplished
28 + * via the apc_copy_* functions and "swizzling" pointer values to a position
29 + * independent value, and unswizzling them on restoration.
30 + */
31 +
32 +#include "apc_globals.h"
33 +#include "apc_bin.h"
34 +#include "apc_zend.h"
35 +#include "apc_sma.h"
36 +#include "apc_pool.h"
37 +#include "ext/standard/md5.h"
38 +#include "ext/standard/crc32.h"
39 +
40 +extern apc_cache_t* apc_cache;
41 +extern apc_cache_t* apc_user_cache;
42 +
43 +extern int _apc_store(char *strkey, int strkey_len, const zval *val, const uint ttl, const int exclusive TSRMLS_DC); /* this is hacky */
44 +
45 +#define APC_BINDUMP_DEBUG 0
46 +
47 +
48 +#if APC_BINDUMP_DEBUG
49 +
50 +#define SWIZZLE(bd, ptr) \
51 + do { \
52 + if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \
53 + printf("SWIZZLE: %x ~> ", ptr); \
54 + ptr = (void*)((long)(ptr) - (long)(bd)); \
55 + printf("%x in %s on line %d", ptr, __FILE__, __LINE__); \
56 + } else if((long)ptr > bd->size) { /* not swizzled */ \
57 + apc_eprint("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d", (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \
58 + } \
59 + printf("\n"); \
60 + } while(0);
61 +
62 +#define UNSWIZZLE(bd, ptr) \
63 + do { \
64 + printf("UNSWIZZLE: %x -> ", ptr); \
65 + ptr = (void*)((long)(ptr) + (long)(bd)); \
66 + printf("%x in %s on line %d \n", ptr, __FILE__, __LINE__); \
67 + } while(0);
68 +
69 +#else /* !APC_BINDUMP_DEBUG */
70 +
71 +#define SWIZZLE(bd, ptr) \
72 + do { \
73 + if((long)bd < (long)ptr && (ulong)ptr < ((long)bd + bd->size)) { \
74 + ptr = (void*)((long)(ptr) - (long)(bd)); \
75 + } else if((ulong)ptr > bd->size) { /* not swizzled */ \
76 + apc_eprint("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d", (long)bd, ptr, ((long)bd + bd->size), __FILE__, __LINE__); \
77 + } \
78 + } while(0);
79 +
80 +#define UNSWIZZLE(bd, ptr) \
81 + do { \
82 + ptr = (void*)((long)(ptr) + (long)(bd)); \
83 + } while(0);
84 +
85 +#endif
86 +
87 +
88 +static void *apc_bd_alloc(size_t size);
89 +static void apc_bd_free(void *ptr);
90 +static void *apc_bd_alloc_ex(void *ptr_new, size_t size);
91 +
92 +typedef void (*apc_swizzle_cb_t)(apc_bd_t *bd, zend_llist *ll, void *ptr TSRMLS_DC);
93 +
94 +#if APC_BINDUMP_DEBUG
95 +#define apc_swizzle_ptr(bd, ll, ptr) _apc_swizzle_ptr(bd, ll, (void*)ptr, __FILE__, __LINE__ TSRMLS_CC)
96 +#else
97 +#define apc_swizzle_ptr(bd, ll, ptr) _apc_swizzle_ptr(bd, ll, (void*)ptr, NULL, 0 TSRMLS_CC)
98 +#endif
99 +
100 +static void _apc_swizzle_ptr(apc_bd_t *bd, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC);
101 +static void apc_swizzle_function(apc_bd_t *bd, zend_llist *ll, zend_function *func TSRMLS_DC);
102 +static void apc_swizzle_class_entry(apc_bd_t *bd, zend_llist *ll, zend_class_entry *ce TSRMLS_DC);
103 +static void apc_swizzle_hashtable(apc_bd_t *bd, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC);
104 +static void apc_swizzle_zval(apc_bd_t *bd, zend_llist *ll, zval *zv TSRMLS_DC);
105 +static void apc_swizzle_op_array(apc_bd_t *bd, zend_llist *ll, zend_op_array *op_array TSRMLS_DC);
106 +static void apc_swizzle_property_info(apc_bd_t *bd, zend_llist *ll, zend_property_info *pi TSRMLS_DC);
107 +static void apc_swizzle_function_entry(apc_bd_t *bd, zend_llist *ll, const zend_function_entry *fe TSRMLS_DC);
108 +static void apc_swizzle_arg_info_array(apc_bd_t *bd, zend_llist *ll, const zend_arg_info* arg_info_array, uint num_args TSRMLS_DC);
109 +
110 +static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC);
111 +static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC);
112 +
113 +
114 +/* {{{ apc_bd_alloc
115 + * callback for copy_* functions */
116 +static void *apc_bd_alloc(size_t size) {
117 + return apc_bd_alloc_ex(NULL, size);
118 +} /* }}} */
119 +
120 +
121 +/* {{{ apc_bd_free
122 + * callback for copy_* functions */
123 +static void apc_bd_free(void *ptr) {
124 + size_t *size;
125 + TSRMLS_FETCH();
126 + if(zend_hash_index_find(&APCG(apc_bd_alloc_list), (ulong)ptr, (void**)&size) == FAILURE) {
127 + apc_eprint("apc_bd_free could not free pointer (not found in list: %x)", ptr);
128 + }
129 + APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) - *size);
130 + zend_hash_index_del(&APCG(apc_bd_alloc_list), (ulong)ptr);
131 +} /* }}} */
132 +
133 +
134 +/* {{{ apc_bd_alloc_ex
135 + * set ranges or allocate a block of data from an already (e)malloc'd range.
136 + * if ptr_new is not NULL, it will reset the pointer to start at ptr_new,
137 + * with a range of size. If ptr_new is NULL, returns the next available
138 + * block of given size.
139 + */
140 +static void *apc_bd_alloc_ex(void *ptr_new, size_t size) {
141 + void *rval;
142 + TSRMLS_FETCH();
143 +
144 + rval = APCG(apc_bd_alloc_ptr);
145 + if(ptr_new != NULL) { /* reset ptrs */
146 + APCG(apc_bd_alloc_ptr) = ptr_new;
147 + APCG(apc_bd_alloc_ubptr) = (void*)((unsigned char *) ptr_new + size);
148 + } else { /* alloc block */
149 + APCG(apc_bd_alloc_ptr) = (void*)((size_t)APCG(apc_bd_alloc_ptr) + size);
150 +#if APC_BINDUMP_DEBUG
151 + apc_nprint("apc_bd_alloc: rval: 0x%x ptr: 0x%x ubptr: 0x%x size: %d", rval, APCG(apc_bd_alloc_ptr), APCG(apc_bd_alloc_ubptr), size);
152 +#endif
153 + if(APCG(apc_bd_alloc_ptr) > APCG(apc_bd_alloc_ubptr)) {
154 + apc_eprint("Exceeded bounds check in apc_bd_alloc_ex by %d bytes.", (unsigned char *) APCG(apc_bd_alloc_ptr) - (unsigned char *) APCG(apc_bd_alloc_ubptr));
155 + }
156 + zend_hash_index_update(&APCG(apc_bd_alloc_list), (ulong)rval, &size, sizeof(size_t), NULL);
157 + }
158 +
159 + return rval;
160 +} /* }}} */
161 +
162 +
163 +/* {{{ _apc_swizzle_ptr */
164 +static void _apc_swizzle_ptr(apc_bd_t *bd, zend_llist *ll, void **ptr, const char* file, int line TSRMLS_DC) {
165 + if(*ptr) {
166 + if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) {
167 + zend_llist_add_element(ll, &ptr);
168 +#if APC_BINDUMP_DEBUG
169 + printf("[%06d] apc_swizzle_ptr: %x -> %x ", zend_llist_count(ll), ptr, *ptr);
170 + printf(" in %s on line %d \n", file, line);
171 +#endif
172 + } else if((ulong)ptr > bd->size) {
173 + apc_eprint("pointer to be swizzled is not within allowed memory range! (%x < %x < %x) in %s on %d", (long)bd, *ptr, ((long)bd + bd->size), file, line); \
174 + }
175 + }
176 +} /* }}} */
177 +
178 +
179 +/* {{{ apc_swizzle_op_array */
180 +static void apc_swizzle_op_array(apc_bd_t *bd, zend_llist *ll, zend_op_array *op_array TSRMLS_DC) {
181 + uint i;
182 +
183 +#ifdef ZEND_ENGINE_2
184 + apc_swizzle_arg_info_array(bd, ll, op_array->arg_info, op_array->num_args TSRMLS_CC);
185 + apc_swizzle_ptr(bd, ll, &op_array->arg_info);
186 +#else
187 + if (op_array->arg_types) {
188 + apc_swizzle_ptr(bd, ll, &op_array->arg_types);
189 + }
190 +#endif
191 +
192 + apc_swizzle_ptr(bd, ll, &op_array->function_name);
193 + apc_swizzle_ptr(bd, ll, &op_array->filename);
194 + apc_swizzle_ptr(bd, ll, &op_array->refcount);
195 +
196 + /* swizzle op_array */
197 + for(i=0; i < op_array->last; i++) {
198 + if(op_array->opcodes[i].result.op_type == IS_CONST) {
199 + apc_swizzle_zval(bd, ll, &op_array->opcodes[i].result.u.constant TSRMLS_CC);
200 + }
201 + if(op_array->opcodes[i].op1.op_type == IS_CONST) {
202 + apc_swizzle_zval(bd, ll, &op_array->opcodes[i].op1.u.constant TSRMLS_CC);
203 + }
204 + if(op_array->opcodes[i].op2.op_type == IS_CONST) {
205 + apc_swizzle_zval(bd, ll, &op_array->opcodes[i].op2.u.constant TSRMLS_CC);
206 + }
207 + switch (op_array->opcodes[i].opcode) {
208 + case ZEND_JMP:
209 + apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op1.u.jmp_addr);
210 + case ZEND_JMPZ:
211 + case ZEND_JMPNZ:
212 + case ZEND_JMPZ_EX:
213 + case ZEND_JMPNZ_EX:
214 + apc_swizzle_ptr(bd, ll, &op_array->opcodes[i].op2.u.jmp_addr);
215 + }
216 + }
217 + apc_swizzle_ptr(bd, ll, &op_array->opcodes);
218 +
219 + /* break-continue array ptr */
220 + if(op_array->brk_cont_array) {
221 + apc_swizzle_ptr(bd, ll, &op_array->brk_cont_array);
222 + }
223 +
224 + /* static voriables */
225 + if(op_array->static_variables) {
226 + apc_swizzle_hashtable(bd, ll, op_array->static_variables, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
227 + apc_swizzle_ptr(bd, ll, &op_array->static_variables);
228 + }
229 +
230 +#ifdef ZEND_ENGINE_2
231 + /* try-catch */
232 + if(op_array->try_catch_array) {
233 + apc_swizzle_ptr(bd, ll, &op_array->try_catch_array);
234 + }
235 +#endif
236 +
237 +#ifdef ZEND_ENGINE_2_1 /* PHP 5.1 */
238 + /* vars */
239 + if(op_array->vars) {
240 + for(i=0; (signed int) i < op_array->last_var; i++) {
241 + apc_swizzle_ptr(bd, ll, &op_array->vars[i].name);
242 + }
243 + apc_swizzle_ptr(bd, ll, &op_array->vars);
244 + }
245 +#endif
246 +
247 +#ifdef ZEND_ENGINE_2
248 + /* doc comment */
249 + if(op_array->doc_comment) {
250 + apc_swizzle_ptr(bd, ll, &op_array->doc_comment);
251 + }
252 +#endif
253 +
254 +} /* }}} */
255 +
256 +
257 +/* {{{ apc_swizzle_function */
258 +static void apc_swizzle_function(apc_bd_t *bd, zend_llist *ll, zend_function *func TSRMLS_DC) {
259 + apc_swizzle_op_array(bd, ll, &func->op_array TSRMLS_CC);
260 +#ifdef ZEND_ENGINE_2
261 + if(func->common.scope) {
262 + apc_swizzle_ptr(bd, ll, &func->common.scope);
263 + }
264 +#endif
265 +} /* }}} */
266 +
267 +
268 +/* {{{ apc_swizzle_class_entry */
269 +static void apc_swizzle_class_entry(apc_bd_t *bd, zend_llist *ll, zend_class_entry *ce TSRMLS_DC) {
270 +
271 + uint i;
272 +
273 + if(ce->name) {
274 + apc_swizzle_ptr(bd, ll, &ce->name);
275 + }
276 +
277 + if(ce->doc_comment) {
278 + apc_swizzle_ptr(bd, ll, &ce->doc_comment);
279 + }
280 +
281 +#ifndef ZEND_ENGINE_2
282 + apc_swizzle_ptr(bd, ll, &ce->refcount);
283 +#endif
284 +
285 + apc_swizzle_hashtable(bd, ll, &ce->function_table, (apc_swizzle_cb_t)apc_swizzle_function, 0 TSRMLS_CC);
286 + apc_swizzle_hashtable(bd, ll, &ce->default_properties, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
287 +
288 +#ifdef ZEND_ENGINE_2
289 + apc_swizzle_hashtable(bd, ll, &ce->properties_info, (apc_swizzle_cb_t)apc_swizzle_property_info, 0 TSRMLS_CC);
290 +#endif
291 +
292 + apc_swizzle_hashtable(bd, ll, &ce->default_static_members, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
293 +
294 + if(ce->static_members != &ce->default_static_members) {
295 + apc_swizzle_hashtable(bd, ll, ce->static_members, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
296 + } else {
297 + apc_swizzle_ptr(bd, ll, &ce->static_members);
298 + }
299 +
300 + apc_swizzle_hashtable(bd, ll, &ce->constants_table, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
301 +
302 + if(ce->builtin_functions) {
303 + for(i=0; ce->builtin_functions[i].fname; i++) {
304 + apc_swizzle_function_entry(bd, ll, &ce->builtin_functions[i] TSRMLS_CC);
305 + }
306 + }
307 +
308 + apc_swizzle_ptr(bd, ll, &ce->constructor);
309 + apc_swizzle_ptr(bd, ll, &ce->destructor);
310 + apc_swizzle_ptr(bd, ll, &ce->clone);
311 + apc_swizzle_ptr(bd, ll, &ce->__get);
312 + apc_swizzle_ptr(bd, ll, &ce->__set);
313 + apc_swizzle_ptr(bd, ll, &ce->__unset);
314 + apc_swizzle_ptr(bd, ll, &ce->__isset);
315 + apc_swizzle_ptr(bd, ll, &ce->__call);
316 + apc_swizzle_ptr(bd, ll, &ce->serialize_func);
317 + apc_swizzle_ptr(bd, ll, &ce->unserialize_func);
318 +
319 +#ifdef ZEND_ENGINE_2_2
320 + apc_swizzle_ptr(bd, ll, &ce->__tostring);
321 +#endif
322 +
323 + apc_swizzle_ptr(bd, ll, &ce->filename);
324 +} /* }}} */
325 +
326 +
327 +/* {{{ apc_swizzle_property_info */
328 +static void apc_swizzle_property_info(apc_bd_t *bd, zend_llist *ll, zend_property_info *pi TSRMLS_DC) {
329 + apc_swizzle_ptr(bd, ll, &pi->name);
330 + apc_swizzle_ptr(bd, ll, &pi->doc_comment);
331 +
332 +#ifdef ZEND_ENGINE_2_2
333 + apc_swizzle_ptr(bd, ll, &pi->ce);
334 +#endif
335 +} /* }}} */
336 +
337 +
338 +/* {{{ apc_swizzle_function_entry */
339 +static void apc_swizzle_function_entry(apc_bd_t *bd, zend_llist *ll, const zend_function_entry *fe TSRMLS_DC) {
340 + apc_swizzle_ptr(bd, ll, &fe->fname);
341 + apc_swizzle_arg_info_array(bd, ll, fe->arg_info, fe->num_args TSRMLS_CC);
342 + apc_swizzle_ptr(bd, ll, &fe->arg_info);
343 +} /* }}} */
344 +
345 +
346 +/* {{{ apc_swizzle_arg_info_array */
347 +static void apc_swizzle_arg_info_array(apc_bd_t *bd, zend_llist *ll, const zend_arg_info* arg_info_array, uint num_args TSRMLS_DC) {
348 + if(arg_info_array) {
349 + uint i;
350 +
351 + for(i=0; i < num_args; i++) {
352 + apc_swizzle_ptr(bd, ll, &arg_info_array[i].name);
353 + apc_swizzle_ptr(bd, ll, &arg_info_array[i].class_name);
354 + }
355 + }
356 +
357 +} /* }}} */
358 +
359 +
360 +/* {{{ apc_swizzle_hashtable */
361 +static void apc_swizzle_hashtable(apc_bd_t *bd, zend_llist *ll, HashTable *ht, apc_swizzle_cb_t swizzle_cb, int is_ptr TSRMLS_DC) {
362 + uint i;
363 + Bucket **bp, **bp_prev;
364 +
365 + bp = &ht->pListHead;
366 + while(*bp) {
367 + bp_prev = bp;
368 + bp = &(*bp)->pListNext;
369 + if(is_ptr) {
370 + swizzle_cb(bd, ll, *(void**)(*bp_prev)->pData TSRMLS_CC);
371 + apc_swizzle_ptr(bd, ll, (*bp_prev)->pData);
372 + } else {
373 + swizzle_cb(bd, ll, (void**)(*bp_prev)->pData TSRMLS_CC);
374 + }
375 + apc_swizzle_ptr(bd, ll, &(*bp_prev)->pData);
376 + if((*bp_prev)->pDataPtr) {
377 + apc_swizzle_ptr(bd, ll, &(*bp_prev)->pDataPtr);
378 + }
379 + if((*bp_prev)->pListLast) {
380 + apc_swizzle_ptr(bd, ll, &(*bp_prev)->pListLast);
381 + }
382 + if((*bp_prev)->pNext) {
383 + apc_swizzle_ptr(bd, ll, &(*bp_prev)->pNext);
384 + }
385 + if((*bp_prev)->pLast) {
386 + apc_swizzle_ptr(bd, ll, &(*bp_prev)->pLast);
387 + }
388 + apc_swizzle_ptr(bd, ll, bp_prev);
389 + }
390 + for(i=0; i < ht->nTableSize; i++) {
391 + if(ht->arBuckets[i]) {
392 + apc_swizzle_ptr(bd, ll, &ht->arBuckets[i]);
393 + }
394 + }
395 + apc_swizzle_ptr(bd, ll, &ht->pListTail);
396 +
397 + apc_swizzle_ptr(bd, ll, &ht->arBuckets);
398 +} /* }}} */
399 +
400 +
401 +/* {{{ apc_swizzle_zval */
402 +static void apc_swizzle_zval(apc_bd_t *bd, zend_llist *ll, zval *zv TSRMLS_DC) {
403 +
404 + if(APCG(copied_zvals).nTableSize) {
405 + if(zend_hash_index_exists(&APCG(copied_zvals), (ulong)zv)) {
406 + return;
407 + }
408 + zend_hash_index_update(&APCG(copied_zvals), (ulong)zv, (void**)&zv, sizeof(zval*), NULL);
409 + }
410 +
411 + switch(zv->type & ~IS_CONSTANT_INDEX) {
412 + case IS_NULL:
413 + case IS_LONG:
414 + case IS_DOUBLE:
415 + case IS_BOOL:
416 + case IS_RESOURCE:
417 + /* nothing to do */
418 + break;
419 + case IS_CONSTANT:
420 + case IS_STRING:
421 + apc_swizzle_ptr(bd, ll, &zv->value.str.val);
422 + break;
423 + case IS_ARRAY:
424 + case IS_CONSTANT_ARRAY:
425 + apc_swizzle_hashtable(bd, ll, zv->value.ht, (apc_swizzle_cb_t)apc_swizzle_zval, 1 TSRMLS_CC);
426 + apc_swizzle_ptr(bd, ll, &zv->value.ht);
427 + break;
428 + case IS_OBJECT:
429 + break;
430 + default:
431 + assert(0); /* shouldn't happen */
432 + }
433 +} /* }}} */
434 +
435 +
436 +/* {{{ apc_swizzle_bd */
437 +static apc_bd_t* apc_swizzle_bd(apc_bd_t* bd, zend_llist *ll TSRMLS_DC) {
438 + int count, i;
439 + PHP_MD5_CTX context;
440 + unsigned char digest[16];
441 + register php_uint32 crc;
442 + php_uint32 crcinit = 0;
443 + char *crc_p;
444 + void ***ptr;
445 + void ***ptr_list;
446 +
447 + count = zend_llist_count(ll);
448 + ptr_list = emalloc(count * sizeof(void**));
449 + ptr = zend_llist_get_first(ll);
450 + for(i=0; i < count; i++) {
451 +#if APC_BINDUMP_DEBUG
452 + printf("[%06d] ", i+1);
453 +#endif
454 + SWIZZLE(bd, **ptr); /* swizzle ptr */
455 + if((long)bd < (long)*ptr && (ulong)*ptr < ((long)bd + bd->size)) { /* exclude ptrs that aren't actually included in the ptr list */
456 +#if APC_BINDUMP_DEBUG
457 + printf("[------] ");
458 +#endif
459 + SWIZZLE(bd, *ptr); /* swizzle ptr list */
460 + ptr_list[i] = *ptr;
461 + }
462 + ptr = zend_llist_get_next(ll);
463 + }
464 + SWIZZLE(bd, bd->entries);
465 +
466 + if(count > 0) {
467 + bd = erealloc(bd, bd->size + (count * sizeof(void**)));
468 + bd->num_swizzled_ptrs = count;
469 + bd->swizzled_ptrs = (void***)((unsigned char *)bd + bd->size -2); /* extra -1 for null termination */
470 + bd->size += count * sizeof(void**);
471 + memcpy(bd->swizzled_ptrs, ptr_list, count * sizeof(void**));
472 + SWIZZLE(bd, bd->swizzled_ptrs);
473 + } else {
474 + bd->num_swizzled_ptrs = 0;
475 + bd->swizzled_ptrs = NULL;
476 + }
477 + ((char*)bd)[bd->size-1] = 0; /* silence null termination for zval strings */
478 + efree(ptr_list);
479 + bd->swizzled = 1;
480 +
481 + /* Generate MD5/CRC32 checksum */
482 + for(i=0; i<16; i++) { bd->md5[i] = 0; }
483 + bd->crc=0;
484 + PHP_MD5Init(&context);
485 + PHP_MD5Update(&context, (const unsigned char*)bd, bd->size);
486 + PHP_MD5Final(digest, &context);
487 + crc = crcinit^0xFFFFFFFF;
488 + crc_p = (char*)bd;
489 + for(i=bd->size; i--; ++crc_p) {
490 + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*crc_p)) & 0xFF ];
491 + }
492 + memcpy(bd->md5, digest, 16);
493 + bd->crc = crc;
494 +
495 + return bd;
496 +} /* }}} */
497 +
498 +
499 +/* {{{ apc_unswizzle_bd */
500 +static int apc_unswizzle_bd(apc_bd_t *bd, int flags TSRMLS_DC) {
501 + int i;
502 + unsigned char md5_orig[16];
503 + unsigned char digest[16];
504 + PHP_MD5_CTX context;
505 + register php_uint32 crc;
506 + php_uint32 crcinit = 0;
507 + php_uint32 crc_orig;
508 + char *crc_p;
509 +
510 + /* Verify the md5 or crc32 before we unswizzle */
511 + memcpy(md5_orig, bd->md5, 16);
512 + for(i=0; i<16; i++) { bd->md5[i] = 0; }
513 + crc_orig = bd->crc;
514 + bd->crc=0;
515 + if(flags & APC_BIN_VERIFY_MD5) {
516 + PHP_MD5Init(&context);
517 + PHP_MD5Update(&context, (const unsigned char*)bd, bd->size);
518 + PHP_MD5Final(digest, &context);
519 + if(memcmp(md5_orig, digest, 16)) {
520 + apc_eprint("MD5 checksum of binary dump failed.");
521 + memcpy(bd->md5, md5_orig, 16); /* add back md5 checksum */
522 + return -1;
523 + }
524 + }
525 + if(flags & APC_BIN_VERIFY_CRC32) {
526 + crc = crcinit^0xFFFFFFFF;
527 + crc_p = (char*)bd;
528 + for(i=bd->size; i--; ++crc_p) {
529 + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*crc_p)) & 0xFF ];
530 + }
531 + if(crc_orig != crc) {
532 + apc_eprint("CRC32 checksum of binary dump failed.");
533 + bd->crc = crc_orig;
534 + return -1;
535 + }
536 + }
537 + memcpy(bd->md5, md5_orig, 16); /* add back md5 checksum */
538 + bd->crc = crc_orig;
539 +
540 + UNSWIZZLE(bd, bd->entries);
541 + UNSWIZZLE(bd, bd->swizzled_ptrs);
542 + for(i=0; i < bd->num_swizzled_ptrs; i++) {
543 + if(bd->swizzled_ptrs[i]) {
544 + UNSWIZZLE(bd, bd->swizzled_ptrs[i]);
545 + if(*bd->swizzled_ptrs[i] && (*bd->swizzled_ptrs[i] < (void*)bd)) {
546 + UNSWIZZLE(bd, *bd->swizzled_ptrs[i]);
547 + }
548 + }
549 + }
550 +
551 + bd->swizzled=0;
552 +
553 + return 0;
554 +} /* }}} */
555 +
556 +
557 +/* {{{ apc_bin_checkfilter */
558 +static int apc_bin_checkfilter(HashTable *filter, const char *key, uint key_len) {
559 + zval **zptr;
560 +
561 + if(filter == NULL) {
562 + return 1;
563 + }
564 +
565 + if(zend_hash_find(filter, (char*)key, key_len, (void**)&zptr) == SUCCESS) {
566 + if(Z_TYPE_PP(zptr) == IS_LONG && Z_LVAL_PP(zptr) == 0) {
567 + return 0;
568 + }
569 + } else {
570 + return 0;
571 + }
572 +
573 +
574 + return 1;
575 +} /* }}} */
576 +
577 +/* {{{ apc_bin_fixup_op_array */
578 +static inline void apc_bin_fixup_op_array(zend_op_array *op_array) {
579 + ulong i;
580 + for (i = 0; i < op_array->last; i++) {
581 + op_array->opcodes[i].handler = zend_opcode_handlers[APC_OPCODE_HANDLER_DECODE(&op_array->opcodes[i])];
582 + }
583 +}
584 +/* }}} */
585 +
586 +/* {{{ apc_bin_fixup_class_entry */
587 +static inline void apc_bin_fixup_class_entry(zend_class_entry *ce) {
588 + zend_function *fe;
589 + HashPosition hpos;
590 +
591 + /* fixup the opcodes in each method */
592 + zend_hash_internal_pointer_reset_ex(&ce->function_table, &hpos);
593 + while(zend_hash_get_current_data_ex(&ce->function_table, (void**)&fe, &hpos) == SUCCESS) {
594 + apc_bin_fixup_op_array(&fe->op_array);
595 + zend_hash_move_forward_ex(&ce->function_table, &hpos);
596 + }
597 +
598 + /* fixup hashtable destructor pointers */
599 + ce->function_table.pDestructor = (dtor_func_t)zend_function_dtor;
600 + ce->default_properties.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
601 + ce->properties_info.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
602 + ce->default_static_members.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
603 + if (ce->static_members) {
604 + ce->static_members->pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
605 + }
606 + ce->constants_table.pDestructor = (dtor_func_t)zval_ptr_dtor_wrapper;
607 +}
608 +/* }}} */
609 +
610 +/* {{{ apc_bin_dump */
611 +apc_bd_t* apc_bin_dump(HashTable *files, HashTable *user_vars TSRMLS_DC) {
612 +
613 + int i;
614 + uint fcount;
615 + slot_t *sp;
616 + apc_bd_entry_t *ep;
617 + int count=0;
618 + apc_bd_t *bd;
619 + zend_llist ll;
620 + zend_function *efp, *sfp;
621 + long size=0;
622 + apc_context_t ctxt;
623 + void *pool_ptr;
624 +
625 + zend_llist_init(&ll, sizeof(void*), NULL, 0);
626 + zend_hash_init(&APCG(apc_bd_alloc_list), 0, NULL, NULL, 0);
627 +
628 + /* flip the hash for faster filter checking */
629 + files = apc_flip_hash(files);
630 + user_vars = apc_flip_hash(user_vars);
631 +
632 + /* get size and entry counts */
633 + for(i=0; i < apc_user_cache->num_slots; i++) {
634 + sp = apc_user_cache->slots[i];
635 + for(; sp != NULL; sp = sp->next) {
636 + if(apc_bin_checkfilter(user_vars, sp->key.data.user.identifier, sp->key.data.user.identifier_len+1)) {
637 + size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t);
638 + size += sp->value->mem_size - (sizeof(apc_cache_entry_t) - sizeof(apc_cache_entry_value_t));
639 + count++;
640 + }
641 + }
642 + }
643 + for(i=0; i < apc_cache->num_slots; i++) {
644 + sp = apc_cache->slots[i];
645 + for(; sp != NULL; sp = sp->next) {
646 + if(sp->key.type == APC_CACHE_KEY_FPFILE) {
647 + if(apc_bin_checkfilter(files, sp->key.data.fpfile.fullpath, sp->key.data.fpfile.fullpath_len+1)) {
648 + size += sizeof(apc_bd_entry_t*) + sizeof(apc_bd_entry_t);
649 + size += sp->value->mem_size - (sizeof(apc_cache_entry_t) - sizeof(apc_cache_entry_value_t));
650 + count++;
651 + }
652 + } else {
653 + /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load */
654 + apc_wprint("Excluding some files from apc_bin_dump[file]. Cached files must be included using full path with apc.stat=0.");
655 + }
656 + }
657 + }
658 +
659 + size += sizeof(apc_bd_t) +1; /* +1 for null termination */
660 + bd = emalloc(size);
661 + bd->size = size;
662 + pool_ptr = emalloc(sizeof(apc_pool));
663 + apc_bd_alloc_ex(pool_ptr, sizeof(apc_pool));
664 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_bd_alloc, apc_bd_free, NULL, NULL); /* ideally the pool wouldn't be alloc'd as part of this */
665 + if (!ctxt.pool) { /* TODO need to cleanup */
666 + apc_wprint("Unable to allocate memory for pool.");
667 + return NULL;
668 + }
669 + ctxt.copy = APC_COPY_IN_USER; /* avoid stupid ALLOC_ZVAL calls here, hack */
670 + apc_bd_alloc_ex( (void*)((long)bd + sizeof(apc_bd_t)), bd->size - sizeof(apc_bd_t) -1);
671 + bd->num_entries = count;
672 + bd->entries = apc_bd_alloc_ex(NULL, sizeof(apc_bd_entry_t) * count);
673 +
674 + /* User entries */
675 + zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
676 + count = 0;
677 + for(i=0; i < apc_user_cache->num_slots; i++) {
678 + sp = apc_user_cache->slots[i];
679 + for(; sp != NULL; sp = sp->next) {
680 + if(apc_bin_checkfilter(user_vars, sp->key.data.user.identifier, sp->key.data.user.identifier_len+1)) {
681 + ep = &bd->entries[count];
682 + ep->type = sp->value->type;
683 + ep->val.user.info = apc_bd_alloc(sp->value->data.user.info_len+1);
684 + memcpy(ep->val.user.info, sp->value->data.user.info, sp->value->data.user.info_len+1);
685 + ep->val.user.info_len = sp->value->data.user.info_len;
686 + ep->val.user.val = apc_copy_zval(NULL, sp->value->data.user.val, &ctxt);
687 + ep->val.user.ttl = sp->value->data.user.ttl;
688 +
689 + /* swizzle pointers */
690 + apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.user.info);
691 + zend_hash_clean(&APCG(copied_zvals));
692 + apc_swizzle_zval(bd, &ll, bd->entries[count].val.user.val TSRMLS_CC);
693 + apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.user.val);
694 +
695 + count++;
696 + }
697 + }
698 + }
699 + zend_hash_destroy(&APCG(copied_zvals));
700 + APCG(copied_zvals).nTableSize=0;
701 +
702 + /* File entries */
703 + for(i=0; i < apc_cache->num_slots; i++) {
704 + for(sp=apc_cache->slots[i]; sp != NULL; sp = sp->next) {
705 + if(sp->key.type == APC_CACHE_KEY_FPFILE) {
706 + if(apc_bin_checkfilter(files, sp->key.data.fpfile.fullpath, sp->key.data.fpfile.fullpath_len+1)) {
707 + ep = &bd->entries[count];
708 + ep->type = sp->key.type;
709 + ep->val.file.filename = apc_bd_alloc(strlen(sp->value->data.file.filename)+1);
710 + strcpy(ep->val.file.filename, sp->value->data.file.filename);
711 + ep->val.file.op_array = apc_copy_op_array(NULL, sp->value->data.file.op_array, &ctxt TSRMLS_CC);
712 +
713 + for(ep->num_functions=0; sp->value->data.file.functions[ep->num_functions].function != NULL;) { ep->num_functions++; }
714 + ep->val.file.functions = apc_bd_alloc(sizeof(apc_function_t) * ep->num_functions);
715 + for(fcount=0; fcount < ep->num_functions; fcount++) {
716 + memcpy(&ep->val.file.functions[fcount], &sp->value->data.file.functions[fcount], sizeof(apc_function_t));
717 + ep->val.file.functions[fcount].name = apc_xmemcpy(sp->value->data.file.functions[fcount].name, sp->value->data.file.functions[fcount].name_len+1, apc_bd_alloc);
718 + ep->val.file.functions[fcount].name_len = sp->value->data.file.functions[fcount].name_len;
719 + ep->val.file.functions[fcount].function = apc_bd_alloc(sizeof(zend_function));
720 + efp = ep->val.file.functions[fcount].function;
721 + sfp = sp->value->data.file.functions[fcount].function;
722 + switch(sfp->type) {
723 + case ZEND_INTERNAL_FUNCTION:
724 + case ZEND_OVERLOADED_FUNCTION:
725 + efp->op_array = sfp->op_array;
726 + break;
727 + case ZEND_USER_FUNCTION:
728 + case ZEND_EVAL_CODE:
729 + apc_copy_op_array(&efp->op_array, &sfp->op_array, &ctxt TSRMLS_CC);
730 + break;
731 + default:
732 + assert(0);
733 + }
734 +#ifdef ZEND_ENGINE_2
735 + efp->common.prototype = NULL;
736 + efp->common.fn_flags = sfp->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
737 +#endif
738 + apc_swizzle_ptr(bd, &ll, &ep->val.file.functions[fcount].name);
739 + apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.functions[fcount].function);
740 + apc_swizzle_op_array(bd, &ll, &efp->op_array TSRMLS_CC);
741 + }
742 +
743 +
744 + for(ep->num_classes=0; sp->value->data.file.classes[ep->num_classes].class_entry != NULL;) { ep->num_classes++; }
745 + ep->val.file.classes = apc_bd_alloc(sizeof(apc_class_t) * ep->num_classes);
746 + for(fcount=0; fcount < ep->num_classes; fcount++) {
747 + ep->val.file.classes[fcount].name = apc_xmemcpy(sp->value->data.file.classes[fcount].name, sp->value->data.file.classes[fcount].name_len+1, apc_bd_alloc);
748 + ep->val.file.classes[fcount].name_len = sp->value->data.file.classes[fcount].name_len;
749 + ep->val.file.classes[fcount].class_entry = apc_copy_class_entry(NULL, sp->value->data.file.classes[fcount].class_entry, &ctxt);
750 + ep->val.file.classes[fcount].parent_name = apc_xstrdup(sp->value->data.file.classes[fcount].parent_name, apc_bd_alloc);
751 +
752 + apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].name);
753 + apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].parent_name);
754 + apc_swizzle_class_entry(bd, &ll, ep->val.file.classes[fcount].class_entry TSRMLS_CC);
755 + apc_swizzle_ptr(bd, &ll, &ep->val.file.classes[fcount].class_entry);
756 + }
757 +
758 + apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.file.filename);
759 + apc_swizzle_op_array(bd, &ll, bd->entries[count].val.file.op_array TSRMLS_CC);
760 + apc_swizzle_ptr(bd, &ll, &bd->entries[count].val.file.op_array);
761 + apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.functions);
762 + apc_swizzle_ptr(bd, &ll, (void**)&ep->val.file.classes);
763 +
764 + count++;
765 + } else {
766 + /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load */
767 + }
768 + }
769 + }
770 + }
771 +
772 + /* append swizzle pointer list to bd */
773 + bd = apc_swizzle_bd(bd, &ll TSRMLS_CC);
774 + zend_llist_destroy(&ll);
775 + zend_hash_destroy(&APCG(apc_bd_alloc_list));
776 +
777 + if(files) {
778 + zend_hash_destroy(files);
779 + efree(files);
780 + }
781 + if(user_vars) {
782 + zend_hash_destroy(user_vars);
783 + efree(user_vars);
784 + }
785 +
786 + efree(pool_ptr);
787 +
788 + return bd;
789 +} /* }}} */
790 +
791 +
792 +/* {{{ apc_bin_load */
793 +int apc_bin_load(apc_bd_t *bd, int flags TSRMLS_DC) {
794 +
795 + apc_bd_entry_t *ep;
796 + uint i, i2;
797 + int ret;
798 + time_t t;
799 + zend_op_array *alloc_op_array = NULL;
800 + apc_function_t *alloc_functions = NULL;
801 + apc_class_t *alloc_classes = NULL;
802 + apc_cache_entry_t *cache_entry;
803 + apc_cache_key_t cache_key;
804 + apc_context_t ctxt;
805 +
806 + if (bd->swizzled) {
807 + if(apc_unswizzle_bd(bd, flags TSRMLS_CC) < 0) {
808 + return -1;
809 + }
810 + }
811 +
812 + t = apc_time();
813 +
814 + for(i = 0; i < bd->num_entries; i++) {
815 + ctxt.pool = apc_pool_create(APC_SMALL_POOL, apc_sma_malloc, apc_sma_free, apc_sma_protect, apc_sma_unprotect);
816 + if (!ctxt.pool) { /* TODO need to cleanup previous pools */
817 + apc_wprint("Unable to allocate memory for pool.");
818 + goto failure;
819 + }
820 + ep = &bd->entries[i];
821 + switch (ep->type) {
822 + case APC_CACHE_KEY_FILE:
823 + /* TODO: Currently we don't support APC_CACHE_KEY_FILE type. We need to store the path and re-stat on load (or something else perhaps?) */
824 + break;
825 + case APC_CACHE_KEY_FPFILE:
826 + ctxt.copy = APC_COPY_IN_OPCODE;
827 +
828 + HANDLE_BLOCK_INTERRUPTIONS();
829 +#if NONBLOCKING_LOCK_AVAILABLE
830 + if(APCG(write_lock)) {
831 + if(!apc_cache_write_lock(apc_cache)) {
832 + HANDLE_UNBLOCK_INTERRUPTIONS();
833 + return -1;
834 + }
835 + }
836 +#endif
837 + if(! (alloc_op_array = apc_copy_op_array(NULL, ep->val.file.op_array, &ctxt TSRMLS_CC))) {
838 + goto failure;
839 + }
840 + apc_bin_fixup_op_array(alloc_op_array);
841 +
842 + if(! (alloc_functions = apc_sma_malloc(sizeof(apc_function_t) * (ep->num_functions + 1)))) {
843 + goto failure;
844 + }
845 + for(i2=0; i2 < ep->num_functions; i2++) {
846 + if(! (alloc_functions[i2].name = apc_xmemcpy(ep->val.file.functions[i2].name, ep->val.file.functions[i2].name_len+1, apc_sma_malloc))) {
847 + goto failure;
848 + }
849 + alloc_functions[i2].name_len = ep->val.file.functions[i2].name_len;
850 + if(! (alloc_functions[i2].function = apc_sma_malloc(sizeof(zend_function)))) {
851 + goto failure;
852 + }
853 + switch(ep->val.file.functions[i2].function->type) {
854 + case ZEND_INTERNAL_FUNCTION:
855 + case ZEND_OVERLOADED_FUNCTION:
856 + alloc_functions[i2].function->op_array = ep->val.file.functions[i2].function->op_array;
857 + break;
858 + case ZEND_USER_FUNCTION:
859 + case ZEND_EVAL_CODE:
860 + if (!apc_copy_op_array(&alloc_functions[i2].function->op_array, &ep->val.file.functions[i2].function->op_array, &ctxt TSRMLS_CC)) {
861 + goto failure;
862 + }
863 + apc_bin_fixup_op_array(&alloc_functions[i2].function->op_array);
864 + break;
865 + default:
866 + assert(0);
867 + }
868 +#ifdef ZEND_ENGINE_2
869 + alloc_functions[i2].function->common.prototype=NULL;
870 + alloc_functions[i2].function->common.fn_flags=ep->val.file.functions[i2].function->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
871 +#endif
872 + }
873 + alloc_functions[i2].name = NULL;
874 + alloc_functions[i2].function = NULL;
875 +
876 + if(! (alloc_classes = apc_sma_malloc(sizeof(apc_class_t) * (ep->num_classes + 1)))) {
877 + goto failure;
878 + }
879 + for(i2=0; i2 < ep->num_classes; i2++) {
880 + if(! (alloc_classes[i2].name = apc_xmemcpy(ep->val.file.classes[i2].name, ep->val.file.classes[i2].name_len+1, apc_sma_malloc))) {
881 + goto failure;
882 + }
883 + alloc_classes[i2].name_len = ep->val.file.classes[i2].name_len;
884 + if(! (alloc_classes[i2].class_entry = apc_copy_class_entry(NULL, ep->val.file.classes[i2].class_entry, &ctxt))) {
885 + goto failure;
886 + }
887 + apc_bin_fixup_class_entry(alloc_classes[i2].class_entry);
888 + if(! (alloc_classes[i2].parent_name = apc_xstrdup(ep->val.file.classes[i2].parent_name, apc_sma_malloc))) {
889 + if(ep->val.file.classes[i2].parent_name != NULL) {
890 + goto failure;
891 + }
892 + }
893 + }
894 + alloc_classes[i2].name = NULL;
895 + alloc_classes[i2].class_entry = NULL;
896 +
897 + if(!(cache_entry = apc_cache_make_file_entry(ep->val.file.filename, alloc_op_array, alloc_functions, alloc_classes, &ctxt))) {
898 + goto failure;
899 + }
900 +
901 + if (!apc_cache_make_file_key(&cache_key, ep->val.file.filename, PG(include_path), t TSRMLS_CC)) {
902 + goto failure;
903 + }
904 +
905 + if ((ret = apc_cache_insert(apc_cache, cache_key, cache_entry, &ctxt, t)) != 1) {
906 + if(ret==-1) {
907 + goto failure;
908 + }
909 + }
910 +
911 +#if NONBLOCKING_LOCK_AVAILABLE
912 + if(APCG(write_lock)) {
913 + apc_cache_write_unlock(apc_cache);
914 + }
915 +#endif
916 + HANDLE_UNBLOCK_INTERRUPTIONS();
917 +
918 + break;
919 + case APC_CACHE_KEY_USER:
920 + ctxt.copy = APC_COPY_IN_USER;
921 + _apc_store(ep->val.user.info, ep->val.user.info_len, ep->val.user.val, ep->val.user.ttl, 0 TSRMLS_CC);
922 + break;
923 + default:
924 + break;
925 + }
926 + }
927 +
928 + return 0;
929 +
930 +failure:
931 + apc_pool_destroy(ctxt.pool);
932 + apc_wprint("Unable to allocate memory for apc binary load/dump functionality.");
933 +#if NONBLOCKING_LOCK_AVAILABLE
934 + if(APCG(write_lock)) {
935 + apc_cache_write_unlock(apc_cache);
936 + }
937 +#endif
938 + HANDLE_UNBLOCK_INTERRUPTIONS();
939 + return -1;
940 +} /* }}} */
941 +
942 +
943 +/*
944 + * Local variables:
945 + * tab-width: 4
946 + * c-basic-offset: 4
947 + * End:
948 + * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
949 + * vim<600: expandtab sw=4 ts=4 sts=4
950 + */
951 diff -Naur php-5.3.1.orig/ext/apc/apc_bin.h php-5.3.1/ext/apc/apc_bin.h
952 --- php-5.3.1.orig/ext/apc/apc_bin.h 1970-01-01 01:00:00.000000000 +0100
953 +++ php-5.3.1/ext/apc/apc_bin.h 1970-01-01 10:13:08.000000000 +0100
954 @@ -0,0 +1,63 @@
955 +/*
956 + +----------------------------------------------------------------------+
957 + | APC |
958 + +----------------------------------------------------------------------+
959 + | Copyright (c) 2009 The PHP Group |
960 + +----------------------------------------------------------------------+
961 + | This source file is subject to version 3.01 of the PHP license, |
962 + | that is bundled with this package in the file LICENSE, and is |
963 + | available through the world-wide-web at the following url: |
964 + | http://www.php.net/license/3_01.txt |
965 + | If you did not receive a copy of the PHP license and are unable to |
966 + | obtain it through the world-wide-web, please send a note to |
967 + | license@php.net so we can mail you a copy immediately. |
968 + +----------------------------------------------------------------------+
969 + | Authors: Brian Shire <shire@php.net> |
970 + +----------------------------------------------------------------------+
971 +
972 + */
973 +
974 +/* $Id: apc_bin.h 274613 2009-01-26 06:57:57Z shire $ */
975 +
976 +#ifndef APC_BINDUMP_H
977 +#define APC_BINDUMP_H
978 +
979 +#include "apc.h"
980 +#include "apc_php.h"
981 +#include "ext/standard/basic_functions.h"
982 +
983 +/* APC binload flags */
984 +#define APC_BIN_VERIFY_MD5 1 << 0
985 +#define APC_BIN_VERIFY_CRC32 1 << 1
986 +
987 +typedef struct _apc_bd_entry_t {
988 + unsigned char type;
989 + uint num_functions;
990 + uint num_classes;
991 + apc_cache_entry_value_t val;
992 +} apc_bd_entry_t;
993 +
994 +typedef struct _apc_bd_t {
995 + unsigned int size;
996 + int swizzled;
997 + unsigned char md5[16];
998 + php_uint32 crc;
999 + unsigned int num_entries;
1000 + apc_bd_entry_t *entries;
1001 + int num_swizzled_ptrs;
1002 + void ***swizzled_ptrs;
1003 +} apc_bd_t;
1004 +
1005 +apc_bd_t* apc_bin_dump(HashTable *files, HashTable *user_vars TSRMLS_DC);
1006 +int apc_bin_load(apc_bd_t *bd, int flags TSRMLS_DC);
1007 +
1008 +#endif
1009 +
1010 +/*
1011 + * Local variables:
1012 + * tab-width: 4
1013 + * c-basic-offset: 4
1014 + * End:
1015 + * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
1016 + * vim<600: expandtab sw=4 ts=4 sts=4
1017 + */
1018 diff -Naur php-5.3.1.orig/ext/apc/apc.c php-5.3.1/ext/apc/apc.c
1019 --- php-5.3.1.orig/ext/apc/apc.c 1970-01-01 01:00:00.000000000 +0100
1020 +++ php-5.3.1/ext/apc/apc.c 1970-01-01 10:13:08.000000000 +0100
1021 @@ -0,0 +1,635 @@
1022 +/*
1023 + +----------------------------------------------------------------------+
1024 + | APC |
1025 + +----------------------------------------------------------------------+
1026 + | Copyright (c) 2006-2008 The PHP Group |
1027 + +----------------------------------------------------------------------+
1028 + | This source file is subject to version 3.01 of the PHP license, |
1029 + | that is bundled with this package in the file LICENSE, and is |
1030 + | available through the world-wide-web at the following url: |
1031 + | http://www.php.net/license/3_01.txt |
1032 + | If you did not receive a copy of the PHP license and are unable to |
1033 + | obtain it through the world-wide-web, please send a note to |
1034 + | license@php.net so we can mail you a copy immediately. |
1035 + +----------------------------------------------------------------------+
1036 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
1037 + | George Schlossnagle <george@omniti.com> |
1038 + | Rasmus Lerdorf <rasmus@php.net> |
1039 + | Arun C. Murthy <arunc@yahoo-inc.com> |
1040 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
1041 + +----------------------------------------------------------------------+
1042 +
1043 + This software was contributed to PHP by Community Connect Inc. in 2002
1044 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
1045 + Future revisions and derivatives of this source code must acknowledge
1046 + Community Connect Inc. as the original contributor of this module by
1047 + leaving this note intact in the source code.
1048 +
1049 + All other licensing and usage conditions are those of the PHP Group.
1050 +
1051 + */
1052 +
1053 +/* $Id: apc.c 277132 2009-03-14 01:50:57Z shire $ */
1054 +
1055 +#include "apc.h"
1056 +#include "apc_zend.h"
1057 +#include "php.h"
1058 +
1059 +#if HAVE_PCRE || HAVE_BUNDLED_PCRE
1060 +/* Deal with problem present until php-5.2.2 where php_pcre.h was not installed correctly */
1061 +# if !HAVE_BUNDLED_PCRE && PHP_MAJOR_VERSION == 5 && (PHP_MINOR_VERSION < 2 || (PHP_MINOR_VERSION == 2 && PHP_RELEASE_VERSION < 2))
1062 +# include "apc_php_pcre.h"
1063 +# else
1064 +# include "ext/pcre/php_pcre.h"
1065 +# endif
1066 +# include "ext/standard/php_smart_str.h"
1067 +#endif
1068 +
1069 +#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))
1070 +
1071 +/* {{{ memory allocation wrappers */
1072 +
1073 +void* apc_emalloc(size_t n)
1074 +{
1075 + void* p = malloc(n);
1076 + if (p == NULL) {
1077 + apc_eprint("apc_emalloc: malloc failed to allocate %u bytes:", n);
1078 + }
1079 + return p;
1080 +}
1081 +
1082 +void* apc_erealloc(void* p, size_t n)
1083 +{
1084 + p = realloc(p, n);
1085 + if (p == NULL) {
1086 + apc_eprint("apc_erealloc: realloc failed to allocate %u bytes:", n);
1087 + }
1088 + return p;
1089 +}
1090 +
1091 +void apc_efree(void* p)
1092 +{
1093 + if (p == NULL) {
1094 + apc_eprint("apc_efree: attempt to free null pointer");
1095 + }
1096 + free(p);
1097 +}
1098 +
1099 +char* apc_estrdup(const char* s)
1100 +{
1101 + int len;
1102 + char* dup;
1103 +
1104 + if (s == NULL) {
1105 + return NULL;
1106 + }
1107 + len = strlen(s);
1108 + dup = (char*) malloc(len+1);
1109 + if (dup == NULL) {
1110 + apc_eprint("apc_estrdup: malloc failed to allocate %u bytes:", len+1);
1111 + }
1112 + memcpy(dup, s, len);
1113 + dup[len] = '\0';
1114 + return dup;
1115 +}
1116 +
1117 +void* apc_xstrdup(const char* s, apc_malloc_t f)
1118 +{
1119 + return s != NULL ? apc_xmemcpy(s, strlen(s)+1, f) : NULL;
1120 +}
1121 +
1122 +void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f)
1123 +{
1124 + void* q;
1125 +
1126 + if (p != NULL && (q = f(n)) != NULL) {
1127 + memcpy(q, p, n);
1128 + return q;
1129 + }
1130 + return NULL;
1131 +}
1132 +
1133 +/* }}} */
1134 +
1135 +/* {{{ console display functions */
1136 +
1137 +static void my_log(int level, const char* fmt, va_list args)
1138 +{
1139 + static const char* level_strings[] = {
1140 + "apc-debug",
1141 + "apc-notice",
1142 + "apc-warning",
1143 + "apc-error"
1144 + };
1145 + static const int num_levels = NELEMS(level_strings);
1146 +
1147 + time_t now;
1148 + char* buf; /* for ctime */
1149 +
1150 + TSRMLS_FETCH();
1151 +
1152 + fflush(stdout);
1153 +
1154 + if (level < 0)
1155 + level = 0;
1156 + else if (level >= num_levels)
1157 + level = num_levels-1;
1158 +
1159 + now = time(0);
1160 + buf = ctime(&now); /* TODO: replace with reentrant impl */
1161 + buf[24] = '\0';
1162 +
1163 + fprintf(stderr, "[%s] [%s] ", buf, level_strings[level]);
1164 + vfprintf(stderr, fmt, args);
1165 +
1166 + if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') {
1167 + fprintf(stderr, " %s", strerror(errno));
1168 + }
1169 +
1170 + if (zend_is_compiling(TSRMLS_C)) {
1171 + fprintf(stderr, " in %s on line %d.", zend_get_compiled_filename(TSRMLS_C), zend_get_compiled_lineno(TSRMLS_C));
1172 + } else if (zend_is_executing(TSRMLS_C)) {
1173 + fprintf(stderr, " in %s on line %d.", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C));
1174 + }
1175 + fprintf(stderr, "\n");
1176 +
1177 + if (level == APC_ERROR) {
1178 + exit(2);
1179 + }
1180 +}
1181 +
1182 +void apc_eprint(const char* fmt, ...)
1183 +{
1184 + va_list args;
1185 + va_start(args, fmt);
1186 + my_log(APC_ERROR, fmt, args);
1187 + va_end(args);
1188 +}
1189 +
1190 +void apc_wprint(const char* fmt, ...)
1191 +{
1192 + va_list args;
1193 + va_start(args, fmt);
1194 + my_log(APC_WARNING, fmt, args);
1195 + va_end(args);
1196 +}
1197 +
1198 +void apc_nprint(const char* fmt, ...)
1199 +{
1200 + va_list args;
1201 + va_start(args, fmt);
1202 + my_log(APC_NOTICE, fmt, args);
1203 + va_end(args);
1204 +}
1205 +
1206 +void apc_dprint(const char* fmt, ...)
1207 +{
1208 +#ifdef APC_DEBUG
1209 + va_list args;
1210 + va_start(args, fmt);
1211 + my_log(APC_DBG, fmt, args);
1212 + va_end(args);
1213 +#endif
1214 +}
1215 +
1216 +/* }}} */
1217 +
1218 +/* {{{ string and text manipulation */
1219 +
1220 +char* apc_append(const char* s, const char* t)
1221 +{
1222 + int slen;
1223 + int tlen;
1224 + char* p;
1225 +
1226 + slen = strlen(s);
1227 + tlen = strlen(t);
1228 +
1229 + p = (char*) apc_emalloc((slen + tlen + 1) * sizeof(char));
1230 + memcpy(p, s, slen);
1231 + memcpy(p + slen, t, tlen + 1);
1232 +
1233 + return p;
1234 +}
1235 +
1236 +char* apc_substr(const char* s, int start, int length)
1237 +{
1238 + char* substr;
1239 + int src_len = strlen(s);
1240 +
1241 + /* bring start into range */
1242 + if (start < 0) {
1243 + start = 0;
1244 + }
1245 + else if (start >= src_len) {
1246 + start = src_len - 1;
1247 + }
1248 +
1249 + /* bring length into range */
1250 + if (length < 0 || src_len - start < length) {
1251 + length = src_len - start;
1252 + }
1253 +
1254 + /* create the substring */
1255 + substr = apc_xmemcpy(s + start, length + 1, apc_emalloc);
1256 + substr[length] = '\0';
1257 + return substr;
1258 +}
1259 +
1260 +char** apc_tokenize(const char* s, char delim)
1261 +{
1262 + char** tokens; /* array of tokens, NULL terminated */
1263 + int size; /* size of tokens array */
1264 + int n; /* index of next token in tokens array */
1265 + int cur; /* current position in input string */
1266 + int end; /* final legal position in input string */
1267 + int next; /* position of next delimiter in input */
1268 +
1269 + if (!s) {
1270 + return NULL;
1271 + }
1272 +
1273 + size = 2;
1274 + n = 0;
1275 + cur = 0;
1276 + end = strlen(s) - 1;
1277 +
1278 + tokens = (char**) apc_emalloc(size * sizeof(char*));
1279 + tokens[n] = NULL;
1280 +
1281 + while (cur <= end) {
1282 + /* search for the next delimiter */
1283 + char* p = strchr(s + cur, delim);
1284 + next = p ? p-s : end+1;
1285 +
1286 + /* resize token array if necessary */
1287 + if (n == size-1) {
1288 + size *= 2;
1289 + tokens = (char**) apc_erealloc(tokens, size * sizeof(char*));
1290 + }
1291 +
1292 + /* save the current token */
1293 + tokens[n] = apc_substr(s, cur, next-cur);
1294 +
1295 + tokens[++n] = NULL;
1296 + cur = next + 1;
1297 + }
1298 +
1299 + return tokens;
1300 +}
1301 +
1302 +/* }}} */
1303 +
1304 +/* {{{ apc stat */
1305 +/* similar to php_stream_stat_path */
1306 +#define APC_URL_STAT(wrapper, filename, pstatbuf) \
1307 + ((wrapper)->wops->url_stat((wrapper), (filename), PHP_STREAM_URL_STAT_QUIET, (pstatbuf), NULL TSRMLS_CC))
1308 +int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo)
1309 +{
1310 + char** paths;
1311 + char *exec_fname;
1312 + int exec_fname_length;
1313 + int found = 0;
1314 + int i;
1315 + php_stream_wrapper *wrapper = NULL;
1316 + char *path_for_open = NULL;
1317 +
1318 + TSRMLS_FETCH();
1319 +
1320 + assert(filename && fileinfo);
1321 +
1322 +
1323 + wrapper = php_stream_locate_url_wrapper(filename, &path_for_open, 0 TSRMLS_CC);
1324 +
1325 + if(!wrapper || !wrapper->wops || !wrapper->wops->url_stat) {
1326 + return -1;
1327 + }
1328 +
1329 + if(wrapper != &php_plain_files_wrapper) {
1330 + if(APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) {
1331 + strncpy(fileinfo->fullpath, path_for_open, MAXPATHLEN);
1332 + return 0;
1333 + }
1334 + return -1; /* cannot stat */
1335 + }
1336 +
1337 + if (IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) &&
1338 + APC_URL_STAT(wrapper, path_for_open, &fileinfo->st_buf) == 0) {
1339 + strncpy(fileinfo->fullpath, path_for_open, MAXPATHLEN);
1340 + return 0;
1341 + }
1342 +
1343 + paths = apc_tokenize(path, DEFAULT_DIR_SEPARATOR);
1344 + if (!paths)
1345 + return -1;
1346 +
1347 + /* for each directory in paths, look for filename inside */
1348 + for (i = 0; paths[i]; i++) {
1349 + snprintf(fileinfo->fullpath, sizeof(fileinfo->fullpath), "%s%c%s", paths[i], DEFAULT_SLASH, path_for_open);
1350 + if (APC_URL_STAT(wrapper, fileinfo->fullpath, &fileinfo->st_buf) == 0) {
1351 + found = 1;
1352 + break;
1353 + }
1354 + }
1355 +
1356 + /* check in path of the calling scripts' current working directory */
1357 + /* modified from main/streams/plain_wrapper.c */
1358 + if(!found && zend_is_executing(TSRMLS_C)) {
1359 + exec_fname = zend_get_executed_filename(TSRMLS_C);
1360 + exec_fname_length = strlen(exec_fname);
1361 + while((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
1362 + if((exec_fname && exec_fname[0] != '[') && exec_fname_length > 0) {
1363 + /* not: [no active file] or no path */
1364 + memcpy(fileinfo->fullpath, exec_fname, exec_fname_length);
1365 + fileinfo->fullpath[exec_fname_length] = DEFAULT_SLASH;
1366 + strlcpy(fileinfo->fullpath +exec_fname_length +1, path_for_open,sizeof(fileinfo->fullpath)-exec_fname_length-1);
1367 + /* apc_wprint("filename: %s, exec_fname: %s, fileinfo->fullpath: %s", path_for_open, exec_fname, fileinfo->fullpath); */
1368 + if (APC_URL_STAT(wrapper, fileinfo->fullpath, &fileinfo->st_buf) == 0) {
1369 + found = 1;
1370 + }
1371 + }
1372 + }
1373 +
1374 + /* free the value returned by apc_tokenize */
1375 + for (i = 0; paths[i]; i++) {
1376 + apc_efree(paths[i]);
1377 + }
1378 + apc_efree(paths);
1379 +
1380 + return found ? 0 : -1;
1381 +}
1382 +
1383 +/* }}} */
1384 +
1385 +/* {{{ regular expression wrapper functions */
1386 +
1387 +#if (HAVE_PCRE || HAVE_BUNDLED_PCRE)
1388 +typedef struct {
1389 + pcre *preg;
1390 + pcre *nreg;
1391 +} apc_regex;
1392 +
1393 +#define APC_ADD_PATTERN(match, pat) do {\
1394 + if(match.len > 1) {\
1395 + smart_str_appendc(&match, '|');\
1396 + }\
1397 + smart_str_appendc(&match, '(');\
1398 + while(*pat) {\
1399 + if(*pat == '/') smart_str_appendc(&match, '\\');\
1400 + \
1401 + smart_str_appendc(&match, *(pat++));\
1402 + }\
1403 + smart_str_appendc(&match, ')');\
1404 +} while(0)
1405 +
1406 +#define APC_COMPILE_PATTERN(re, match) do {\
1407 + if(match.len > 2) { /* more than just "//" */\
1408 + if (((re) = pcre_get_compiled_regex(match.c, NULL, NULL TSRMLS_CC)) == NULL) {\
1409 + apc_wprint("apc_regex_compile_array: invalid expression '%s'", match.c); \
1410 + smart_str_free(&match);\
1411 + return NULL;\
1412 + }\
1413 + } else { \
1414 + (re) = NULL;\
1415 + }\
1416 +} while(0)
1417 +
1418 +void* apc_regex_compile_array(char* patterns[] TSRMLS_DC)
1419 +{
1420 + apc_regex* regs;
1421 + int npat;
1422 + smart_str pmatch = {0,};
1423 + smart_str nmatch = {0,};
1424 + char* pattern;
1425 +
1426 + if (!patterns)
1427 + return NULL;
1428 +
1429 + regs = (apc_regex*) apc_emalloc(sizeof(apc_regex));
1430 +
1431 + smart_str_appendc(&pmatch, '/');
1432 + smart_str_appendc(&nmatch, '/');
1433 +
1434 + for (npat = 0; patterns[npat] != NULL; npat++) {
1435 + pattern = patterns[npat];
1436 + if(pattern[0] == '+') {
1437 + pattern += sizeof(char);
1438 + APC_ADD_PATTERN(pmatch, pattern);
1439 + } else {
1440 + if(pattern[0] == '-') pattern += sizeof(char);
1441 + APC_ADD_PATTERN(nmatch, pattern);
1442 + }
1443 + }
1444 + smart_str_appendc(&pmatch, '/');
1445 + smart_str_appendc(&nmatch, '/');
1446 +
1447 + smart_str_0(&nmatch);
1448 + smart_str_0(&pmatch);
1449 +
1450 + APC_COMPILE_PATTERN(regs->preg, pmatch);
1451 + APC_COMPILE_PATTERN(regs->nreg, nmatch);
1452 +
1453 + smart_str_free(&pmatch);
1454 + smart_str_free(&nmatch);
1455 +
1456 + return (void*) regs;
1457 +}
1458 +
1459 +void apc_regex_destroy_array(void* p)
1460 +{
1461 + if (p != NULL) {
1462 + apc_regex* regs = (apc_regex*) p;
1463 + apc_efree(regs);
1464 + }
1465 +}
1466 +
1467 +#define APC_MATCH_PATTERN(re, input, output) do {\
1468 + if (re && pcre_exec(re, NULL, (input), strlen(input), 0, 0, NULL, 0) >= 0) {\
1469 + return (output);\
1470 + }\
1471 +} while(0)
1472 +
1473 +
1474 +int apc_regex_match_array(void* p, const char* input)
1475 +{
1476 + apc_regex* regs;
1477 +
1478 + if (!p)
1479 + return 0;
1480 +
1481 + regs = (apc_regex*) p;
1482 +
1483 + APC_MATCH_PATTERN(regs->preg, input, APC_POSITIVE_MATCH);
1484 + APC_MATCH_PATTERN(regs->nreg, input, APC_NEGATIVE_MATCH);
1485 +
1486 + return 0;
1487 +}
1488 +#else /* no pcre */
1489 +void* apc_regex_compile_array(char* patterns[] TSRMLS_DC)
1490 +{
1491 + if(patterns && patterns[0] != NULL) {
1492 + apc_wprint("pcre missing, disabling filters");
1493 + }
1494 + return NULL;
1495 +}
1496 +void apc_regex_destroy_array(void* p)
1497 +{
1498 + /* nothing */
1499 +}
1500 +int apc_regex_match_array(void* p, const char* input)
1501 +{
1502 + return 0;
1503 +}
1504 +#endif
1505 +/* }}} */
1506 +
1507 +/* {{{ crc32 implementation */
1508 +
1509 +/* this table was generated by crc32gen() */
1510 +static unsigned int crc32tab[] = {
1511 + /* 0 */ 0x00000000, 0x3b83984b, 0x77073096, 0x4c84a8dd,
1512 + /* 4 */ 0xee0e612c, 0xd58df967, 0x990951ba, 0xa28ac9f1,
1513 + /* 8 */ 0x076dc419, 0x3cee5c52, 0x706af48f, 0x4be96cc4,
1514 + /* 12 */ 0xe963a535, 0xd2e03d7e, 0x9e6495a3, 0xa5e70de8,
1515 + /* 16 */ 0x0edb8832, 0x35581079, 0x79dcb8a4, 0x425f20ef,
1516 + /* 20 */ 0xe0d5e91e, 0xdb567155, 0x97d2d988, 0xac5141c3,
1517 + /* 24 */ 0x09b64c2b, 0x3235d460, 0x7eb17cbd, 0x4532e4f6,
1518 + /* 28 */ 0xe7b82d07, 0xdc3bb54c, 0x90bf1d91, 0xab3c85da,
1519 + /* 32 */ 0x1db71064, 0x2634882f, 0x6ab020f2, 0x5133b8b9,
1520 + /* 36 */ 0xf3b97148, 0xc83ae903, 0x84be41de, 0xbf3dd995,
1521 + /* 40 */ 0x1adad47d, 0x21594c36, 0x6ddde4eb, 0x565e7ca0,
1522 + /* 44 */ 0xf4d4b551, 0xcf572d1a, 0x83d385c7, 0xb8501d8c,
1523 + /* 48 */ 0x136c9856, 0x28ef001d, 0x646ba8c0, 0x5fe8308b,
1524 + /* 52 */ 0xfd62f97a, 0xc6e16131, 0x8a65c9ec, 0xb1e651a7,
1525 + /* 56 */ 0x14015c4f, 0x2f82c404, 0x63066cd9, 0x5885f492,
1526 + /* 60 */ 0xfa0f3d63, 0xc18ca528, 0x8d080df5, 0xb68b95be,
1527 + /* 64 */ 0x3b6e20c8, 0x00edb883, 0x4c69105e, 0x77ea8815,
1528 + /* 68 */ 0xd56041e4, 0xeee3d9af, 0xa2677172, 0x99e4e939,
1529 + /* 72 */ 0x3c03e4d1, 0x07807c9a, 0x4b04d447, 0x70874c0c,
1530 + /* 76 */ 0xd20d85fd, 0xe98e1db6, 0xa50ab56b, 0x9e892d20,
1531 + /* 80 */ 0x35b5a8fa, 0x0e3630b1, 0x42b2986c, 0x79310027,
1532 + /* 84 */ 0xdbbbc9d6, 0xe038519d, 0xacbcf940, 0x973f610b,
1533 + /* 88 */ 0x32d86ce3, 0x095bf4a8, 0x45df5c75, 0x7e5cc43e,
1534 + /* 92 */ 0xdcd60dcf, 0xe7559584, 0xabd13d59, 0x9052a512,
1535 + /* 96 */ 0x26d930ac, 0x1d5aa8e7, 0x51de003a, 0x6a5d9871,
1536 + /* 100 */ 0xc8d75180, 0xf354c9cb, 0xbfd06116, 0x8453f95d,
1537 + /* 104 */ 0x21b4f4b5, 0x1a376cfe, 0x56b3c423, 0x6d305c68,
1538 + /* 108 */ 0xcfba9599, 0xf4390dd2, 0xb8bda50f, 0x833e3d44,
1539 + /* 112 */ 0x2802b89e, 0x138120d5, 0x5f058808, 0x64861043,
1540 + /* 116 */ 0xc60cd9b2, 0xfd8f41f9, 0xb10be924, 0x8a88716f,
1541 + /* 120 */ 0x2f6f7c87, 0x14ece4cc, 0x58684c11, 0x63ebd45a,
1542 + /* 124 */ 0xc1611dab, 0xfae285e0, 0xb6662d3d, 0x8de5b576,
1543 + /* 128 */ 0x76dc4190, 0x4d5fd9db, 0x01db7106, 0x3a58e94d,
1544 + /* 132 */ 0x98d220bc, 0xa351b8f7, 0xefd5102a, 0xd4568861,
1545 + /* 136 */ 0x71b18589, 0x4a321dc2, 0x06b6b51f, 0x3d352d54,
1546 + /* 140 */ 0x9fbfe4a5, 0xa43c7cee, 0xe8b8d433, 0xd33b4c78,
1547 + /* 144 */ 0x7807c9a2, 0x438451e9, 0x0f00f934, 0x3483617f,
1548 + /* 148 */ 0x9609a88e, 0xad8a30c5, 0xe10e9818, 0xda8d0053,
1549 + /* 152 */ 0x7f6a0dbb, 0x44e995f0, 0x086d3d2d, 0x33eea566,
1550 + /* 156 */ 0x91646c97, 0xaae7f4dc, 0xe6635c01, 0xdde0c44a,
1551 + /* 160 */ 0x6b6b51f4, 0x50e8c9bf, 0x1c6c6162, 0x27eff929,
1552 + /* 164 */ 0x856530d8, 0xbee6a893, 0xf262004e, 0xc9e19805,
1553 + /* 168 */ 0x6c0695ed, 0x57850da6, 0x1b01a57b, 0x20823d30,
1554 + /* 172 */ 0x8208f4c1, 0xb98b6c8a, 0xf50fc457, 0xce8c5c1c,
1555 + /* 176 */ 0x65b0d9c6, 0x5e33418d, 0x12b7e950, 0x2934711b,
1556 + /* 180 */ 0x8bbeb8ea, 0xb03d20a1, 0xfcb9887c, 0xc73a1037,
1557 + /* 184 */ 0x62dd1ddf, 0x595e8594, 0x15da2d49, 0x2e59b502,
1558 + /* 188 */ 0x8cd37cf3, 0xb750e4b8, 0xfbd44c65, 0xc057d42e,
1559 + /* 192 */ 0x4db26158, 0x7631f913, 0x3ab551ce, 0x0136c985,
1560 + /* 196 */ 0xa3bc0074, 0x983f983f, 0xd4bb30e2, 0xef38a8a9,
1561 + /* 200 */ 0x4adfa541, 0x715c3d0a, 0x3dd895d7, 0x065b0d9c,
1562 + /* 204 */ 0xa4d1c46d, 0x9f525c26, 0xd3d6f4fb, 0xe8556cb0,
1563 + /* 208 */ 0x4369e96a, 0x78ea7121, 0x346ed9fc, 0x0fed41b7,
1564 + /* 212 */ 0xad678846, 0x96e4100d, 0xda60b8d0, 0xe1e3209b,
1565 + /* 216 */ 0x44042d73, 0x7f87b538, 0x33031de5, 0x088085ae,
1566 + /* 220 */ 0xaa0a4c5f, 0x9189d414, 0xdd0d7cc9, 0xe68ee482,
1567 + /* 224 */ 0x5005713c, 0x6b86e977, 0x270241aa, 0x1c81d9e1,
1568 + /* 228 */ 0xbe0b1010, 0x8588885b, 0xc90c2086, 0xf28fb8cd,
1569 + /* 232 */ 0x5768b525, 0x6ceb2d6e, 0x206f85b3, 0x1bec1df8,
1570 + /* 236 */ 0xb966d409, 0x82e54c42, 0xce61e49f, 0xf5e27cd4,
1571 + /* 240 */ 0x5edef90e, 0x655d6145, 0x29d9c998, 0x125a51d3,
1572 + /* 244 */ 0xb0d09822, 0x8b530069, 0xc7d7a8b4, 0xfc5430ff,
1573 + /* 248 */ 0x59b33d17, 0x6230a55c, 0x2eb40d81, 0x153795ca,
1574 + /* 252 */ 0xb7bd5c3b, 0x8c3ec470, 0xc0ba6cad, 0xfb39f4e6,
1575 +};
1576 +
1577 +unsigned int apc_crc32(const char* buf, int len)
1578 +{
1579 + int i;
1580 + int k;
1581 + unsigned int crc;
1582 +
1583 + /* preconditioning */
1584 + crc = 0xFFFFFFFF;
1585 +
1586 + for (i = 0; i < len; i++) {
1587 + k = (crc ^ buf[i]) & 0x000000FF;
1588 + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[k];
1589 + }
1590 +
1591 + /* postconditioning */
1592 + return ~crc;
1593 +}
1594 +
1595 +/* crc32gen: generate the nth (0..255) crc32 table value */
1596 +#if 0
1597 +static unsigned long crc32gen(int n)
1598 +{
1599 + int i;
1600 + unsigned long crc;
1601 +
1602 + crc = n;
1603 + for (i = 8; i >= 0; i--) {
1604 + if (crc & 1) {
1605 + crc = (crc >> 1) ^ 0xEDB88320;
1606 + }
1607 + else {
1608 + crc >>= 1;
1609 + }
1610 + }
1611 + return crc;
1612 +}
1613 +#endif
1614 +
1615 +/* }}} */
1616 +
1617 +
1618 +/* {{{ apc_flip_hash() */
1619 +HashTable* apc_flip_hash(HashTable *hash) {
1620 + zval **entry, *data;
1621 + HashTable *new_hash;
1622 + HashPosition pos;
1623 +
1624 + if(hash == NULL) return hash;
1625 +
1626 + MAKE_STD_ZVAL(data);
1627 + ZVAL_LONG(data, 1);
1628 +
1629 + new_hash = emalloc(sizeof(HashTable));
1630 + zend_hash_init(new_hash, hash->nTableSize, NULL, ZVAL_PTR_DTOR, 0);
1631 +
1632 + zend_hash_internal_pointer_reset_ex(hash, &pos);
1633 + while (zend_hash_get_current_data_ex(hash, (void **)&entry, &pos) == SUCCESS) {
1634 + if(Z_TYPE_PP(entry) == IS_STRING) {
1635 + zend_hash_update(new_hash, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) +1, &data, sizeof(data), NULL);
1636 + } else {
1637 + zend_hash_index_update(new_hash, Z_LVAL_PP(entry), &data, sizeof(data), NULL);
1638 + }
1639 + Z_ADDREF_P(data);
1640 + zend_hash_move_forward_ex(hash, &pos);
1641 + }
1642 + efree(data);
1643 +
1644 + return new_hash;
1645 +}
1646 +/* }}} */
1647 +
1648 +
1649 +/*
1650 + * Local variables:
1651 + * tab-width: 4
1652 + * c-basic-offset: 4
1653 + * End:
1654 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
1655 + * vim<600: expandtab sw=4 ts=4 sts=4
1656 + */
1657 diff -Naur php-5.3.1.orig/ext/apc/apc_cache.c php-5.3.1/ext/apc/apc_cache.c
1658 --- php-5.3.1.orig/ext/apc/apc_cache.c 1970-01-01 01:00:00.000000000 +0100
1659 +++ php-5.3.1/ext/apc/apc_cache.c 1970-01-01 10:13:08.000000000 +0100
1660 @@ -0,0 +1,1183 @@
1661 +/*
1662 + +----------------------------------------------------------------------+
1663 + | APC |
1664 + +----------------------------------------------------------------------+
1665 + | Copyright (c) 2006-2008 The PHP Group |
1666 + +----------------------------------------------------------------------+
1667 + | This source file is subject to version 3.01 of the PHP license, |
1668 + | that is bundled with this package in the file LICENSE, and is |
1669 + | available through the world-wide-web at the following url: |
1670 + | http://www.php.net/license/3_01.txt |
1671 + | If you did not receive a copy of the PHP license and are unable to |
1672 + | obtain it through the world-wide-web, please send a note to |
1673 + | license@php.net so we can mail you a copy immediately. |
1674 + +----------------------------------------------------------------------+
1675 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
1676 + | Rasmus Lerdorf <rasmus@php.net> |
1677 + | Arun C. Murthy <arunc@yahoo-inc.com> |
1678 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
1679 + +----------------------------------------------------------------------+
1680 +
1681 + This software was contributed to PHP by Community Connect Inc. in 2002
1682 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
1683 + Future revisions and derivatives of this source code must acknowledge
1684 + Community Connect Inc. as the original contributor of this module by
1685 + leaving this note intact in the source code.
1686 +
1687 + All other licensing and usage conditions are those of the PHP Group.
1688 +
1689 + */
1690 +
1691 +/* $Id: apc_cache.c 286717 2009-08-03 05:25:32Z gopalv $ */
1692 +
1693 +#include "apc_cache.h"
1694 +#include "apc_sma.h"
1695 +#include "apc_main.h"
1696 +#include "apc_globals.h"
1697 +#include "SAPI.h"
1698 +
1699 +/* TODO: rehash when load factor exceeds threshold */
1700 +
1701 +#define CHECK(p) { if ((p) == NULL) return NULL; }
1702 +
1703 +/* {{{ key_equals */
1704 +#define key_equals(a, b) (a.inode==b.inode && a.device==b.device)
1705 +/* }}} */
1706 +
1707 +static void apc_cache_expunge(apc_cache_t* cache, size_t size);
1708 +
1709 +/* {{{ hash */
1710 +static unsigned int hash(apc_cache_key_t key)
1711 +{
1712 + return key.data.file.device + key.data.file.inode;
1713 +}
1714 +/* }}} */
1715 +
1716 +/* {{{ string_nhash_8 */
1717 +#define string_nhash_8(s,len) (unsigned int)(zend_inline_hash_func(s, len))
1718 +/* }}} */
1719 +
1720 +/* {{{ make_slot */
1721 +slot_t* make_slot(apc_cache_key_t key, apc_cache_entry_t* value, slot_t* next, time_t t)
1722 +{
1723 + slot_t* p = apc_pool_alloc(value->pool, sizeof(slot_t));
1724 +
1725 + if (!p) return NULL;
1726 +
1727 + if(value->type == APC_CACHE_ENTRY_USER) {
1728 + char *identifier = (char*) apc_pstrdup(key.data.user.identifier, value->pool);
1729 + if (!identifier) {
1730 + return NULL;
1731 + }
1732 + key.data.user.identifier = identifier;
1733 + } else if(key.type == APC_CACHE_KEY_FPFILE) {
1734 + char *fullpath = (char*) apc_pstrdup(key.data.fpfile.fullpath, value->pool);
1735 + if (!fullpath) {
1736 + return NULL;
1737 + }
1738 + key.data.fpfile.fullpath = fullpath;
1739 + }
1740 + p->key = key;
1741 + p->value = value;
1742 + p->next = next;
1743 + p->num_hits = 0;
1744 + p->creation_time = t;
1745 + p->access_time = t;
1746 + p->deletion_time = 0;
1747 + return p;
1748 +}
1749 +/* }}} */
1750 +
1751 +/* {{{ free_slot */
1752 +static void free_slot(slot_t* slot)
1753 +{
1754 + apc_pool_destroy(slot->value->pool);
1755 +}
1756 +/* }}} */
1757 +
1758 +/* {{{ remove_slot */
1759 +static void remove_slot(apc_cache_t* cache, slot_t** slot)
1760 +{
1761 + slot_t* dead = *slot;
1762 + *slot = (*slot)->next;
1763 +
1764 + cache->header->mem_size -= dead->value->mem_size;
1765 + cache->header->num_entries--;
1766 + if (dead->value->ref_count <= 0) {
1767 + free_slot(dead);
1768 + }
1769 + else {
1770 + dead->next = cache->header->deleted_list;
1771 + dead->deletion_time = time(0);
1772 + cache->header->deleted_list = dead;
1773 + }
1774 +}
1775 +/* }}} */
1776 +
1777 +/* {{{ process_pending_removals */
1778 +static void process_pending_removals(apc_cache_t* cache)
1779 +{
1780 + slot_t** slot;
1781 + time_t now;
1782 +
1783 + /* This function scans the list of removed cache entries and deletes any
1784 + * entry whose reference count is zero (indicating that it is no longer
1785 + * being executed) or that has been on the pending list for more than
1786 + * cache->gc_ttl seconds (we issue a warning in the latter case).
1787 + */
1788 +
1789 + if (!cache->header->deleted_list)
1790 + return;
1791 +
1792 + slot = &cache->header->deleted_list;
1793 + now = time(0);
1794 +
1795 + while (*slot != NULL) {
1796 + int gc_sec = cache->gc_ttl ? (now - (*slot)->deletion_time) : 0;
1797 +
1798 + if ((*slot)->value->ref_count <= 0 || gc_sec > cache->gc_ttl) {
1799 + slot_t* dead = *slot;
1800 +
1801 + if (dead->value->ref_count > 0) {
1802 + switch(dead->value->type) {
1803 + case APC_CACHE_ENTRY_FILE:
1804 + apc_wprint("GC cache entry '%s' (dev=%d ino=%d) was on gc-list for %d seconds",
1805 + dead->value->data.file.filename, dead->key.data.file.device, dead->key.data.file.inode, gc_sec);
1806 + break;
1807 + case APC_CACHE_ENTRY_USER:
1808 + apc_wprint("GC cache entry '%s'was on gc-list for %d seconds", dead->value->data.user.info, gc_sec);
1809 + break;
1810 + }
1811 + }
1812 + *slot = dead->next;
1813 + free_slot(dead);
1814 + }
1815 + else {
1816 + slot = &(*slot)->next;
1817 + }
1818 + }
1819 +}
1820 +/* }}} */
1821 +
1822 +/* {{{ prevent_garbage_collection */
1823 +static void prevent_garbage_collection(apc_cache_entry_t* entry)
1824 +{
1825 + /* set reference counts on zend objects to an arbitrarily high value to
1826 + * prevent garbage collection after execution */
1827 +
1828 + enum { BIG_VALUE = 1000 };
1829 +
1830 + if(entry->data.file.op_array) {
1831 + entry->data.file.op_array->refcount[0] = BIG_VALUE;
1832 + }
1833 + if (entry->data.file.functions) {
1834 + int i;
1835 + apc_function_t* fns = entry->data.file.functions;
1836 + for (i=0; fns[i].function != NULL; i++) {
1837 + *(fns[i].function->op_array.refcount) = BIG_VALUE;
1838 + }
1839 + }
1840 + if (entry->data.file.classes) {
1841 + int i;
1842 + apc_class_t* classes = entry->data.file.classes;
1843 + for (i=0; classes[i].class_entry != NULL; i++) {
1844 + classes[i].class_entry->refcount = BIG_VALUE;
1845 + }
1846 + }
1847 +}
1848 +/* }}} */
1849 +
1850 +/* {{{ apc_cache_create */
1851 +apc_cache_t* apc_cache_create(int size_hint, int gc_ttl, int ttl)
1852 +{
1853 + apc_cache_t* cache;
1854 + int cache_size;
1855 + int num_slots;
1856 + int i;
1857 +
1858 + num_slots = size_hint > 0 ? size_hint*2 : 2000;
1859 +
1860 + cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t));
1861 + cache_size = sizeof(cache_header_t) + num_slots*sizeof(slot_t*);
1862 +
1863 + cache->shmaddr = apc_sma_malloc(cache_size);
1864 + if(!cache->shmaddr) {
1865 + apc_eprint("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). ");
1866 + }
1867 + memset(cache->shmaddr, 0, cache_size);
1868 +
1869 + cache->header = (cache_header_t*) cache->shmaddr;
1870 + cache->header->num_hits = 0;
1871 + cache->header->num_misses = 0;
1872 + cache->header->deleted_list = NULL;
1873 + cache->header->start_time = time(NULL);
1874 + cache->header->expunges = 0;
1875 + cache->header->busy = 0;
1876 +
1877 + cache->slots = (slot_t**) (((char*) cache->shmaddr) + sizeof(cache_header_t));
1878 + cache->num_slots = num_slots;
1879 + cache->gc_ttl = gc_ttl;
1880 + cache->ttl = ttl;
1881 + CREATE_LOCK(cache->header->lock);
1882 +#if NONBLOCKING_LOCK_AVAILABLE
1883 + CREATE_LOCK(cache->header->wrlock);
1884 +#endif
1885 + for (i = 0; i < num_slots; i++) {
1886 + cache->slots[i] = NULL;
1887 + }
1888 + cache->expunge_cb = apc_cache_expunge;
1889 + cache->has_lock = 0;
1890 +
1891 + return cache;
1892 +}
1893 +/* }}} */
1894 +
1895 +/* {{{ apc_cache_destroy */
1896 +void apc_cache_destroy(apc_cache_t* cache)
1897 +{
1898 + DESTROY_LOCK(cache->header->lock);
1899 +#ifdef NONBLOCKING_LOCK_AVAILABLE
1900 + DESTROY_LOCK(cache->header->wrlock);
1901 +#endif
1902 + apc_efree(cache);
1903 +}
1904 +/* }}} */
1905 +
1906 +/* {{{ apc_cache_clear */
1907 +void apc_cache_clear(apc_cache_t* cache)
1908 +{
1909 + int i;
1910 +
1911 + if(!cache) return;
1912 +
1913 + CACHE_LOCK(cache);
1914 + cache->header->busy = 1;
1915 + cache->header->num_hits = 0;
1916 + cache->header->num_misses = 0;
1917 + cache->header->start_time = time(NULL);
1918 + cache->header->expunges = 0;
1919 +
1920 + for (i = 0; i < cache->num_slots; i++) {
1921 + slot_t* p = cache->slots[i];
1922 + while (p) {
1923 + remove_slot(cache, &p);
1924 + }
1925 + cache->slots[i] = NULL;
1926 + }
1927 +
1928 + memset(&cache->header->lastkey, 0, sizeof(apc_keyid_t));
1929 +
1930 + cache->header->busy = 0;
1931 + CACHE_UNLOCK(cache);
1932 +}
1933 +/* }}} */
1934 +
1935 +/* {{{ apc_cache_expunge */
1936 +static void apc_cache_expunge(apc_cache_t* cache, size_t size)
1937 +{
1938 + int i;
1939 + time_t t;
1940 + TSRMLS_FETCH();
1941 +
1942 + t = apc_time();
1943 +
1944 + if(!cache) return;
1945 +
1946 + if(!cache->ttl) {
1947 + /*
1948 + * If cache->ttl is not set, we wipe out the entire cache when
1949 + * we run out of space.
1950 + */
1951 + CACHE_SAFE_LOCK(cache);
1952 + cache->header->busy = 1;
1953 + cache->header->expunges++;
1954 + for (i = 0; i < cache->num_slots; i++) {
1955 + slot_t* p = cache->slots[i];
1956 + while (p) {
1957 + remove_slot(cache, &p);
1958 + }
1959 + cache->slots[i] = NULL;
1960 + }
1961 + cache->header->busy = 0;
1962 + CACHE_SAFE_UNLOCK(cache);
1963 + } else {
1964 + slot_t **p;
1965 +
1966 + /*
1967 + * If the ttl for the cache is set we walk through and delete stale
1968 + * entries. For the user cache that is slightly confusing since
1969 + * we have the individual entry ttl's we can look at, but that would be
1970 + * too much work. So if you want the user cache expunged, set a high
1971 + * default apc.user_ttl and still provide a specific ttl for each entry
1972 + * on insert
1973 + */
1974 +
1975 + CACHE_SAFE_LOCK(cache);
1976 + cache->header->busy = 1;
1977 + cache->header->expunges++;
1978 + for (i = 0; i < cache->num_slots; i++) {
1979 + p = &cache->slots[i];
1980 + while(*p) {
1981 + /*
1982 + * For the user cache we look at the individual entry ttl values
1983 + * and if not set fall back to the default ttl for the user cache
1984 + */
1985 + if((*p)->value->type == APC_CACHE_ENTRY_USER) {
1986 + if((*p)->value->data.user.ttl) {
1987 + if((time_t) ((*p)->creation_time + (*p)->value->data.user.ttl) < t) {
1988 + remove_slot(cache, p);
1989 + continue;
1990 + }
1991 + } else if(cache->ttl) {
1992 + if((*p)->creation_time + cache->ttl < t) {
1993 + remove_slot(cache, p);
1994 + continue;
1995 + }
1996 + }
1997 + } else if((*p)->access_time < (t - cache->ttl)) {
1998 + remove_slot(cache, p);
1999 + continue;
2000 + }
2001 + p = &(*p)->next;
2002 + }
2003 + }
2004 + cache->header->busy = 0;
2005 + CACHE_SAFE_UNLOCK(cache);
2006 + }
2007 +}
2008 +/* }}} */
2009 +
2010 +/* {{{ apc_cache_insert */
2011 +static inline int _apc_cache_insert(apc_cache_t* cache,
2012 + apc_cache_key_t key,
2013 + apc_cache_entry_t* value,
2014 + apc_context_t* ctxt,
2015 + time_t t)
2016 +{
2017 + slot_t** slot;
2018 +
2019 + if (!value) {
2020 + return 0;
2021 + }
2022 +
2023 +#ifdef __DEBUG_APC__
2024 + fprintf(stderr,"Inserting [%s]\n", value->data.file.filename);
2025 +#endif
2026 +
2027 + process_pending_removals(cache);
2028 +
2029 + if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots];
2030 + else slot = &cache->slots[string_nhash_8(key.data.fpfile.fullpath, key.data.fpfile.fullpath_len) % cache->num_slots];
2031 +
2032 + while(*slot) {
2033 + if(key.type == (*slot)->key.type) {
2034 + if(key.type == APC_CACHE_KEY_FILE) {
2035 + if(key_equals((*slot)->key.data.file, key.data.file)) {
2036 + /* If existing slot for the same device+inode is different, remove it and insert the new version */
2037 + if (ctxt->force_update || (*slot)->key.mtime != key.mtime) {
2038 + remove_slot(cache, slot);
2039 + break;
2040 + }
2041 + return 0;
2042 + } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
2043 + remove_slot(cache, slot);
2044 + continue;
2045 + }
2046 + } else { /* APC_CACHE_KEY_FPFILE */
2047 + if(!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) {
2048 + /* Hrm.. it's already here, remove it and insert new one */
2049 + remove_slot(cache, slot);
2050 + break;
2051 + } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
2052 + remove_slot(cache, slot);
2053 + continue;
2054 + }
2055 + }
2056 + }
2057 + slot = &(*slot)->next;
2058 + }
2059 +
2060 + if ((*slot = make_slot(key, value, *slot, t)) == NULL) {
2061 + return -1;
2062 + }
2063 +
2064 + value->mem_size = ctxt->pool->size;
2065 + cache->header->mem_size += ctxt->pool->size;
2066 + cache->header->num_entries++;
2067 + cache->header->num_inserts++;
2068 +
2069 + return 1;
2070 +}
2071 +/* }}} */
2072 +
2073 +/* {{{ apc_cache_insert */
2074 +int apc_cache_insert(apc_cache_t* cache, apc_cache_key_t key, apc_cache_entry_t* value, apc_context_t *ctxt, time_t t)
2075 +{
2076 + int rval;
2077 + CACHE_LOCK(cache);
2078 + rval = _apc_cache_insert(cache, key, value, ctxt, t);
2079 + CACHE_UNLOCK(cache);
2080 + return rval;
2081 +}
2082 +/* }}} */
2083 +
2084 +/* {{{ apc_cache_insert */
2085 +int *apc_cache_insert_mult(apc_cache_t* cache, apc_cache_key_t* keys, apc_cache_entry_t** values, apc_context_t *ctxt, time_t t, int num_entries)
2086 +{
2087 + int *rval;
2088 + int i;
2089 +
2090 + rval = emalloc(sizeof(int) * num_entries);
2091 + CACHE_LOCK(cache);
2092 + for (i=0; i < num_entries; i++) {
2093 + if (values[i]) {
2094 + ctxt->pool = values[i]->pool;
2095 + rval[i] = _apc_cache_insert(cache, keys[i], values[i], ctxt, t);
2096 + }
2097 + }
2098 + CACHE_UNLOCK(cache);
2099 + return rval;
2100 +}
2101 +/* }}} */
2102 +
2103 +
2104 +/* {{{ apc_cache_user_insert */
2105 +int apc_cache_user_insert(apc_cache_t* cache, apc_cache_key_t key, apc_cache_entry_t* value, apc_context_t* ctxt, time_t t, int exclusive TSRMLS_DC)
2106 +{
2107 + slot_t** slot;
2108 + unsigned int keylen = key.data.user.identifier_len+1;
2109 + unsigned int h = string_nhash_8(key.data.user.identifier, keylen);
2110 + apc_keyid_t *lastkey = &cache->header->lastkey;
2111 +
2112 + if (!value) {
2113 + return 0;
2114 + }
2115 +
2116 + if(apc_cache_busy(cache)) {
2117 + /* cache cleanup in progress, do not wait */
2118 + return 0;
2119 + }
2120 +
2121 + if(apc_cache_is_last_key(cache, &key, t)) {
2122 + /* potential cache slam */
2123 + return 0;
2124 + }
2125 +
2126 + CACHE_LOCK(cache);
2127 +
2128 + memset(lastkey, 0, sizeof(apc_keyid_t));
2129 +
2130 + lastkey->h = h;
2131 + lastkey->keylen = keylen;
2132 + lastkey->mtime = t;
2133 +
2134 + /* we do not reset lastkey after the insert. Whether it is inserted
2135 + * or not, another insert in the same second is always a bad idea.
2136 + */
2137 +
2138 + process_pending_removals(cache);
2139 +
2140 + slot = &cache->slots[h % cache->num_slots];
2141 +
2142 + while (*slot) {
2143 + if (!memcmp((*slot)->key.data.user.identifier, key.data.user.identifier, keylen)) {
2144 + /*
2145 + * At this point we have found the user cache entry. If we are doing
2146 + * an exclusive insert (apc_add) we are going to bail right away if
2147 + * the user entry already exists and it has no ttl, or
2148 + * there is a ttl and the entry has not timed out yet.
2149 + */
2150 + if(exclusive && ( !(*slot)->value->data.user.ttl ||
2151 + ( (*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) >= t )
2152 + ) ) {
2153 + goto fail;
2154 + }
2155 + remove_slot(cache, slot);
2156 + break;
2157 + } else
2158 + /*
2159 + * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of
2160 + * slot entries so we don't always have to skip past a bunch of stale entries. We check
2161 + * for staleness here and get rid of them by first checking to see if the cache has a global
2162 + * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly
2163 + * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl
2164 + */
2165 + if((cache->ttl && (*slot)->access_time < (t - cache->ttl)) ||
2166 + ((*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t)) {
2167 + remove_slot(cache, slot);
2168 + continue;
2169 + }
2170 + slot = &(*slot)->next;
2171 + }
2172 +
2173 + if ((*slot = make_slot(key, value, *slot, t)) == NULL) {
2174 + goto fail;
2175 + }
2176 +
2177 + value->mem_size = ctxt->pool->size;
2178 + cache->header->mem_size += ctxt->pool->size;
2179 +
2180 + cache->header->num_entries++;
2181 + cache->header->num_inserts++;
2182 +
2183 + CACHE_UNLOCK(cache);
2184 +
2185 + return 1;
2186 +
2187 +fail:
2188 + CACHE_UNLOCK(cache);
2189 +
2190 + return 0;
2191 +}
2192 +/* }}} */
2193 +
2194 +/* {{{ apc_cache_find_slot */
2195 +slot_t* apc_cache_find_slot(apc_cache_t* cache, apc_cache_key_t key, time_t t)
2196 +{
2197 + slot_t** slot;
2198 + volatile slot_t* retval = NULL;
2199 +
2200 + CACHE_LOCK(cache);
2201 + if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots];
2202 + else slot = &cache->slots[string_nhash_8(key.data.fpfile.fullpath, key.data.fpfile.fullpath_len) % cache->num_slots];
2203 +
2204 + while (*slot) {
2205 + if(key.type == (*slot)->key.type) {
2206 + if(key.type == APC_CACHE_KEY_FILE) {
2207 + if(key_equals((*slot)->key.data.file, key.data.file)) {
2208 + if((*slot)->key.mtime != key.mtime) {
2209 + remove_slot(cache, slot);
2210 + cache->header->num_misses++;
2211 + CACHE_UNLOCK(cache);
2212 + return NULL;
2213 + }
2214 + (*slot)->num_hits++;
2215 + (*slot)->value->ref_count++;
2216 + (*slot)->access_time = t;
2217 + prevent_garbage_collection((*slot)->value);
2218 + cache->header->num_hits++;
2219 + retval = *slot;
2220 + CACHE_UNLOCK(cache);
2221 + return (slot_t*)retval;
2222 + }
2223 + } else { /* APC_CACHE_KEY_FPFILE */
2224 + if(!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) {
2225 + /* TTL Check ? */
2226 + (*slot)->num_hits++;
2227 + (*slot)->value->ref_count++;
2228 + (*slot)->access_time = t;
2229 + prevent_garbage_collection((*slot)->value);
2230 + cache->header->num_hits++;
2231 + retval = *slot;
2232 + CACHE_UNLOCK(cache);
2233 + return (slot_t*)retval;
2234 + }
2235 + }
2236 + }
2237 + slot = &(*slot)->next;
2238 + }
2239 + cache->header->num_misses++;
2240 + CACHE_UNLOCK(cache);
2241 + return NULL;
2242 +}
2243 +/* }}} */
2244 +
2245 +/* {{{ apc_cache_find */
2246 +apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, apc_cache_key_t key, time_t t)
2247 +{
2248 + slot_t * slot = apc_cache_find_slot(cache, key, t);
2249 + return (slot) ? slot->value : NULL;
2250 +}
2251 +/* }}} */
2252 +
2253 +/* {{{ apc_cache_user_find */
2254 +apc_cache_entry_t* apc_cache_user_find(apc_cache_t* cache, char *strkey, int keylen, time_t t)
2255 +{
2256 + slot_t** slot;
2257 + volatile apc_cache_entry_t* value = NULL;
2258 +
2259 + if(apc_cache_busy(cache))
2260 + {
2261 + /* cache cleanup in progress */
2262 + return NULL;
2263 + }
2264 +
2265 + CACHE_LOCK(cache);
2266 +
2267 + slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots];
2268 +
2269 + while (*slot) {
2270 + if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
2271 + /* Check to make sure this entry isn't expired by a hard TTL */
2272 + if((*slot)->value->data.user.ttl && (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl) < t) {
2273 + remove_slot(cache, slot);
2274 + cache->header->num_misses++;
2275 + CACHE_UNLOCK(cache);
2276 + return NULL;
2277 + }
2278 + /* Otherwise we are fine, increase counters and return the cache entry */
2279 + (*slot)->num_hits++;
2280 + (*slot)->value->ref_count++;
2281 + (*slot)->access_time = t;
2282 +
2283 + cache->header->num_hits++;
2284 + value = (*slot)->value;
2285 + CACHE_UNLOCK(cache);
2286 + return (apc_cache_entry_t*)value;
2287 + }
2288 + slot = &(*slot)->next;
2289 + }
2290 +
2291 + cache->header->num_misses++;
2292 + CACHE_UNLOCK(cache);
2293 + return NULL;
2294 +}
2295 +/* }}} */
2296 +
2297 +/* {{{ apc_cache_user_update */
2298 +int _apc_cache_user_update(apc_cache_t* cache, char *strkey, int keylen, apc_cache_updater_t updater, void* data TSRMLS_DC)
2299 +{
2300 + slot_t** slot;
2301 + int retval;
2302 +
2303 + if(apc_cache_busy(cache))
2304 + {
2305 + /* cache cleanup in progress */
2306 + return 0;
2307 + }
2308 +
2309 + CACHE_LOCK(cache);
2310 +
2311 + slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots];
2312 +
2313 + while (*slot) {
2314 + if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
2315 + retval = updater(cache, (*slot)->value, data);
2316 + (*slot)->key.mtime = apc_time();
2317 + CACHE_UNLOCK(cache);
2318 + return retval;
2319 + }
2320 + slot = &(*slot)->next;
2321 + }
2322 + CACHE_UNLOCK(cache);
2323 + return 0;
2324 +}
2325 +/* }}} */
2326 +
2327 +/* {{{ apc_cache_user_delete */
2328 +int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen)
2329 +{
2330 + slot_t** slot;
2331 +
2332 + CACHE_LOCK(cache);
2333 +
2334 + slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots];
2335 +
2336 + while (*slot) {
2337 + if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
2338 + remove_slot(cache, slot);
2339 + CACHE_UNLOCK(cache);
2340 + return 1;
2341 + }
2342 + slot = &(*slot)->next;
2343 + }
2344 +
2345 + CACHE_UNLOCK(cache);
2346 + return 0;
2347 +}
2348 +/* }}} */
2349 +
2350 +/* {{{ apc_cache_delete */
2351 +int apc_cache_delete(apc_cache_t* cache, char *filename, int filename_len)
2352 +{
2353 + slot_t** slot;
2354 + time_t t;
2355 + apc_cache_key_t key;
2356 +
2357 + TSRMLS_FETCH();
2358 +
2359 + t = apc_time();
2360 +
2361 + /* try to create a cache key; if we fail, give up on caching */
2362 + if (!apc_cache_make_file_key(&key, filename, PG(include_path), t TSRMLS_CC)) {
2363 + apc_wprint("Could not stat file %s, unable to delete from cache.", filename);
2364 + return -1;
2365 + }
2366 +
2367 + CACHE_LOCK(cache);
2368 +
2369 + if(key.type == APC_CACHE_KEY_FILE) slot = &cache->slots[hash(key) % cache->num_slots];
2370 + else slot = &cache->slots[string_nhash_8(key.data.fpfile.fullpath, key.data.fpfile.fullpath_len) % cache->num_slots];
2371 +
2372 + while(*slot) {
2373 + if(key.type == (*slot)->key.type) {
2374 + if(key.type == APC_CACHE_KEY_FILE) {
2375 + if(key_equals((*slot)->key.data.file, key.data.file)) {
2376 + remove_slot(cache, slot);
2377 + CACHE_UNLOCK(cache);
2378 + return 1;
2379 + }
2380 + } else { /* APC_CACHE_KEY_FPFILE */
2381 + if(!memcmp((*slot)->key.data.fpfile.fullpath, key.data.fpfile.fullpath, key.data.fpfile.fullpath_len+1)) {
2382 + remove_slot(cache, slot);
2383 + CACHE_UNLOCK(cache);
2384 + return 1;
2385 + }
2386 + }
2387 + }
2388 + slot = &(*slot)->next;
2389 + }
2390 +
2391 + CACHE_UNLOCK(cache);
2392 + return 0;
2393 +
2394 +}
2395 +/* }}} */
2396 +
2397 +/* {{{ apc_cache_release */
2398 +void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry)
2399 +{
2400 + CACHE_LOCK(cache);
2401 + entry->ref_count--;
2402 + CACHE_UNLOCK(cache);
2403 +}
2404 +/* }}} */
2405 +
2406 +/* {{{ apc_cache_make_file_key */
2407 +int apc_cache_make_file_key(apc_cache_key_t* key,
2408 + const char* filename,
2409 + const char* include_path,
2410 + time_t t
2411 + TSRMLS_DC)
2412 +{
2413 + struct stat *tmp_buf=NULL;
2414 + struct apc_fileinfo_t fileinfo = { {0}, };
2415 + int len;
2416 +
2417 + assert(key != NULL);
2418 +
2419 + if (!filename || !SG(request_info).path_translated) {
2420 +#ifdef __DEBUG_APC__
2421 + fprintf(stderr,"No filename and no path_translated - bailing\n");
2422 +#endif
2423 + return 0;
2424 + }
2425 +
2426 + len = strlen(filename);
2427 + if(APCG(fpstat)==0) {
2428 + if(IS_ABSOLUTE_PATH(filename,len)) {
2429 + key->data.fpfile.fullpath = filename;
2430 + key->data.fpfile.fullpath_len = len;
2431 + key->mtime = t;
2432 + key->type = APC_CACHE_KEY_FPFILE;
2433 + return 1;
2434 + } else if(APCG(canonicalize)) {
2435 + if (apc_search_paths(filename, include_path, &fileinfo) != 0) {
2436 + apc_wprint("apc failed to locate %s - bailing", filename);
2437 + return 0;
2438 + }
2439 +
2440 + if(!realpath(fileinfo.fullpath, APCG(canon_path))) {
2441 + apc_wprint("realpath failed to canonicalize %s - bailing", filename);
2442 + return 0;
2443 + }
2444 +
2445 + key->data.fpfile.fullpath = APCG(canon_path);
2446 + key->data.fpfile.fullpath_len = strlen(APCG(canon_path));
2447 + key->mtime = t;
2448 + key->type = APC_CACHE_KEY_FPFILE;
2449 + return 1;
2450 + }
2451 + /* fall through to stat mode */
2452 + }
2453 +
2454 + if(!strcmp(SG(request_info).path_translated, filename)) {
2455 + tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */
2456 + }
2457 + if(tmp_buf) {
2458 + fileinfo.st_buf.sb = *tmp_buf;
2459 + } else {
2460 + if (apc_search_paths(filename, include_path, &fileinfo) != 0) {
2461 +#ifdef __DEBUG_APC__
2462 + fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",filename,SG(request_info).path_translated);
2463 +#endif
2464 + return 0;
2465 + }
2466 + }
2467 +
2468 + if(APCG(max_file_size) < fileinfo.st_buf.sb.st_size) {
2469 +#ifdef __DEBUG_APC__
2470 + fprintf(stderr,"File is too big %s (%d - %ld) - bailing\n",filename,t,fileinfo.st_buf.sb.st_size);
2471 +#endif
2472 + return 0;
2473 + }
2474 +
2475 + /*
2476 + * This is a bit of a hack.
2477 + *
2478 + * Here I am checking to see if the file is at least 2 seconds old.
2479 + * The idea is that if the file is currently being written to then its
2480 + * mtime is going to match or at most be 1 second off of the current
2481 + * request time and we want to avoid caching files that have not been
2482 + * completely written. Of course, people should be using atomic
2483 + * mechanisms to push files onto live web servers, but adding this
2484 + * tiny safety is easier than educating the world. This is now
2485 + * configurable, but the default is still 2 seconds.
2486 + */
2487 + if(APCG(file_update_protection) && (t - fileinfo.st_buf.sb.st_mtime < APCG(file_update_protection)) && !APCG(force_file_update)) {
2488 +#ifdef __DEBUG_APC__
2489 + fprintf(stderr,"File is too new %s (%d - %d) - bailing\n",filename,t,fileinfo.st_buf.sb.st_mtime);
2490 +#endif
2491 + return 0;
2492 + }
2493 +
2494 + key->data.file.device = fileinfo.st_buf.sb.st_dev;
2495 + key->data.file.inode = fileinfo.st_buf.sb.st_ino;
2496 + /*
2497 + * If working with content management systems that like to munge the mtime,
2498 + * it might be appropriate to key off of the ctime to be immune to systems
2499 + * that try to backdate a template. If the mtime is set to something older
2500 + * than the previous mtime of a template we will obviously never see this
2501 + * "older" template. At some point the Smarty templating system did this.
2502 + * I generally disagree with using the ctime here because you lose the
2503 + * ability to warm up new content by saving it to a temporary file, hitting
2504 + * it once to cache it and then renaming it into its permanent location so
2505 + * set the apc.stat_ctime=true to enable this check.
2506 + */
2507 + if(APCG(stat_ctime)) {
2508 + key->mtime = (fileinfo.st_buf.sb.st_ctime > fileinfo.st_buf.sb.st_mtime) ? fileinfo.st_buf.sb.st_ctime : fileinfo.st_buf.sb.st_mtime;
2509 + } else {
2510 + key->mtime = fileinfo.st_buf.sb.st_mtime;
2511 + }
2512 + key->type = APC_CACHE_KEY_FILE;
2513 + return 1;
2514 +}
2515 +/* }}} */
2516 +
2517 +/* {{{ apc_cache_make_user_key */
2518 +int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t)
2519 +{
2520 + assert(key != NULL);
2521 +
2522 + if (!identifier)
2523 + return 0;
2524 +
2525 + key->data.user.identifier = identifier;
2526 + key->data.user.identifier_len = identifier_len;
2527 + key->mtime = t;
2528 + key->type = APC_CACHE_KEY_USER;
2529 + return 1;
2530 +}
2531 +/* }}} */
2532 +
2533 +/* {{{ apc_cache_make_file_entry */
2534 +apc_cache_entry_t* apc_cache_make_file_entry(const char* filename,
2535 + zend_op_array* op_array,
2536 + apc_function_t* functions,
2537 + apc_class_t* classes,
2538 + apc_context_t* ctxt)
2539 +{
2540 + apc_cache_entry_t* entry;
2541 + apc_pool* pool = ctxt->pool;
2542 +
2543 + entry = (apc_cache_entry_t*) apc_pool_alloc(pool, sizeof(apc_cache_entry_t));
2544 + if (!entry) return NULL;
2545 +
2546 + entry->data.file.filename = apc_pstrdup(filename, pool);
2547 + if(!entry->data.file.filename) {
2548 +#ifdef __DEBUG_APC__
2549 + fprintf(stderr,"apc_cache_make_file_entry: entry->data.file.filename is NULL - bailing\n");
2550 +#endif
2551 + return NULL;
2552 + }
2553 +#ifdef __DEBUG_APC__
2554 + fprintf(stderr,"apc_cache_make_file_entry: entry->data.file.filename is [%s]\n",entry->data.file.filename);
2555 +#endif
2556 + entry->data.file.op_array = op_array;
2557 + entry->data.file.functions = functions;
2558 + entry->data.file.classes = classes;
2559 +
2560 + entry->data.file.halt_offset = apc_file_halt_offset(filename);
2561 +
2562 + entry->type = APC_CACHE_ENTRY_FILE;
2563 + entry->ref_count = 0;
2564 + entry->mem_size = 0;
2565 + entry->pool = pool;
2566 + return entry;
2567 +}
2568 +/* }}} */
2569 +
2570 +/* {{{ apc_cache_store_zval */
2571 +zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt)
2572 +{
2573 + TSRMLS_FETCH();
2574 +
2575 + if (Z_TYPE_P(src) == IS_ARRAY) {
2576 + /* Maintain a list of zvals we've copied to properly handle recursive structures */
2577 + zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
2578 + dst = apc_copy_zval(dst, src, ctxt);
2579 + zend_hash_destroy(&APCG(copied_zvals));
2580 + APCG(copied_zvals).nTableSize=0;
2581 + } else {
2582 + dst = apc_copy_zval(dst, src, ctxt);
2583 + }
2584 +
2585 +
2586 + return dst;
2587 +}
2588 +/* }}} */
2589 +
2590 +/* {{{ apc_cache_fetch_zval */
2591 +zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_context_t* ctxt)
2592 +{
2593 + TSRMLS_FETCH();
2594 +
2595 + if (Z_TYPE_P(src) == IS_ARRAY) {
2596 + /* Maintain a list of zvals we've copied to properly handle recursive structures */
2597 + zend_hash_init(&APCG(copied_zvals), 0, NULL, NULL, 0);
2598 + dst = apc_copy_zval(dst, src, ctxt);
2599 + zend_hash_destroy(&APCG(copied_zvals));
2600 + APCG(copied_zvals).nTableSize=0;
2601 + } else {
2602 + dst = apc_copy_zval(dst, src, ctxt);
2603 + }
2604 +
2605 +
2606 + return dst;
2607 +}
2608 +/* }}} */
2609 +
2610 +/* {{{ apc_cache_make_user_entry */
2611 +apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval* val, apc_context_t* ctxt, const unsigned int ttl)
2612 +{
2613 + apc_cache_entry_t* entry;
2614 + apc_pool* pool = ctxt->pool;
2615 +
2616 + entry = (apc_cache_entry_t*) apc_pool_alloc(pool, sizeof(apc_cache_entry_t));
2617 + if (!entry) return NULL;
2618 +
2619 + entry->data.user.info = apc_pmemcpy(info, info_len+1, pool);
2620 + entry->data.user.info_len = info_len;
2621 + if(!entry->data.user.info) {
2622 + return NULL;
2623 + }
2624 + entry->data.user.val = apc_cache_store_zval(NULL, val, ctxt);
2625 + if(!entry->data.user.val) {
2626 + return NULL;
2627 + }
2628 + INIT_PZVAL(entry->data.user.val);
2629 + entry->data.user.ttl = ttl;
2630 + entry->type = APC_CACHE_ENTRY_USER;
2631 + entry->ref_count = 0;
2632 + entry->mem_size = 0;
2633 + entry->pool = pool;
2634 + return entry;
2635 +}
2636 +/* }}} */
2637 +
2638 +/* {{{ apc_cache_info */
2639 +apc_cache_info_t* apc_cache_info(apc_cache_t* cache, zend_bool limited)
2640 +{
2641 + apc_cache_info_t* info;
2642 + slot_t* p;
2643 + int i;
2644 +
2645 + TSRMLS_FETCH();
2646 +
2647 + if(!cache) return NULL;
2648 +
2649 + CACHE_LOCK(cache);
2650 +
2651 + info = (apc_cache_info_t*) apc_emalloc(sizeof(apc_cache_info_t));
2652 + if(!info) {
2653 + CACHE_UNLOCK(cache);
2654 + return NULL;
2655 + }
2656 + info->num_slots = cache->num_slots;
2657 + info->ttl = cache->ttl;
2658 + info->num_hits = cache->header->num_hits;
2659 + info->num_misses = cache->header->num_misses;
2660 + info->list = NULL;
2661 + info->deleted_list = NULL;
2662 + info->start_time = cache->header->start_time;
2663 + info->expunges = cache->header->expunges;
2664 + info->mem_size = cache->header->mem_size;
2665 + info->num_entries = cache->header->num_entries;
2666 + info->num_inserts = cache->header->num_inserts;
2667 +
2668 + if(!limited) {
2669 + /* For each hashtable slot */
2670 + for (i = 0; i < info->num_slots; i++) {
2671 + p = cache->slots[i];
2672 + for (; p != NULL; p = p->next) {
2673 + apc_cache_link_t* link = (apc_cache_link_t*) apc_emalloc(sizeof(apc_cache_link_t));
2674 +
2675 + if(p->value->type == APC_CACHE_ENTRY_FILE) {
2676 + if(p->key.type == APC_CACHE_KEY_FILE) {
2677 + link->data.file.device = p->key.data.file.device;
2678 + link->data.file.inode = p->key.data.file.inode;
2679 + link->data.file.filename = apc_xstrdup(p->value->data.file.filename, apc_emalloc);
2680 + } else { /* This is a no-stat fullpath file entry */
2681 + link->data.file.device = 0;
2682 + link->data.file.inode = 0;
2683 + link->data.file.filename = apc_xstrdup(p->key.data.fpfile.fullpath, apc_emalloc);
2684 + }
2685 + link->type = APC_CACHE_ENTRY_FILE;
2686 + if (APCG(file_md5)) {
2687 + link->data.file.md5 = emalloc(sizeof(p->key.md5));
2688 + memcpy(link->data.file.md5, p->key.md5, 16);
2689 + } else {
2690 + link->data.file.md5 = NULL;
2691 + }
2692 + } else if(p->value->type == APC_CACHE_ENTRY_USER) {
2693 + link->data.user.info = apc_xmemcpy(p->value->data.user.info, p->value->data.user.info_len+1, apc_emalloc);
2694 + link->data.user.ttl = p->value->data.user.ttl;
2695 + link->type = APC_CACHE_ENTRY_USER;
2696 + }
2697 + link->num_hits = p->num_hits;
2698 + link->mtime = p->key.mtime;
2699 + link->creation_time = p->creation_time;
2700 + link->deletion_time = p->deletion_time;
2701 + link->access_time = p->access_time;
2702 + link->ref_count = p->value->ref_count;
2703 + link->mem_size = p->value->mem_size;
2704 + link->next = info->list;
2705 + info->list = link;
2706 + }
2707 + }
2708 +
2709 + /* For each slot pending deletion */
2710 + for (p = cache->header->deleted_list; p != NULL; p = p->next) {
2711 + apc_cache_link_t* link = (apc_cache_link_t*) apc_emalloc(sizeof(apc_cache_link_t));
2712 +
2713 + if(p->value->type == APC_CACHE_ENTRY_FILE) {
2714 + if(p->key.type == APC_CACHE_KEY_FILE) {
2715 + link->data.file.device = p->key.data.file.device;
2716 + link->data.file.inode = p->key.data.file.inode;
2717 + link->data.file.filename = apc_xstrdup(p->value->data.file.filename, apc_emalloc);
2718 + } else { /* This is a no-stat fullpath file entry */
2719 + link->data.file.device = 0;
2720 + link->data.file.inode = 0;
2721 + link->data.file.filename = apc_xstrdup(p->key.data.fpfile.fullpath, apc_emalloc);
2722 + }
2723 + link->type = APC_CACHE_ENTRY_FILE;
2724 + if (APCG(file_md5)) {
2725 + link->data.file.md5 = emalloc(sizeof(p->key.md5));
2726 + memcpy(link->data.file.md5, p->key.md5, 16);
2727 + } else {
2728 + link->data.file.md5 = NULL;
2729 + }
2730 + } else if(p->value->type == APC_CACHE_ENTRY_USER) {
2731 + link->data.user.info = apc_xmemcpy(p->value->data.user.info, p->value->data.user.info_len+1, apc_emalloc);
2732 + link->data.user.ttl = p->value->data.user.ttl;
2733 + link->type = APC_CACHE_ENTRY_USER;
2734 + }
2735 + link->num_hits = p->num_hits;
2736 + link->mtime = p->key.mtime;
2737 + link->creation_time = p->creation_time;
2738 + link->deletion_time = p->deletion_time;
2739 + link->access_time = p->access_time;
2740 + link->ref_count = p->value->ref_count;
2741 + link->mem_size = p->value->mem_size;
2742 + link->next = info->deleted_list;
2743 + info->deleted_list = link;
2744 + }
2745 + }
2746 +
2747 + CACHE_UNLOCK(cache);
2748 + return info;
2749 +}
2750 +/* }}} */
2751 +
2752 +/* {{{ apc_cache_free_info */
2753 +void apc_cache_free_info(apc_cache_info_t* info)
2754 +{
2755 + apc_cache_link_t* p = info->list;
2756 + apc_cache_link_t* q = NULL;
2757 + while (p != NULL) {
2758 + q = p;
2759 + p = p->next;
2760 + if(q->type == APC_CACHE_ENTRY_FILE) {
2761 + if(q->data.file.md5) {
2762 + efree(q->data.file.md5);
2763 + }
2764 + apc_efree(q->data.file.filename);
2765 + }
2766 + else if(q->type == APC_CACHE_ENTRY_USER) apc_efree(q->data.user.info);
2767 + apc_efree(q);
2768 + }
2769 + p = info->deleted_list;
2770 + while (p != NULL) {
2771 + q = p;
2772 + p = p->next;
2773 + if(q->type == APC_CACHE_ENTRY_FILE) {
2774 + if(q->data.file.md5) {
2775 + efree(q->data.file.md5);
2776 + }
2777 + apc_efree(q->data.file.filename);
2778 + }
2779 + else if(q->type == APC_CACHE_ENTRY_USER) apc_efree(q->data.user.info);
2780 + apc_efree(q);
2781 + }
2782 + apc_efree(info);
2783 +}
2784 +/* }}} */
2785 +
2786 +/* {{{ apc_cache_unlock */
2787 +void apc_cache_unlock(apc_cache_t* cache)
2788 +{
2789 + CACHE_UNLOCK(cache);
2790 +}
2791 +/* }}} */
2792 +
2793 +/* {{{ apc_cache_busy */
2794 +zend_bool apc_cache_busy(apc_cache_t* cache)
2795 +{
2796 + return cache->header->busy;
2797 +}
2798 +/* }}} */
2799 +
2800 +/* {{{ apc_cache_is_last_key */
2801 +zend_bool apc_cache_is_last_key(apc_cache_t* cache, apc_cache_key_t* key, time_t t)
2802 +{
2803 + apc_keyid_t *lastkey = &cache->header->lastkey;
2804 + unsigned int keylen = key->data.user.identifier_len+1;
2805 + unsigned int h = string_nhash_8(key->data.user.identifier, keylen);
2806 +
2807 + /* unlocked reads, but we're not shooting for 100% success with this */
2808 + if(lastkey->h == h && keylen == lastkey->keylen) {
2809 + if(lastkey->mtime == t) {
2810 + /* potential cache slam */
2811 + apc_wprint("Potential cache slam averted for key '%s'", key->data.user.identifier);
2812 + return 1;
2813 + }
2814 + }
2815 +
2816 + return 0;
2817 +}
2818 +/* }}} */
2819 +
2820 +#if NONBLOCKING_LOCK_AVAILABLE
2821 +/* {{{ apc_cache_write_lock */
2822 +zend_bool apc_cache_write_lock(apc_cache_t* cache)
2823 +{
2824 + return apc_lck_nb_lock(cache->header->wrlock);
2825 +}
2826 +/* }}} */
2827 +
2828 +/* {{{ apc_cache_write_unlock */
2829 +void apc_cache_write_unlock(apc_cache_t* cache)
2830 +{
2831 + apc_lck_unlock(cache->header->wrlock);
2832 +}
2833 +/* }}} */
2834 +#endif
2835 +
2836 +/*
2837 + * Local variables:
2838 + * tab-width: 4
2839 + * c-basic-offset: 4
2840 + * End:
2841 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
2842 + * vim<600: expandtab sw=4 ts=4 sts=4
2843 + */
2844 diff -Naur php-5.3.1.orig/ext/apc/apc_cache.h php-5.3.1/ext/apc/apc_cache.h
2845 --- php-5.3.1.orig/ext/apc/apc_cache.h 1970-01-01 01:00:00.000000000 +0100
2846 +++ php-5.3.1/ext/apc/apc_cache.h 1970-01-01 10:13:08.000000000 +0100
2847 @@ -0,0 +1,378 @@
2848 +/*
2849 + +----------------------------------------------------------------------+
2850 + | APC |
2851 + +----------------------------------------------------------------------+
2852 + | Copyright (c) 2006-2008 The PHP Group |
2853 + +----------------------------------------------------------------------+
2854 + | This source file is subject to version 3.01 of the PHP license, |
2855 + | that is bundled with this package in the file LICENSE, and is |
2856 + | available through the world-wide-web at the following url: |
2857 + | http://www.php.net/license/3_01.txt. |
2858 + | If you did not receive a copy of the PHP license and are unable to |
2859 + | obtain it through the world-wide-web, please send a note to |
2860 + | license@php.net so we can mail you a copy immediately. |
2861 + +----------------------------------------------------------------------+
2862 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
2863 + | Rasmus Lerdorf <rasmus@php.net> |
2864 + +----------------------------------------------------------------------+
2865 +
2866 + This software was contributed to PHP by Community Connect Inc. in 2002
2867 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
2868 + Future revisions and derivatives of this source code must acknowledge
2869 + Community Connect Inc. as the original contributor of this module by
2870 + leaving this note intact in the source code.
2871 +
2872 + All other licensing and usage conditions are those of the PHP Group.
2873 +
2874 + */
2875 +
2876 +/* $Id: apc_cache.h 281919 2009-06-10 11:23:55Z gopalv $ */
2877 +
2878 +#ifndef APC_CACHE_H
2879 +#define APC_CACHE_H
2880 +
2881 +/*
2882 + * This module defines the shared memory file cache. Basically all of the
2883 + * logic for storing and retrieving cache entries lives here.
2884 + */
2885 +
2886 +#include "apc.h"
2887 +#include "apc_compile.h"
2888 +#include "apc_lock.h"
2889 +#include "apc_pool.h"
2890 +#include "apc_main.h"
2891 +
2892 +#define APC_CACHE_ENTRY_FILE 1
2893 +#define APC_CACHE_ENTRY_USER 2
2894 +
2895 +#define APC_CACHE_KEY_FILE 1
2896 +#define APC_CACHE_KEY_USER 2
2897 +#define APC_CACHE_KEY_FPFILE 3
2898 +
2899 +/* {{{ cache locking macros */
2900 +#define CACHE_LOCK(cache) { LOCK(cache->header->lock); cache->has_lock = 1; }
2901 +#define CACHE_UNLOCK(cache) { UNLOCK(cache->header->lock); cache->has_lock = 0; }
2902 +#define CACHE_SAFE_LOCK(cache) { if ((++cache->has_lock) == 1) LOCK(cache->header->lock); }
2903 +#define CACHE_SAFE_UNLOCK(cache) { if ((--cache->has_lock) == 0) UNLOCK(cache->header->lock); }
2904 +/* }}} */
2905 +
2906 +/* {{{ struct definition: apc_cache_key_t */
2907 +#define T apc_cache_t*
2908 +typedef struct apc_cache_t apc_cache_t; /* opaque cache type */
2909 +
2910 +typedef union _apc_cache_key_data_t {
2911 + struct {
2912 + dev_t device; /* the filesystem device */
2913 + ino_t inode; /* the filesystem inode */
2914 + } file;
2915 + struct {
2916 + const char *identifier;
2917 + int identifier_len;
2918 + } user;
2919 + struct {
2920 + const char *fullpath;
2921 + int fullpath_len;
2922 + } fpfile;
2923 +} apc_cache_key_data_t;
2924 +
2925 +typedef struct apc_cache_key_t apc_cache_key_t;
2926 +struct apc_cache_key_t {
2927 + apc_cache_key_data_t data;
2928 + time_t mtime; /* the mtime of this cached entry */
2929 + unsigned char type;
2930 + unsigned char md5[16]; /* md5 hash of the source file */
2931 +};
2932 +
2933 +
2934 +typedef struct apc_keyid_t apc_keyid_t;
2935 +
2936 +struct apc_keyid_t {
2937 + unsigned int h;
2938 + unsigned int keylen;
2939 + time_t mtime;
2940 +};
2941 +/* }}} */
2942 +
2943 +/* {{{ struct definition: apc_cache_entry_t */
2944 +typedef union _apc_cache_entry_value_t {
2945 + struct {
2946 + char *filename; /* absolute path to source file */
2947 + zend_op_array* op_array; /* op_array allocated in shared memory */
2948 + apc_function_t* functions; /* array of apc_function_t's */
2949 + apc_class_t* classes; /* array of apc_class_t's */
2950 + long halt_offset; /* value of __COMPILER_HALT_OFFSET__ for the file */
2951 + } file;
2952 + struct {
2953 + char *info;
2954 + int info_len;
2955 + zval *val;
2956 + unsigned int ttl;
2957 + } user;
2958 +} apc_cache_entry_value_t;
2959 +
2960 +typedef struct apc_cache_entry_t apc_cache_entry_t;
2961 +struct apc_cache_entry_t {
2962 + apc_cache_entry_value_t data;
2963 + unsigned char type;
2964 + int ref_count;
2965 + size_t mem_size;
2966 + apc_pool *pool;
2967 +};
2968 +/* }}} */
2969 +
2970 +/*
2971 + * apc_cache_create creates the shared memory compiler cache. This function
2972 + * should be called just once (ideally in the web server parent process, e.g.
2973 + * in apache), otherwise you will end up with multiple caches (which won't
2974 + * necessarily break anything). Returns a pointer to the cache object.
2975 + *
2976 + * size_hint is a "hint" at the total number of source files that will be
2977 + * cached. It determines the physical size of the hash table. Passing 0 for
2978 + * this argument will use a reasonable default value.
2979 + *
2980 + * gc_ttl is the maximum time a cache entry may speed on the garbage
2981 + * collection list. This is basically a work around for the inherent
2982 + * unreliability of our reference counting mechanism (see apc_cache_release).
2983 + *
2984 + * ttl is the maximum time a cache entry can idle in a slot in case the slot
2985 + * is needed. This helps in cleaning up the cache and ensuring that entries
2986 + * hit frequently stay cached and ones not hit very often eventually disappear.
2987 + */
2988 +extern T apc_cache_create(int size_hint, int gc_ttl, int ttl);
2989 +
2990 +/*
2991 + * apc_cache_destroy releases any OS resources associated with a cache object.
2992 + * Under apache, this function can be safely called by the child processes
2993 + * when they exit.
2994 + */
2995 +extern void apc_cache_destroy(T cache);
2996 +
2997 +/*
2998 + * apc_cache_clear empties a cache. This can safely be called at any time,
2999 + * even while other server processes are executing cached source files.
3000 + */
3001 +extern void apc_cache_clear(T cache);
3002 +
3003 +/*
3004 + * apc_cache_insert adds an entry to the cache, using a filename as a key.
3005 + * Internally, the filename is translated to a canonical representation, so
3006 + * that relative and absolute filenames will map to a single key. Returns
3007 + * non-zero if the file was successfully inserted, 0 otherwise. If 0 is
3008 + * returned, the caller must free the cache entry by calling
3009 + * apc_cache_free_entry (see below).
3010 + *
3011 + * key is the value created by apc_cache_make_file_key for file keys.
3012 + *
3013 + * value is a cache entry returned by apc_cache_make_entry (see below).
3014 + */
3015 +extern int apc_cache_insert(T cache, apc_cache_key_t key,
3016 + apc_cache_entry_t* value, apc_context_t* ctxt, time_t t);
3017 +
3018 +extern int apc_cache_user_insert(T cache, apc_cache_key_t key,
3019 + apc_cache_entry_t* value, apc_context_t* ctxt, time_t t, int exclusive TSRMLS_DC);
3020 +
3021 +extern int *apc_cache_insert_mult(apc_cache_t* cache, apc_cache_key_t* keys,
3022 + apc_cache_entry_t** values, apc_context_t *ctxt, time_t t, int num_entries);
3023 +
3024 +/*
3025 + * apc_cache_find searches for a cache entry by filename, and returns a
3026 + * pointer to the entry if found, NULL otherwise.
3027 + *
3028 + * key is a value created by apc_cache_make_file_key for file keys.
3029 + */
3030 +extern apc_cache_entry_t* apc_cache_find(T cache, apc_cache_key_t key, time_t t);
3031 +
3032 +/*
3033 + * apc_cache_user_find searches for a cache entry by its hashed identifier,
3034 + * and returns a pointer to the entry if found, NULL otherwise.
3035 + *
3036 + */
3037 +extern apc_cache_entry_t* apc_cache_user_find(T cache, char* strkey, int keylen, time_t t);
3038 +
3039 +/*
3040 + * apc_cache_delete and apc_cache_user_delete finds an entry in the cache and deletes it.
3041 + */
3042 +extern int apc_cache_delete(apc_cache_t* cache, char *filename, int filename_len);
3043 +extern int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen);
3044 +
3045 +/* apc_cach_fetch_zval takes a zval in the cache and reconstructs a runtime
3046 + * zval from it.
3047 + *
3048 + */
3049 +zval* apc_cache_fetch_zval(zval* dst, const zval* src, apc_context_t* ctxt);
3050 +
3051 +/*
3052 + * apc_cache_release decrements the reference count associated with a cache
3053 + * entry. Calling apc_cache_find automatically increments the reference count,
3054 + * and this function must be called post-execution to return the count to its
3055 + * original value. Failing to do so will prevent the entry from being
3056 + * garbage-collected.
3057 + *
3058 + * entry is the cache entry whose ref count you want to decrement.
3059 + */
3060 +extern void apc_cache_release(T cache, apc_cache_entry_t* entry);
3061 +
3062 +/*
3063 + * apc_cache_make_file_key creates a key object given a relative or absolute
3064 + * filename and an optional list of auxillary paths to search. include_path is
3065 + * searched if the filename cannot be found relative to the current working
3066 + * directory.
3067 + *
3068 + * key points to caller-allocated storage (must not be null).
3069 + *
3070 + * filename is the path to the source file.
3071 + *
3072 + * include_path is a colon-separated list of directories to search.
3073 + *
3074 + * and finally we pass in the current request time so we can avoid
3075 + * caching files with a current mtime which tends to indicate that
3076 + * they are still being written to.
3077 + */
3078 +extern int apc_cache_make_file_key(apc_cache_key_t* key,
3079 + const char* filename,
3080 + const char* include_path,
3081 + time_t t
3082 + TSRMLS_DC);
3083 +
3084 +/*
3085 + * apc_cache_make_file_entry creates an apc_cache_entry_t object given a filename
3086 + * and the compilation results returned by the PHP compiler.
3087 + */
3088 +extern apc_cache_entry_t* apc_cache_make_file_entry(const char* filename,
3089 + zend_op_array* op_array,
3090 + apc_function_t* functions,
3091 + apc_class_t* classes,
3092 + apc_context_t* ctxt);
3093 +
3094 +
3095 +zend_bool apc_compile_cache_entry(apc_cache_key_t key, zend_file_handle* h, int type, time_t t, zend_op_array** op_array_pp, apc_cache_entry_t** cache_entry_pp TSRMLS_DC);
3096 +
3097 +/*
3098 + * apc_cache_make_user_entry creates an apc_cache_entry_t object given an info string
3099 + * and the zval to be stored.
3100 + */
3101 +extern apc_cache_entry_t* apc_cache_make_user_entry(const char* info, int info_len, const zval *val, apc_context_t* ctxt, const unsigned int ttl);
3102 +
3103 +extern int apc_cache_make_user_key(apc_cache_key_t* key, char* identifier, int identifier_len, const time_t t);
3104 +
3105 +/* {{{ struct definition: apc_cache_link_data_t */
3106 +typedef union _apc_cache_link_data_t {
3107 + struct {
3108 + char *filename;
3109 + dev_t device;
3110 + ino_t inode;
3111 + unsigned char *md5;
3112 + } file;
3113 + struct {
3114 + char *info;
3115 + unsigned int ttl;
3116 + } user;
3117 +} apc_cache_link_data_t;
3118 +/* }}} */
3119 +
3120 +/* {{{ struct definition: apc_cache_link_t */
3121 +typedef struct apc_cache_link_t apc_cache_link_t;
3122 +struct apc_cache_link_t {
3123 + apc_cache_link_data_t data;
3124 + unsigned char type;
3125 + unsigned long num_hits;
3126 + time_t mtime;
3127 + time_t creation_time;
3128 + time_t deletion_time;
3129 + time_t access_time;
3130 + int ref_count;
3131 + size_t mem_size;
3132 + apc_cache_link_t* next;
3133 +};
3134 +/* }}} */
3135 +
3136 +/* {{{ struct definition: apc_cache_info_t */
3137 +typedef struct apc_cache_info_t apc_cache_info_t;
3138 +struct apc_cache_info_t {
3139 + int num_slots;
3140 + unsigned long num_hits;
3141 + unsigned long num_misses;
3142 + unsigned long num_inserts;
3143 + unsigned long expunges;
3144 + int ttl;
3145 + apc_cache_link_t* list;
3146 + apc_cache_link_t* deleted_list;
3147 + time_t start_time;
3148 + int num_entries;
3149 + size_t mem_size;
3150 +};
3151 +/* }}} */
3152 +
3153 +/* {{{ struct definition: slot_t */
3154 +typedef struct slot_t slot_t;
3155 +struct slot_t {
3156 + apc_cache_key_t key; /* slot key */
3157 + apc_cache_entry_t* value; /* slot value */
3158 + slot_t* next; /* next slot in linked list */
3159 + unsigned long num_hits; /* number of hits to this bucket */
3160 + time_t creation_time; /* time slot was initialized */
3161 + time_t deletion_time; /* time slot was removed from cache */
3162 + time_t access_time; /* time slot was last accessed */
3163 +};
3164 +/* }}} */
3165 +
3166 +/* {{{ struct definition: cache_header_t
3167 + Any values that must be shared among processes should go in here. */
3168 +typedef struct cache_header_t cache_header_t;
3169 +struct cache_header_t {
3170 + apc_lck_t lock; /* read/write lock (exclusive blocking cache lock) */
3171 + apc_lck_t wrlock; /* write lock (non-blocking used to prevent cache slams) */
3172 + unsigned long num_hits; /* total successful hits in cache */
3173 + unsigned long num_misses; /* total unsuccessful hits in cache */
3174 + unsigned long num_inserts; /* total successful inserts in cache */
3175 + unsigned long expunges; /* total number of expunges */
3176 + slot_t* deleted_list; /* linked list of to-be-deleted slots */
3177 + time_t start_time; /* time the above counters were reset */
3178 + zend_bool busy; /* Flag to tell clients when we are busy cleaning the cache */
3179 + int num_entries; /* Statistic on the number of entries */
3180 + size_t mem_size; /* Statistic on the memory size used by this cache */
3181 + apc_keyid_t lastkey; /* the key that is being inserted (user cache) */
3182 +};
3183 +/* }}} */
3184 +
3185 +typedef void (*apc_expunge_cb_t)(T cache, size_t n);
3186 +
3187 +/* {{{ struct definition: apc_cache_t */
3188 +struct apc_cache_t {
3189 + void* shmaddr; /* process (local) address of shared cache */
3190 + cache_header_t* header; /* cache header (stored in SHM) */
3191 + slot_t** slots; /* array of cache slots (stored in SHM) */
3192 + int num_slots; /* number of slots in cache */
3193 + int gc_ttl; /* maximum time on GC list for a slot */
3194 + int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */
3195 + apc_expunge_cb_t expunge_cb; /* cache specific expunge callback to free up sma memory */
3196 + uint has_lock; /* flag for possible recursive locks within the same process */
3197 +};
3198 +/* }}} */
3199 +
3200 +extern apc_cache_info_t* apc_cache_info(T cache, zend_bool limited);
3201 +extern void apc_cache_free_info(apc_cache_info_t* info);
3202 +extern void apc_cache_unlock(apc_cache_t* cache);
3203 +extern zend_bool apc_cache_busy(apc_cache_t* cache);
3204 +extern zend_bool apc_cache_write_lock(apc_cache_t* cache);
3205 +extern void apc_cache_write_unlock(apc_cache_t* cache);
3206 +extern zend_bool apc_cache_is_last_key(apc_cache_t* cache, apc_cache_key_t* key, time_t t);
3207 +
3208 +/* used by apc_rfc1867 to update data in-place - not to be used elsewhere */
3209 +
3210 +typedef int (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data);
3211 +extern int _apc_cache_user_update(apc_cache_t* cache, char *strkey, int keylen,
3212 + apc_cache_updater_t updater, void* data TSRMLS_DC);
3213 +
3214 +
3215 +#undef T
3216 +#endif
3217 +
3218 +/*
3219 + * Local variables:
3220 + * tab-width: 4
3221 + * c-basic-offset: 4
3222 + * End:
3223 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
3224 + * vim<600: expandtab sw=4 ts=4 sts=4
3225 + */
3226 diff -Naur php-5.3.1.orig/ext/apc/apc_compile.c php-5.3.1/ext/apc/apc_compile.c
3227 --- php-5.3.1.orig/ext/apc/apc_compile.c 1970-01-01 01:00:00.000000000 +0100
3228 +++ php-5.3.1/ext/apc/apc_compile.c 1970-01-01 10:13:08.000000000 +0100
3229 @@ -0,0 +1,1775 @@
3230 +/*
3231 + +----------------------------------------------------------------------+
3232 + | APC |
3233 + +----------------------------------------------------------------------+
3234 + | Copyright (c) 2006-2008 The PHP Group |
3235 + +----------------------------------------------------------------------+
3236 + | This source file is subject to version 3.01 of the PHP license, |
3237 + | that is bundled with this package in the file LICENSE, and is |
3238 + | available through the world-wide-web at the following url: |
3239 + | http://www.php.net/license/3_01.txt. |
3240 + | If you did not receive a copy of the PHP license and are unable to |
3241 + | obtain it through the world-wide-web, please send a note to |
3242 + | license@php.net so we can mail you a copy immediately. |
3243 + +----------------------------------------------------------------------+
3244 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
3245 + | Rasmus Lerdorf <rasmus@php.net> |
3246 + | Arun C. Murthy <arunc@yahoo-inc.com> |
3247 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
3248 + +----------------------------------------------------------------------+
3249 +
3250 + This software was contributed to PHP by Community Connect Inc. in 2002
3251 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
3252 + Future revisions and derivatives of this source code must acknowledge
3253 + Community Connect Inc. as the original contributor of this module by
3254 + leaving this note intact in the source code.
3255 +
3256 + All other licensing and usage conditions are those of the PHP Group.
3257 +
3258 + */
3259 +
3260 +/* $Id: apc_compile.c 284580 2009-07-22 06:05:31Z kalle $ */
3261 +
3262 +#include "apc_compile.h"
3263 +#include "apc_globals.h"
3264 +#include "apc_zend.h"
3265 +#include "ext/standard/php_var.h"
3266 +#include "ext/standard/php_smart_str.h"
3267 +
3268 +#ifndef IS_CONSTANT_TYPE_MASK
3269 +#define IS_CONSTANT_TYPE_MASK (~IS_CONSTANT_INDEX)
3270 +#endif
3271 +
3272 +typedef void* (*ht_copy_fun_t)(void*, void*, apc_context_t*);
3273 +//typedef void (*ht_free_fun_t)(void*, apc_context_t*);
3274 +typedef int (*ht_check_copy_fun_t)(Bucket*, va_list);
3275 +
3276 +typedef void (*ht_fixup_fun_t)(Bucket*, zend_class_entry*, zend_class_entry*);
3277 +
3278 +#define CHECK(p) { if ((p) == NULL) return NULL; }
3279 +
3280 +/* {{{ internal function declarations */
3281 +
3282 +static zend_function* my_bitwise_copy_function(zend_function*, zend_function*, apc_context_t*);
3283 +
3284 +/*
3285 + * The "copy" functions perform deep-copies on a particular data structure
3286 + * (passed as the second argument). They also optionally allocate space for
3287 + * the destination data structure if the first argument is null.
3288 + */
3289 +static zval** my_copy_zval_ptr(zval**, const zval**, apc_context_t*);
3290 +static zval* my_copy_zval(zval*, const zval*, apc_context_t*);
3291 +static znode* my_copy_znode(znode*, znode*, apc_context_t*);
3292 +static zend_op* my_copy_zend_op(zend_op*, zend_op*, apc_context_t*);
3293 +static zend_function* my_copy_function(zend_function*, zend_function*, apc_context_t*);
3294 +static zend_function_entry* my_copy_function_entry(zend_function_entry*, const zend_function_entry*, apc_context_t*);
3295 +static zend_class_entry* my_copy_class_entry(zend_class_entry*, zend_class_entry*, apc_context_t*);
3296 +static HashTable* my_copy_hashtable_ex(HashTable*, HashTable*, ht_copy_fun_t, int, apc_context_t*, ht_check_copy_fun_t, ...);
3297 +#define my_copy_hashtable( dst, src, copy_fn, holds_ptr, ctxt) \
3298 + my_copy_hashtable_ex(dst, src, copy_fn, holds_ptr, ctxt, NULL)
3299 +static HashTable* my_copy_static_variables(zend_op_array* src, apc_context_t*);
3300 +static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_context_t*);
3301 +static zend_arg_info* my_copy_arg_info_array(zend_arg_info*, const zend_arg_info*, uint, apc_context_t*);
3302 +static zend_arg_info* my_copy_arg_info(zend_arg_info*, const zend_arg_info*, apc_context_t*);
3303 +
3304 +/*
3305 + * The "fixup" functions need for ZEND_ENGINE_2
3306 + */
3307 +static void my_fixup_function( Bucket *p, zend_class_entry *src, zend_class_entry *dst );
3308 +static void my_fixup_hashtable( HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst );
3309 +/* my_fixup_function_for_execution is the same as my_fixup_function
3310 + * but named differently for clarity
3311 + */
3312 +#define my_fixup_function_for_execution my_fixup_function
3313 +
3314 +#ifdef ZEND_ENGINE_2_2
3315 +static void my_fixup_property_info( Bucket *p, zend_class_entry *src, zend_class_entry *dst );
3316 +#define my_fixup_property_info_for_execution my_fixup_property_info
3317 +#endif
3318 +
3319 +/*
3320 + * These functions return "1" if the member/function is
3321 + * defined/overridden in the 'current' class and not inherited.
3322 + */
3323 +static int my_check_copy_function(Bucket* src, va_list args);
3324 +static int my_check_copy_default_property(Bucket* p, va_list args);
3325 +static int my_check_copy_property_info(Bucket* src, va_list args);
3326 +static int my_check_copy_static_member(Bucket* src, va_list args);
3327 +
3328 +/* }}} */
3329 +
3330 +/* {{{ check_op_array_integrity */
3331 +#if 0
3332 +static void check_op_array_integrity(zend_op_array* src)
3333 +{
3334 + int i, j;
3335 +
3336 + /* These sorts of checks really aren't particularly effective, but they
3337 + * can provide a welcome sanity check when debugging. Just don't enable
3338 + * for production use! */
3339 +
3340 + assert(src->refcount != NULL);
3341 + assert(src->opcodes != NULL);
3342 + assert(src->last > 0);
3343 +
3344 + for (i = 0; i < src->last; i++) {
3345 + zend_op* op = &src->opcodes[i];
3346 + znode* nodes[] = { &op->result, &op->op1, &op->op2 };
3347 + for (j = 0; j < 3; j++) {
3348 + assert(nodes[j]->op_type == IS_CONST ||
3349 + nodes[j]->op_type == IS_VAR ||
3350 + nodes[j]->op_type == IS_TMP_VAR ||
3351 + nodes[j]->op_type == IS_UNUSED);
3352 +
3353 + if (nodes[j]->op_type == IS_CONST) {
3354 + int type = nodes[j]->u.constant.type;
3355 + assert(type == IS_RESOURCE ||
3356 + type == IS_BOOL ||
3357 + type == IS_LONG ||
3358 + type == IS_DOUBLE ||
3359 + type == IS_NULL ||
3360 + type == IS_CONSTANT ||
3361 + type == IS_STRING ||
3362 + type == FLAG_IS_BC ||
3363 + type == IS_ARRAY ||
3364 + type == IS_CONSTANT_ARRAY ||
3365 + type == IS_OBJECT);
3366 + }
3367 + }
3368 + }
3369 +}
3370 +#endif
3371 +/* }}} */
3372 +
3373 +/* {{{ my_bitwise_copy_function */
3374 +static zend_function* my_bitwise_copy_function(zend_function* dst, zend_function* src, apc_context_t* ctxt)
3375 +{
3376 + apc_pool* pool = ctxt->pool;
3377 +
3378 + assert(src != NULL);
3379 +
3380 + if (!dst) {
3381 + CHECK(dst = (zend_function*) apc_pool_alloc(pool, sizeof(src[0])));
3382 + }
3383 +
3384 + /* We only need to do a bitwise copy */
3385 + memcpy(dst, src, sizeof(src[0]));
3386 +
3387 + return dst;
3388 +}
3389 +/* }}} */
3390 +
3391 +/* {{{ my_copy_zval_ptr */
3392 +static zval** my_copy_zval_ptr(zval** dst, const zval** src, apc_context_t* ctxt)
3393 +{
3394 + zval* dst_new;
3395 + apc_pool* pool = ctxt->pool;
3396 + int usegc = (ctxt->copy == APC_COPY_OUT_OPCODE) || (ctxt->copy == APC_COPY_OUT_USER);
3397 +
3398 + assert(src != NULL);
3399 +
3400 + if (!dst) {
3401 + CHECK(dst = (zval**) apc_pool_alloc(pool, sizeof(zval*)));
3402 + }
3403 +
3404 + if(usegc) {
3405 + ALLOC_ZVAL(dst[0]);
3406 + CHECK(dst[0]);
3407 + } else {
3408 + CHECK((dst[0] = (zval*) apc_pool_alloc(pool, sizeof(zval))));
3409 + }
3410 +
3411 + CHECK((dst_new = my_copy_zval(*dst, *src, ctxt)));
3412 +
3413 + if(dst_new != *dst) {
3414 + if(usegc) {
3415 + TSRMLS_FETCH();
3416 + FREE_ZVAL(dst[0]);
3417 + }
3418 + *dst = dst_new;
3419 + }
3420 +
3421 + return dst;
3422 +}
3423 +/* }}} */
3424 +
3425 +/* {{{ my_serialize_object */
3426 +static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt)
3427 +{
3428 + smart_str buf = {0};
3429 + php_serialize_data_t var_hash;
3430 + apc_pool* pool = ctxt->pool;
3431 +
3432 + TSRMLS_FETCH();
3433 +
3434 + PHP_VAR_SERIALIZE_INIT(var_hash);
3435 + php_var_serialize(&buf, (zval**)&src, &var_hash TSRMLS_CC);
3436 + PHP_VAR_SERIALIZE_DESTROY(var_hash);
3437 +
3438 + if(buf.c) {
3439 + dst->type = src->type & ~IS_CONSTANT_INDEX;
3440 + dst->value.str.len = buf.len;
3441 + CHECK(dst->value.str.val = apc_pmemcpy(buf.c, buf.len+1, pool));
3442 + dst->type = src->type;
3443 + smart_str_free(&buf);
3444 + }
3445 +
3446 + return dst;
3447 +}
3448 +/* }}} */
3449 +
3450 +/* {{{ my_unserialize_object */
3451 +static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt)
3452 +{
3453 + php_unserialize_data_t var_hash;
3454 + const unsigned char *p = (unsigned char*)Z_STRVAL_P(src);
3455 +
3456 + TSRMLS_FETCH();
3457 +
3458 + PHP_VAR_UNSERIALIZE_INIT(var_hash);
3459 + if(!php_var_unserialize(&dst, &p, p + Z_STRLEN_P(src), &var_hash TSRMLS_CC)) {
3460 + PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
3461 + zval_dtor(dst);
3462 + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - Z_STRVAL_P(src)), Z_STRLEN_P(src));
3463 + dst->type = IS_NULL;
3464 + }
3465 + PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
3466 + return dst;
3467 +}
3468 +/* }}} */
3469 +
3470 +/* {{{ my_copy_zval */
3471 +static zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt)
3472 +{
3473 + zval **tmp;
3474 + apc_pool* pool = ctxt->pool;
3475 + TSRMLS_FETCH();
3476 +
3477 + assert(dst != NULL);
3478 + assert(src != NULL);
3479 +
3480 + memcpy(dst, src, sizeof(src[0]));
3481 +
3482 + if(APCG(copied_zvals).nTableSize) {
3483 + if(zend_hash_index_find(&APCG(copied_zvals), (ulong)src, (void**)&tmp) == SUCCESS) {
3484 + if(Z_ISREF_P((zval*)src)) {
3485 + Z_SET_ISREF_PP(tmp);
3486 + }
3487 + Z_ADDREF_PP(tmp);
3488 + return *tmp;
3489 + }
3490 +
3491 + zend_hash_index_update(&APCG(copied_zvals), (ulong)src, (void**)&dst, sizeof(zval*), NULL);
3492 + }
3493 +
3494 +
3495 + if(ctxt->copy == APC_COPY_OUT_USER || ctxt->copy == APC_COPY_IN_USER) {
3496 + /* deep copies are refcount(1), but moved up for recursive
3497 + * arrays, which end up being add_ref'd during its copy. */
3498 + Z_SET_REFCOUNT_P(dst, 1);
3499 + Z_UNSET_ISREF_P(dst);
3500 + } else {
3501 + /* code uses refcount=2 for consts */
3502 + Z_SET_REFCOUNT_P(dst, Z_REFCOUNT_P((zval*)src));
3503 + Z_SET_ISREF_TO_P(dst, Z_ISREF_P((zval*)src));
3504 + }
3505 +
3506 + switch (src->type & IS_CONSTANT_TYPE_MASK) {
3507 + case IS_RESOURCE:
3508 + case IS_BOOL:
3509 + case IS_LONG:
3510 + case IS_DOUBLE:
3511 + case IS_NULL:
3512 + break;
3513 +
3514 + case IS_CONSTANT:
3515 + case IS_STRING:
3516 + if (src->value.str.val) {
3517 + CHECK(dst->value.str.val = apc_pmemcpy(src->value.str.val,
3518 + src->value.str.len+1,
3519 + pool));
3520 + }
3521 + break;
3522 +
3523 + case IS_ARRAY:
3524 + case IS_CONSTANT_ARRAY:
3525 +
3526 + CHECK(dst->value.ht =
3527 + my_copy_hashtable(NULL,
3528 + src->value.ht,
3529 + (ht_copy_fun_t) my_copy_zval_ptr,
3530 + 1,
3531 + ctxt));
3532 + break;
3533 +
3534 + case IS_OBJECT:
3535 +
3536 + dst->type = IS_NULL;
3537 + if(ctxt->copy == APC_COPY_IN_USER) {
3538 + dst = my_serialize_object(dst, src, ctxt);
3539 + } else if(ctxt->copy == APC_COPY_OUT_USER) {
3540 + dst = my_unserialize_object(dst, src, ctxt);
3541 + }
3542 + break;
3543 +
3544 + default:
3545 + assert(0);
3546 + }
3547 +
3548 + return dst;
3549 +}
3550 +/* }}} */
3551 +
3552 +/* {{{ my_copy_znode */
3553 +static znode* my_copy_znode(znode* dst, znode* src, apc_context_t* ctxt)
3554 +{
3555 + assert(dst != NULL);
3556 + assert(src != NULL);
3557 +
3558 + memcpy(dst, src, sizeof(src[0]));
3559 +
3560 +#ifdef IS_CV
3561 + assert(dst ->op_type == IS_CONST ||
3562 + dst ->op_type == IS_VAR ||
3563 + dst ->op_type == IS_CV ||
3564 + dst ->op_type == IS_TMP_VAR ||
3565 + dst ->op_type == IS_UNUSED);
3566 +#else
3567 + assert(dst ->op_type == IS_CONST ||
3568 + dst ->op_type == IS_VAR ||
3569 + dst ->op_type == IS_TMP_VAR ||
3570 + dst ->op_type == IS_UNUSED);
3571 +#endif
3572 +
3573 + if (src->op_type == IS_CONST) {
3574 + if(!my_copy_zval(&dst->u.constant, &src->u.constant, ctxt)) {
3575 + return NULL;
3576 + }
3577 + }
3578 +
3579 + return dst;
3580 +}
3581 +/* }}} */
3582 +
3583 +/* {{{ my_copy_zend_op */
3584 +static zend_op* my_copy_zend_op(zend_op* dst, zend_op* src, apc_context_t* ctxt)
3585 +{
3586 + assert(dst != NULL);
3587 + assert(src != NULL);
3588 +
3589 + memcpy(dst, src, sizeof(src[0]));
3590 +
3591 + CHECK(my_copy_znode(&dst->result, &src->result, ctxt));
3592 + CHECK(my_copy_znode(&dst->op1, &src->op1, ctxt));
3593 + CHECK(my_copy_znode(&dst->op2, &src->op2, ctxt));
3594 +
3595 + return dst;
3596 +}
3597 +/* }}} */
3598 +
3599 +/* {{{ my_copy_function */
3600 +static zend_function* my_copy_function(zend_function* dst, zend_function* src, apc_context_t* ctxt)
3601 +{
3602 + TSRMLS_FETCH();
3603 +
3604 + assert(src != NULL);
3605 +
3606 + CHECK(dst = my_bitwise_copy_function(dst, src, ctxt));
3607 +
3608 + switch (src->type) {
3609 + case ZEND_INTERNAL_FUNCTION:
3610 + case ZEND_OVERLOADED_FUNCTION:
3611 + /* shallow copy because op_array is internal */
3612 + dst->op_array = src->op_array;
3613 + break;
3614 +
3615 + case ZEND_USER_FUNCTION:
3616 + case ZEND_EVAL_CODE:
3617 + CHECK(apc_copy_op_array(&dst->op_array,
3618 + &src->op_array,
3619 + ctxt TSRMLS_CC));
3620 + break;
3621 +
3622 + default:
3623 + assert(0);
3624 + }
3625 + /*
3626 + * op_array bitwise copying overwrites what ever you modified
3627 + * before apc_copy_op_array - which is why this code is outside
3628 + * my_bitwise_copy_function.
3629 + */
3630 +
3631 + /* zend_do_inheritance will re-look this up, because the pointers
3632 + * in prototype are from a function table of another class. It just
3633 + * helps if that one is from EG(class_table).
3634 + */
3635 + dst->common.prototype = NULL;
3636 +
3637 + /* once a method is marked as ZEND_ACC_IMPLEMENTED_ABSTRACT then you
3638 + * have to carry around a prototype. Thankfully zend_do_inheritance
3639 + * sets this properly as well
3640 + */
3641 + dst->common.fn_flags = src->common.fn_flags & (~ZEND_ACC_IMPLEMENTED_ABSTRACT);
3642 +
3643 +
3644 + return dst;
3645 +}
3646 +/* }}} */
3647 +
3648 +/* {{{ my_copy_function_entry */
3649 +static zend_function_entry* my_copy_function_entry(zend_function_entry* dst, const zend_function_entry* src, apc_context_t* ctxt)
3650 +{
3651 + assert(src != NULL);
3652 +
3653 + if (!dst) {
3654 + CHECK(dst = (zend_function_entry*) apc_pool_alloc(ctxt->pool, sizeof(src[0])));
3655 + }
3656 +
3657 + /* Start with a bitwise copy */
3658 + memcpy(dst, src, sizeof(src[0]));
3659 +
3660 + dst->fname = NULL;
3661 + dst->arg_info = NULL;
3662 +
3663 + if (src->fname) {
3664 + CHECK((dst->fname = apc_pstrdup(src->fname, ctxt->pool)));
3665 + }
3666 +
3667 + if (src->arg_info) {
3668 + CHECK((dst->arg_info = my_copy_arg_info_array(NULL,
3669 + src->arg_info,
3670 + src->num_args,
3671 + ctxt)));
3672 + }
3673 +
3674 + return dst;
3675 +}
3676 +/* }}} */
3677 +
3678 +/* {{{ my_copy_property_info */
3679 +static zend_property_info* my_copy_property_info(zend_property_info* dst, zend_property_info* src, apc_context_t* ctxt)
3680 +{
3681 + apc_pool* pool = ctxt->pool;
3682 +
3683 + assert(src != NULL);
3684 +
3685 + if (!dst) {
3686 + CHECK(dst = (zend_property_info*) apc_pool_alloc(pool, sizeof(*src)));
3687 + }
3688 +
3689 + /* Start with a bitwise copy */
3690 + memcpy(dst, src, sizeof(*src));
3691 +
3692 + dst->name = NULL;
3693 +#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0
3694 + dst->doc_comment = NULL;
3695 +#endif
3696 +
3697 + if (src->name) {
3698 + /* private members are stored inside property_info as a mangled
3699 + * string of the form:
3700 + * \0<classname>\0<membername>\0
3701 + */
3702 + CHECK((dst->name = apc_pmemcpy(src->name, src->name_length+1, pool)));
3703 + }
3704 +
3705 +#if defined(ZEND_ENGINE_2) && PHP_MINOR_VERSION > 0
3706 + if (src->doc_comment) {
3707 + CHECK((dst->doc_comment = apc_pmemcpy(src->doc_comment, src->doc_comment_len+1, pool)));
3708 + }
3709 +#endif
3710 +
3711 + return dst;
3712 +}
3713 +/* }}} */
3714 +
3715 +/* {{{ my_copy_property_info_for_execution */
3716 +static zend_property_info* my_copy_property_info_for_execution(zend_property_info* dst, zend_property_info* src, apc_context_t* ctxt)
3717 +{
3718 + assert(src != NULL);
3719 +
3720 + if (!dst) {
3721 + CHECK(dst = (zend_property_info*) apc_pool_alloc(ctxt->pool, (sizeof(*src))));
3722 + }
3723 +
3724 + /* We need only a shallow copy */
3725 + memcpy(dst, src, sizeof(*src));
3726 +
3727 + return dst;
3728 +}
3729 +/* }}} */
3730 +
3731 +/* {{{ my_copy_arg_info_array */
3732 +static zend_arg_info* my_copy_arg_info_array(zend_arg_info* dst, const zend_arg_info* src, uint num_args, apc_context_t* ctxt)
3733 +{
3734 + uint i = 0;
3735 +
3736 +
3737 + if (!dst) {
3738 + CHECK(dst = (zend_arg_info*) apc_pool_alloc(ctxt->pool, sizeof(*src)*num_args));
3739 + }
3740 +
3741 + /* Start with a bitwise copy */
3742 + memcpy(dst, src, sizeof(*src)*num_args);
3743 +
3744 + for(i=0; i < num_args; i++) {
3745 + CHECK((my_copy_arg_info( &dst[i], &src[i], ctxt)));
3746 + }
3747 +
3748 + return dst;
3749 +}
3750 +/* }}} */
3751 +
3752 +/* {{{ my_copy_arg_info */
3753 +static zend_arg_info* my_copy_arg_info(zend_arg_info* dst, const zend_arg_info* src, apc_context_t* ctxt)
3754 +{
3755 + apc_pool* pool = ctxt->pool;
3756 +
3757 + assert(src != NULL);
3758 +
3759 + if (!dst) {
3760 + CHECK(dst = (zend_arg_info*) apc_pool_alloc(pool, sizeof(*src)));
3761 + }
3762 +
3763 + /* Start with a bitwise copy */
3764 + memcpy(dst, src, sizeof(*src));
3765 +
3766 + dst->name = NULL;
3767 + dst->class_name = NULL;
3768 +
3769 + if (src->name) {
3770 + CHECK((dst->name = apc_pmemcpy(src->name, src->name_len+1, pool)));
3771 + }
3772 +
3773 + if (src->class_name) {
3774 + CHECK((dst->class_name = apc_pmemcpy(src->class_name, src->class_name_len+1, pool)));
3775 + }
3776 +
3777 + return dst;
3778 +}
3779 +/* }}} */
3780 +
3781 +/* {{{ apc_copy_class_entry */
3782 +zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt)
3783 +{
3784 + return my_copy_class_entry(dst, src, ctxt);
3785 +}
3786 +
3787 +/* {{{ my_copy_class_entry */
3788 +static zend_class_entry* my_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt)
3789 +{
3790 + uint i = 0;
3791 + apc_pool* pool = ctxt->pool;
3792 +
3793 + assert(src != NULL);
3794 +
3795 + if (!dst) {
3796 + CHECK(dst = (zend_class_entry*) apc_pool_alloc(pool, sizeof(*src)));
3797 + }
3798 +
3799 + /* Start with a bitwise copy */
3800 + memcpy(dst, src, sizeof(*src));
3801 +
3802 + dst->name = NULL;
3803 + dst->builtin_functions = NULL;
3804 + memset(&dst->function_table, 0, sizeof(dst->function_table));
3805 + memset(&dst->default_properties, 0, sizeof(dst->default_properties));
3806 + dst->static_members = NULL;
3807 + dst->doc_comment = NULL;
3808 + dst->filename = NULL;
3809 + memset(&dst->properties_info, 0, sizeof(dst->properties_info));
3810 + memset(&dst->constants_table, 0, sizeof(dst->constants_table));
3811 + memset(&dst->default_static_members, 0, sizeof(dst->default_static_members));
3812 +
3813 + if (src->name) {
3814 + CHECK((dst->name = apc_pstrdup(src->name, pool)));
3815 + }
3816 +
3817 + if(!(my_copy_hashtable_ex(&dst->function_table,
3818 + &src->function_table,
3819 + (ht_copy_fun_t) my_copy_function,
3820 + 0,
3821 + ctxt,
3822 + (ht_check_copy_fun_t) my_check_copy_function,
3823 + src))) {
3824 + return NULL;
3825 + }
3826 +
3827 + /* the interfaces are populated at runtime using ADD_INTERFACE */
3828 + dst->interfaces = NULL;
3829 +
3830 + /* the current count includes inherited interfaces as well,
3831 + the real dynamic ones are the first <n> which are zero'd
3832 + out in zend_do_end_class_declaration */
3833 + for(i = 0 ; i < src->num_interfaces ; i++) {
3834 + if(src->interfaces[i])
3835 + {
3836 + dst->num_interfaces = i;
3837 + break;
3838 + }
3839 + }
3840 +
3841 + /* these will either be set inside my_fixup_hashtable or
3842 + * they will be copied out from parent inside zend_do_inheritance
3843 + */
3844 + dst->parent = NULL;
3845 + dst->constructor = NULL;
3846 + dst->destructor = NULL;
3847 + dst->clone = NULL;
3848 + dst->__get = NULL;
3849 + dst->__set = NULL;
3850 + dst->__unset = NULL;
3851 + dst->__isset = NULL;
3852 + dst->__call = NULL;
3853 +#ifdef ZEND_ENGINE_2_2
3854 + dst->__tostring = NULL;
3855 +#endif
3856 +#ifdef ZEND_ENGINE_2_3
3857 + dst->__callstatic = NULL;
3858 +#endif
3859 +
3860 + /* unset function proxies */
3861 + dst->serialize_func = NULL;
3862 + dst->unserialize_func = NULL;
3863 +
3864 + my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function, src, dst);
3865 +
3866 + CHECK((my_copy_hashtable_ex(&dst->default_properties,
3867 + &src->default_properties,
3868 + (ht_copy_fun_t) my_copy_zval_ptr,
3869 + 1,
3870 + ctxt,
3871 + (ht_check_copy_fun_t) my_check_copy_default_property,
3872 + src)));
3873 +
3874 + CHECK((my_copy_hashtable_ex(&dst->properties_info,
3875 + &src->properties_info,
3876 + (ht_copy_fun_t) my_copy_property_info,
3877 + 0,
3878 + ctxt,
3879 + (ht_check_copy_fun_t) my_check_copy_property_info,
3880 + src)));
3881 +
3882 +#ifdef ZEND_ENGINE_2_2
3883 + /* php5.2 introduced a scope attribute for property info */
3884 + my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst);
3885 +#endif
3886 +
3887 + CHECK(my_copy_hashtable_ex(&dst->default_static_members,
3888 + &src->default_static_members,
3889 + (ht_copy_fun_t) my_copy_zval_ptr,
3890 + 1,
3891 + ctxt,
3892 + (ht_check_copy_fun_t) my_check_copy_static_member,
3893 + src,
3894 + &src->default_static_members));
3895 +
3896 + if(src->static_members != &src->default_static_members)
3897 + {
3898 + CHECK((dst->static_members = my_copy_hashtable_ex(NULL,
3899 + src->static_members,
3900 + (ht_copy_fun_t) my_copy_zval_ptr,
3901 + 1,
3902 + ctxt,
3903 + (ht_check_copy_fun_t) my_check_copy_static_member,
3904 + src,
3905 + src->static_members)));
3906 + }
3907 + else
3908 + {
3909 + dst->static_members = &dst->default_static_members;
3910 + }
3911 +
3912 + CHECK((my_copy_hashtable(&dst->constants_table,
3913 + &src->constants_table,
3914 + (ht_copy_fun_t) my_copy_zval_ptr,
3915 + 1,
3916 + ctxt)));
3917 +
3918 + if (src->doc_comment) {
3919 + CHECK(dst->doc_comment =
3920 + apc_pmemcpy(src->doc_comment, src->doc_comment_len+1, pool));
3921 + }
3922 +
3923 + if (src->builtin_functions) {
3924 + int i, n;
3925 +
3926 + for (n = 0; src->type == ZEND_INTERNAL_CLASS && src->builtin_functions[n].fname != NULL; n++) {}
3927 +
3928 + CHECK((dst->builtin_functions =
3929 + (zend_function_entry*) apc_pool_alloc(pool, (n + 1) * sizeof(zend_function_entry))));
3930 +
3931 + for (i = 0; i < n; i++) {
3932 + CHECK(my_copy_function_entry((zend_function_entry*)(&dst->builtin_functions[i]),
3933 + &src->builtin_functions[i],
3934 + ctxt));
3935 + }
3936 + *(char**)&(dst->builtin_functions[n].fname) = NULL;
3937 + }
3938 +
3939 + if (src->filename) {
3940 + CHECK((dst->filename = apc_pstrdup(src->filename, pool)));
3941 + }
3942 +
3943 + return dst;
3944 +}
3945 +/* }}} */
3946 +
3947 +/* {{{ my_copy_hashtable */
3948 +static HashTable* my_copy_hashtable_ex(HashTable* dst,
3949 + HashTable* src,
3950 + ht_copy_fun_t copy_fn,
3951 + int holds_ptrs,
3952 + apc_context_t* ctxt,
3953 + ht_check_copy_fun_t check_fn,
3954 + ...)
3955 +{
3956 + Bucket* curr = NULL;
3957 + Bucket* prev = NULL;
3958 + Bucket* newp = NULL;
3959 + int first = 1;
3960 + apc_pool* pool = ctxt->pool;
3961 +
3962 + assert(src != NULL);
3963 +
3964 + if (!dst) {
3965 + CHECK(dst = (HashTable*) apc_pool_alloc(pool, sizeof(src[0])));
3966 + }
3967 +
3968 + memcpy(dst, src, sizeof(src[0]));
3969 +
3970 + /* allocate buckets for the new hashtable */
3971 + CHECK((dst->arBuckets = apc_pool_alloc(pool, dst->nTableSize * sizeof(Bucket*))));
3972 +
3973 + memset(dst->arBuckets, 0, dst->nTableSize * sizeof(Bucket*));
3974 + dst->pInternalPointer = NULL;
3975 + dst->pListHead = NULL;
3976 +
3977 + for (curr = src->pListHead; curr != NULL; curr = curr->pListNext) {
3978 + int n = curr->h % dst->nTableSize;
3979 +
3980 + if(check_fn) {
3981 + va_list args;
3982 + va_start(args, check_fn);
3983 +
3984 + /* Call the check_fn to see if the current bucket
3985 + * needs to be copied out
3986 + */
3987 + if(!check_fn(curr, args)) {
3988 + dst->nNumOfElements--;
3989 + continue;
3990 + }
3991 +
3992 + va_end(args);
3993 + }
3994 +
3995 + /* create a copy of the bucket 'curr' */
3996 + CHECK((newp = (Bucket*) apc_pmemcpy(curr,
3997 + sizeof(Bucket) + curr->nKeyLength - 1,
3998 + pool)));
3999 +
4000 + /* insert 'newp' into the linked list at its hashed index */
4001 + if (dst->arBuckets[n]) {
4002 + newp->pNext = dst->arBuckets[n];
4003 + newp->pLast = NULL;
4004 + newp->pNext->pLast = newp;
4005 + }
4006 + else {
4007 + newp->pNext = newp->pLast = NULL;
4008 + }
4009 +
4010 + dst->arBuckets[n] = newp;
4011 +
4012 + /* copy the bucket data using our 'copy_fn' callback function */
4013 + CHECK((newp->pData = copy_fn(NULL, curr->pData, ctxt)));
4014 +
4015 + if (holds_ptrs) {
4016 + memcpy(&newp->pDataPtr, newp->pData, sizeof(void*));
4017 + }
4018 + else {
4019 + newp->pDataPtr = NULL;
4020 + }
4021 +
4022 + /* insert 'newp' into the table-thread linked list */
4023 + newp->pListLast = prev;
4024 + newp->pListNext = NULL;
4025 +
4026 + if (prev) {
4027 + prev->pListNext = newp;
4028 + }
4029 +
4030 + if (first) {
4031 + dst->pListHead = newp;
4032 + first = 0;
4033 + }
4034 +
4035 + prev = newp;
4036 + }
4037 +
4038 + dst->pListTail = newp;
4039 +
4040 + return dst;
4041 +}
4042 +/* }}} */
4043 +
4044 +/* {{{ my_copy_static_variables */
4045 +static HashTable* my_copy_static_variables(zend_op_array* src, apc_context_t* ctxt)
4046 +{
4047 + if (src->static_variables == NULL) {
4048 + return NULL;
4049 + }
4050 +
4051 + return my_copy_hashtable(NULL,
4052 + src->static_variables,
4053 + (ht_copy_fun_t) my_copy_zval_ptr,
4054 + 1,
4055 + ctxt);
4056 +}
4057 +/* }}} */
4058 +
4059 +/* {{{ apc_copy_zval */
4060 +zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt)
4061 +{
4062 + apc_pool* pool = ctxt->pool;
4063 + int usegc = (ctxt->copy == APC_COPY_OUT_OPCODE) || (ctxt->copy == APC_COPY_OUT_USER);
4064 +
4065 + assert(src != NULL);
4066 +
4067 + if (!dst) {
4068 + if(usegc) {
4069 + ALLOC_ZVAL(dst);
4070 + CHECK(dst);
4071 + } else {
4072 + CHECK(dst = (zval*) apc_pool_alloc(pool, sizeof(zval)));
4073 + }
4074 + }
4075 +
4076 + CHECK(dst = my_copy_zval(dst, src, ctxt));
4077 + return dst;
4078 +}
4079 +/* }}} */
4080 +
4081 +/* {{{ apc_fixup_op_array_jumps */
4082 +static void apc_fixup_op_array_jumps(zend_op_array *dst, zend_op_array *src )
4083 +{
4084 + uint i;
4085 +
4086 + for (i=0; i < dst->last; ++i) {
4087 + zend_op *zo = &(dst->opcodes[i]);
4088 + /*convert opline number to jump address*/
4089 + switch (zo->opcode) {
4090 + case ZEND_JMP:
4091 + /*Note: if src->opcodes != dst->opcodes then we need to the opline according to src*/
4092 + zo->op1.u.jmp_addr = dst->opcodes + (zo->op1.u.jmp_addr - src->opcodes);
4093 + break;
4094 + case ZEND_JMPZ:
4095 + case ZEND_JMPNZ:
4096 + case ZEND_JMPZ_EX:
4097 + case ZEND_JMPNZ_EX:
4098 +#ifdef ZEND_ENGINE_2_3
4099 + case ZEND_JMP_SET:
4100 +#endif
4101 + zo->op2.u.jmp_addr = dst->opcodes + (zo->op2.u.jmp_addr - src->opcodes);
4102 + break;
4103 + default:
4104 + break;
4105 + }
4106 + }
4107 +}
4108 +/* }}} */
4109 +
4110 +/* {{{ apc_copy_op_array */
4111 +zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
4112 +{
4113 + int i;
4114 + apc_fileinfo_t fileinfo;
4115 + char canon_path[MAXPATHLEN];
4116 + char *fullpath = NULL;
4117 + apc_opflags_t * flags = NULL;
4118 + apc_pool* pool = ctxt->pool;
4119 +
4120 + assert(src != NULL);
4121 +
4122 + if (!dst) {
4123 + CHECK(dst = (zend_op_array*) apc_pool_alloc(pool, sizeof(src[0])));
4124 + }
4125 +
4126 + if(APCG(apc_optimize_function)) {
4127 + APCG(apc_optimize_function)(src TSRMLS_CC);
4128 + }
4129 +
4130 + /* start with a bitwise copy of the array */
4131 + memcpy(dst, src, sizeof(src[0]));
4132 +
4133 + dst->function_name = NULL;
4134 + dst->filename = NULL;
4135 + dst->refcount = NULL;
4136 + dst->opcodes = NULL;
4137 + dst->brk_cont_array = NULL;
4138 + dst->static_variables = NULL;
4139 + dst->try_catch_array = NULL;
4140 + dst->arg_info = NULL;
4141 + dst->doc_comment = NULL;
4142 +#ifdef ZEND_ENGINE_2_1
4143 + dst->vars = NULL;
4144 +#endif
4145 +
4146 + /* copy the arg types array (if set) */
4147 + if (src->arg_info) {
4148 + CHECK(dst->arg_info = my_copy_arg_info_array(NULL,
4149 + src->arg_info,
4150 + src->num_args,
4151 + ctxt));
4152 + }
4153 +
4154 + if (src->function_name) {
4155 + CHECK(dst->function_name = apc_pstrdup(src->function_name, pool));
4156 + }
4157 + if (src->filename) {
4158 + CHECK(dst->filename = apc_pstrdup(src->filename, pool));
4159 + }
4160 +
4161 + CHECK(dst->refcount = apc_pmemcpy(src->refcount,
4162 + sizeof(src->refcount[0]),
4163 + pool));
4164 +
4165 + /* deep-copy the opcodes */
4166 + CHECK(dst->opcodes = (zend_op*) apc_pool_alloc(pool, sizeof(zend_op) * src->last));
4167 +
4168 + if(apc_reserved_offset != -1) {
4169 + /* Insanity alert: the void* pointer is cast into an apc_opflags_t
4170 + * struct. apc_zend_init() checks to ensure that it fits in a void* */
4171 + flags = (apc_opflags_t*) & (dst->reserved[apc_reserved_offset]);
4172 + memset(flags, 0, sizeof(apc_opflags_t));
4173 + /* assert(sizeof(apc_opflags_t) < sizeof(dst->reserved)); */
4174 + }
4175 +
4176 + for (i = 0; (uint) i < src->last; i++) {
4177 + zend_op *zo = &(src->opcodes[i]);
4178 + /* a lot of files are merely constant arrays with no jumps */
4179 + switch (zo->opcode) {
4180 + case ZEND_JMP:
4181 + case ZEND_JMPZ:
4182 + case ZEND_JMPNZ:
4183 + case ZEND_JMPZ_EX:
4184 + case ZEND_JMPNZ_EX:
4185 +#ifdef ZEND_ENGINE_2_3
4186 + case ZEND_JMP_SET:
4187 +#endif
4188 + if(flags != NULL) {
4189 + flags->has_jumps = 1;
4190 + }
4191 + break;
4192 + /* auto_globals_jit was not in php-4.3.* */
4193 + case ZEND_FETCH_R:
4194 + case ZEND_FETCH_W:
4195 + case ZEND_FETCH_IS:
4196 + case ZEND_FETCH_FUNC_ARG:
4197 + if(PG(auto_globals_jit) && flags != NULL)
4198 + {
4199 + /* The fetch is only required if auto_globals_jit=1 */
4200 + if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL &&
4201 + zo->op1.op_type == IS_CONST &&
4202 + zo->op1.u.constant.type == IS_STRING) {
4203 + znode * varname = &zo->op1;
4204 + if (varname->u.constant.value.str.val[0] == '_') {
4205 +#define SET_IF_AUTOGLOBAL(member) \
4206 + if(!strcmp(varname->u.constant.value.str.val, #member)) \
4207 + flags->member = 1 /* no ';' here */
4208 + SET_IF_AUTOGLOBAL(_GET);
4209 + else SET_IF_AUTOGLOBAL(_POST);
4210 + else SET_IF_AUTOGLOBAL(_COOKIE);
4211 + else SET_IF_AUTOGLOBAL(_SERVER);
4212 + else SET_IF_AUTOGLOBAL(_ENV);
4213 + else SET_IF_AUTOGLOBAL(_FILES);
4214 + else SET_IF_AUTOGLOBAL(_REQUEST);
4215 + else if(zend_is_auto_global(
4216 + varname->u.constant.value.str.val,
4217 + varname->u.constant.value.str.len
4218 + TSRMLS_CC))
4219 + {
4220 + flags->unknown_global = 1;
4221 + }
4222 + }
4223 + }
4224 + }
4225 + break;
4226 + case ZEND_RECV_INIT:
4227 + if(zo->op2.op_type == IS_CONST &&
4228 + zo->op2.u.constant.type == IS_CONSTANT_ARRAY) {
4229 + if(flags != NULL) {
4230 + flags->deep_copy = 1;
4231 + }
4232 + }
4233 + break;
4234 + default:
4235 + if((zo->op1.op_type == IS_CONST &&
4236 + zo->op1.u.constant.type == IS_CONSTANT_ARRAY) ||
4237 + (zo->op2.op_type == IS_CONST &&
4238 + zo->op2.u.constant.type == IS_CONSTANT_ARRAY)) {
4239 + if(flags != NULL) {
4240 + flags->deep_copy = 1;
4241 + }
4242 + }
4243 + break;
4244 + }
4245 +
4246 + if(!(my_copy_zend_op(dst->opcodes+i, src->opcodes+i, ctxt))) {
4247 + return NULL;
4248 + }
4249 +
4250 +/* This code breaks apc's rule#1 - cache what you compile */
4251 + if((APCG(fpstat)==0) && APCG(canonicalize)) {
4252 + if((zo->opcode == ZEND_INCLUDE_OR_EVAL) &&
4253 + (zo->op1.op_type == IS_CONST && zo->op1.u.constant.type == IS_STRING)) {
4254 + /* constant includes */
4255 + if(!IS_ABSOLUTE_PATH(Z_STRVAL_P(&zo->op1.u.constant),Z_STRLEN_P(&zo->op1.u.constant))) {
4256 + if (apc_search_paths(Z_STRVAL_P(&zo->op1.u.constant), PG(include_path), &fileinfo) == 0) {
4257 + if((fullpath = realpath(fileinfo.fullpath, canon_path))) {
4258 + /* everything has to go through a realpath() */
4259 + zend_op *dzo = &(dst->opcodes[i]);
4260 + dzo->op1.u.constant.value.str.len = strlen(fullpath);
4261 + dzo->op1.u.constant.value.str.val = apc_pstrdup(fullpath, pool);
4262 + }
4263 + }
4264 + }
4265 + }
4266 + }
4267 + }
4268 +
4269 + if(flags == NULL || flags->has_jumps) {
4270 + apc_fixup_op_array_jumps(dst,src);
4271 + }
4272 +
4273 + /* copy the break-continue array */
4274 + if (src->brk_cont_array) {
4275 + CHECK(dst->brk_cont_array = apc_pmemcpy(src->brk_cont_array,
4276 + sizeof(src->brk_cont_array[0]) * src->last_brk_cont,
4277 + pool));
4278 + }
4279 +
4280 + /* copy the table of static variables */
4281 + if (src->static_variables) {
4282 + CHECK(dst->static_variables = my_copy_static_variables(src, ctxt));
4283 + }
4284 +
4285 + if (src->try_catch_array) {
4286 + CHECK(dst->try_catch_array = apc_pmemcpy(src->try_catch_array,
4287 + sizeof(src->try_catch_array[0]) * src->last_try_catch,
4288 + pool));
4289 + }
4290 +
4291 +#ifdef ZEND_ENGINE_2_1 /* PHP 5.1 */
4292 + if (src->vars) {
4293 + CHECK(dst->vars = apc_pmemcpy(src->vars,
4294 + sizeof(src->vars[0]) * src->last_var,
4295 + pool));
4296 +
4297 + for(i = 0; i < src->last_var; i++) dst->vars[i].name = NULL;
4298 +
4299 + for(i = 0; i < src->last_var; i++) {
4300 + CHECK(dst->vars[i].name = apc_pmemcpy(src->vars[i].name,
4301 + src->vars[i].name_len + 1,
4302 + pool));
4303 + }
4304 + }
4305 +#endif
4306 +
4307 + if (src->doc_comment) {
4308 + CHECK(dst->doc_comment
4309 + = apc_pmemcpy(src->doc_comment, src->doc_comment_len+1, pool));
4310 + }
4311 +
4312 + return dst;
4313 +}
4314 +/* }}} */
4315 +
4316 +
4317 +/* {{{ apc_copy_new_functions */
4318 +apc_function_t* apc_copy_new_functions(int old_count, apc_context_t* ctxt TSRMLS_DC)
4319 +{
4320 + apc_function_t* array;
4321 + int new_count; /* number of new functions in table */
4322 + int i;
4323 + apc_pool* pool = ctxt->pool;
4324 +
4325 + new_count = zend_hash_num_elements(CG(function_table)) - old_count;
4326 + assert(new_count >= 0);
4327 +
4328 + CHECK(array =
4329 + (apc_function_t*)
4330 + apc_pool_alloc(pool, sizeof(apc_function_t) * (new_count+1)));
4331 +
4332 + if (new_count == 0) {
4333 + array[0].function = NULL;
4334 + return array;
4335 + }
4336 +
4337 + /* Skip the first `old_count` functions in the table */
4338 + zend_hash_internal_pointer_reset(CG(function_table));
4339 + for (i = 0; i < old_count; i++) {
4340 + zend_hash_move_forward(CG(function_table));
4341 + }
4342 +
4343 + /* Add the next `new_count` functions to our array */
4344 + for (i = 0; i < new_count; i++) {
4345 + char* key;
4346 + uint key_size;
4347 + zend_function* fun;
4348 +
4349 + zend_hash_get_current_key_ex(CG(function_table),
4350 + &key,
4351 + &key_size,
4352 + NULL,
4353 + 0,
4354 + NULL);
4355 +
4356 + zend_hash_get_current_data(CG(function_table), (void**) &fun);
4357 +
4358 + CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool));
4359 + array[i].name_len = (int) key_size-1;
4360 + CHECK(array[i].function = my_copy_function(NULL, fun, ctxt));
4361 + zend_hash_move_forward(CG(function_table));
4362 + }
4363 +
4364 + array[i].function = NULL;
4365 + return array;
4366 +}
4367 +/* }}} */
4368 +
4369 +/* {{{ apc_copy_new_classes */
4370 +apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t *ctxt TSRMLS_DC)
4371 +{
4372 + apc_class_t* array;
4373 + int new_count; /* number of new classes in table */
4374 + int i;
4375 + apc_pool* pool = ctxt->pool;
4376 +
4377 + new_count = zend_hash_num_elements(CG(class_table)) - old_count;
4378 + assert(new_count >= 0);
4379 +
4380 + CHECK(array =
4381 + (apc_class_t*)
4382 + apc_pool_alloc(pool, sizeof(apc_class_t)*(new_count+1)));
4383 +
4384 + if (new_count == 0) {
4385 + array[0].class_entry = NULL;
4386 + return array;
4387 + }
4388 +
4389 + /* Skip the first `old_count` classes in the table */
4390 + zend_hash_internal_pointer_reset(CG(class_table));
4391 + for (i = 0; i < old_count; i++) {
4392 + zend_hash_move_forward(CG(class_table));
4393 + }
4394 +
4395 + /* Add the next `new_count` classes to our array */
4396 + for (i = 0; i < new_count; i++) {
4397 + char* key;
4398 + uint key_size;
4399 + zend_class_entry* elem = NULL;
4400 +
4401 + array[i].class_entry = NULL;
4402 +
4403 + zend_hash_get_current_key_ex(CG(class_table),
4404 + &key,
4405 + &key_size,
4406 + NULL,
4407 + 0,
4408 + NULL);
4409 +
4410 + zend_hash_get_current_data(CG(class_table), (void**) &elem);
4411 +
4412 +
4413 + elem = *((zend_class_entry**)elem);
4414 +
4415 + CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool));
4416 + array[i].name_len = (int) key_size-1;
4417 + CHECK(array[i].class_entry = my_copy_class_entry(NULL, elem, ctxt));
4418 +
4419 + /*
4420 + * If the class has a pointer to its parent class, save the parent
4421 + * name so that we can enable compile-time inheritance when we reload
4422 + * the child class; otherwise, set the parent name to null and scan
4423 + * the op_array to determine if this class inherits from some base
4424 + * class at execution-time.
4425 + */
4426 +
4427 + if (elem->parent) {
4428 + CHECK(array[i].parent_name = apc_pstrdup(elem->parent->name, pool));
4429 + }
4430 + else {
4431 + array[i].parent_name = NULL;
4432 + }
4433 +
4434 + zend_hash_move_forward(CG(class_table));
4435 + }
4436 +
4437 + array[i].class_entry = NULL;
4438 + return array;
4439 +}
4440 +/* }}} */
4441 +
4442 +/* Used only by my_prepare_op_array_for_execution */
4443 +#define APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION() \
4444 + /* The fetch is only required if auto_globals_jit=1 */ \
4445 + if(zo->op2.u.EA.type == ZEND_FETCH_GLOBAL && \
4446 + zo->op1.op_type == IS_CONST && \
4447 + zo->op1.u.constant.type == IS_STRING && \
4448 + zo->op1.u.constant.value.str.val[0] == '_') { \
4449 + \
4450 + znode* varname = &zo->op1; \
4451 + (void)zend_is_auto_global(varname->u.constant.value.str.val, \
4452 + varname->u.constant.value.str.len \
4453 + TSRMLS_CC); \
4454 + } \
4455 +
4456 +/* {{{ my_prepare_op_array_for_execution */
4457 +static int my_prepare_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
4458 +{
4459 + /* combine my_fetch_global_vars and my_copy_data_exceptions.
4460 + * - Pre-fetch superglobals which would've been pre-fetched in parse phase.
4461 + * - If the opcode stream contain mutable data, ensure a copy.
4462 + * - Fixup array jumps in the same loop.
4463 + */
4464 + int i=src->last;
4465 + zend_op *zo;
4466 + zend_op *dzo;
4467 + apc_opflags_t * flags = apc_reserved_offset != -1 ?
4468 + (apc_opflags_t*) & (src->reserved[apc_reserved_offset]) : NULL;
4469 + int needcopy = flags ? flags->deep_copy : 1;
4470 + /* auto_globals_jit was not in php4 */
4471 + int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global);
4472 +
4473 +#define FETCH_AUTOGLOBAL(member) do { \
4474 + if(flags && flags->member == 1) { \
4475 + zend_is_auto_global(#member,\
4476 + (sizeof(#member) - 1)\
4477 + TSRMLS_CC);\
4478 + } \
4479 +} while(0);
4480 +
4481 + FETCH_AUTOGLOBAL(_GET);
4482 + FETCH_AUTOGLOBAL(_POST);
4483 + FETCH_AUTOGLOBAL(_COOKIE);
4484 + FETCH_AUTOGLOBAL(_SERVER);
4485 + FETCH_AUTOGLOBAL(_ENV);
4486 + FETCH_AUTOGLOBAL(_FILES);
4487 + FETCH_AUTOGLOBAL(_REQUEST);
4488 +
4489 + if(needcopy) {
4490 +
4491 + dst->opcodes = (zend_op*) apc_xmemcpy(src->opcodes,
4492 + sizeof(zend_op) * src->last,
4493 + apc_php_malloc);
4494 + zo = src->opcodes;
4495 + dzo = dst->opcodes;
4496 + while(i > 0) {
4497 +
4498 + if( ((zo->op1.op_type == IS_CONST &&
4499 + zo->op1.u.constant.type == IS_CONSTANT_ARRAY)) ||
4500 + ((zo->op2.op_type == IS_CONST &&
4501 + zo->op2.u.constant.type == IS_CONSTANT_ARRAY))) {
4502 +
4503 + if(!(my_copy_zend_op(dzo, zo, ctxt))) {
4504 + assert(0); /* emalloc failed or a bad constant array */
4505 + }
4506 + }
4507 +
4508 + switch(zo->opcode) {
4509 + case ZEND_JMP:
4510 + dzo->op1.u.jmp_addr = dst->opcodes +
4511 + (zo->op1.u.jmp_addr - src->opcodes);
4512 + break;
4513 + case ZEND_JMPZ:
4514 + case ZEND_JMPNZ:
4515 + case ZEND_JMPZ_EX:
4516 + case ZEND_JMPNZ_EX:
4517 +#ifdef ZEND_ENGINE_2_3
4518 + case ZEND_JMP_SET:
4519 +#endif
4520 + dzo->op2.u.jmp_addr = dst->opcodes +
4521 + (zo->op2.u.jmp_addr - src->opcodes);
4522 + break;
4523 + case ZEND_FETCH_R:
4524 + case ZEND_FETCH_W:
4525 + case ZEND_FETCH_IS:
4526 + case ZEND_FETCH_FUNC_ARG:
4527 + if(do_prepare_fetch_global)
4528 + {
4529 + APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
4530 + }
4531 + break;
4532 + default:
4533 + break;
4534 + }
4535 + i--;
4536 + zo++;
4537 + dzo++;
4538 + }
4539 + } else { /* !needcopy */
4540 + /* The fetch is only required if auto_globals_jit=1 */
4541 + if(do_prepare_fetch_global)
4542 + {
4543 + zo = src->opcodes;
4544 + while(i > 0) {
4545 +
4546 + if(zo->opcode == ZEND_FETCH_R ||
4547 + zo->opcode == ZEND_FETCH_W ||
4548 + zo->opcode == ZEND_FETCH_IS ||
4549 + zo->opcode == ZEND_FETCH_FUNC_ARG
4550 + ) {
4551 + APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
4552 + }
4553 +
4554 + i--;
4555 + zo++;
4556 + }
4557 + }
4558 + }
4559 + return 1;
4560 +}
4561 +/* }}} */
4562 +
4563 +/* {{{ apc_copy_op_array_for_execution */
4564 +zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
4565 +{
4566 + if(dst == NULL) {
4567 + dst = (zend_op_array*) emalloc(sizeof(src[0]));
4568 + }
4569 + memcpy(dst, src, sizeof(src[0]));
4570 + dst->static_variables = my_copy_static_variables(src, ctxt);
4571 +
4572 + /* memory leak */
4573 + dst->refcount = apc_pmemcpy(src->refcount,
4574 + sizeof(src->refcount[0]),
4575 + ctxt->pool);
4576 +
4577 + my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC);
4578 +
4579 + return dst;
4580 +}
4581 +/* }}} */
4582 +
4583 +/* {{{ apc_copy_function_for_execution */
4584 +zend_function* apc_copy_function_for_execution(zend_function* src, apc_context_t* ctxt)
4585 +{
4586 + zend_function* dst;
4587 + TSRMLS_FETCH();
4588 +
4589 + dst = (zend_function*) emalloc(sizeof(src[0]));
4590 + memcpy(dst, src, sizeof(src[0]));
4591 + apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC);
4592 + return dst;
4593 +}
4594 +/* }}} */
4595 +
4596 +/* {{{ apc_copy_function_for_execution_ex */
4597 +zend_function* apc_copy_function_for_execution_ex(void *dummy, zend_function* src, apc_context_t* ctxt)
4598 +{
4599 + if(src->type==ZEND_INTERNAL_FUNCTION || src->type==ZEND_OVERLOADED_FUNCTION) return src;
4600 + return apc_copy_function_for_execution(src, ctxt);
4601 +}
4602 +/* }}} */
4603 +
4604 +/* {{{ apc_copy_class_entry_for_execution */
4605 +zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, apc_context_t* ctxt)
4606 +{
4607 + zend_class_entry* dst = (zend_class_entry*) apc_pool_alloc(ctxt->pool, sizeof(src[0]));
4608 + memcpy(dst, src, sizeof(src[0]));
4609 +
4610 + if(src->num_interfaces)
4611 + {
4612 + /* These are slots to be populated later by ADD_INTERFACE insns */
4613 + dst->interfaces = apc_php_malloc(
4614 + sizeof(zend_class_entry*) * src->num_interfaces);
4615 + memset(dst->interfaces, 0,
4616 + sizeof(zend_class_entry*) * src->num_interfaces);
4617 + }
4618 + else
4619 + {
4620 + /* assert(dst->interfaces == NULL); */
4621 + }
4622 +
4623 + /* Deep-copy the class properties, because they will be modified */
4624 +
4625 + my_copy_hashtable(&dst->default_properties,
4626 + &src->default_properties,
4627 + (ht_copy_fun_t) my_copy_zval_ptr,
4628 + 1,
4629 + ctxt);
4630 +
4631 + /* For derived classes, we must also copy the function hashtable (although
4632 + * we can merely bitwise copy the functions it contains) */
4633 +
4634 + my_copy_hashtable(&dst->function_table,
4635 + &src->function_table,
4636 + (ht_copy_fun_t) apc_copy_function_for_execution_ex,
4637 + 0,
4638 + ctxt);
4639 +
4640 + my_fixup_hashtable(&dst->function_table, (ht_fixup_fun_t)my_fixup_function_for_execution, src, dst);
4641 +
4642 + /* zend_do_inheritance merges properties_info.
4643 + * Need only shallow copying as it doesn't hold the pointers.
4644 + */
4645 + my_copy_hashtable(&dst->properties_info,
4646 + &src->properties_info,
4647 + (ht_copy_fun_t) my_copy_property_info_for_execution,
4648 + 0,
4649 + ctxt);
4650 +
4651 +#ifdef ZEND_ENGINE_2_2
4652 + /* php5.2 introduced a scope attribute for property info */
4653 + my_fixup_hashtable(&dst->properties_info, (ht_fixup_fun_t)my_fixup_property_info_for_execution, src, dst);
4654 +#endif
4655 +
4656 + /* if inheritance results in a hash_del, it might result in
4657 + * a pefree() of the pointers here. Deep copying required.
4658 + */
4659 +
4660 + my_copy_hashtable(&dst->constants_table,
4661 + &src->constants_table,
4662 + (ht_copy_fun_t) my_copy_zval_ptr,
4663 + 1,
4664 + ctxt);
4665 +
4666 + my_copy_hashtable(&dst->default_static_members,
4667 + &src->default_static_members,
4668 + (ht_copy_fun_t) my_copy_zval_ptr,
4669 + 1,
4670 + ctxt);
4671 +
4672 + if(src->static_members != &(src->default_static_members))
4673 + {
4674 + dst->static_members = my_copy_hashtable(NULL,
4675 + src->static_members,
4676 + (ht_copy_fun_t) my_copy_zval_ptr,
4677 + 1,
4678 + ctxt);
4679 + }
4680 + else
4681 + {
4682 + dst->static_members = &(dst->default_static_members);
4683 + }
4684 +
4685 +
4686 + return dst;
4687 +}
4688 +/* }}} */
4689 +
4690 +/* {{{ apc_free_class_entry_after_execution */
4691 +void apc_free_class_entry_after_execution(zend_class_entry* src)
4692 +{
4693 + if(src->num_interfaces > 0 && src->interfaces) {
4694 + apc_php_free(src->interfaces);
4695 + src->interfaces = NULL;
4696 + src->num_interfaces = 0;
4697 + }
4698 + /* my_destroy_hashtable() does not play nice with refcounts */
4699 +
4700 + zend_hash_clean(&src->default_static_members);
4701 + if(src->static_members != &(src->default_static_members))
4702 + {
4703 + zend_hash_destroy(src->static_members);
4704 + apc_php_free(src->static_members);
4705 + src->static_members = NULL;
4706 + }
4707 + else
4708 + {
4709 + src->static_members = NULL;
4710 + }
4711 + zend_hash_clean(&src->default_properties);
4712 + zend_hash_clean(&src->constants_table);
4713 +
4714 + /* TODO: more cleanup */
4715 +}
4716 +/* }}} */
4717 +
4718 +/* {{{ apc_file_halt_offset */
4719 +long apc_file_halt_offset(const char *filename)
4720 +{
4721 + zend_constant *c;
4722 + char *name;
4723 + int len;
4724 + char haltoff[] = "__COMPILER_HALT_OFFSET__";
4725 + long value = -1;
4726 + TSRMLS_FETCH();
4727 +
4728 + zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, filename, strlen(filename), 0);
4729 +
4730 + if (zend_hash_find(EG(zend_constants), name, len+1, (void **) &c) == SUCCESS) {
4731 + value = Z_LVAL(c->value);
4732 + }
4733 +
4734 + pefree(name, 0);
4735 +
4736 + return value;
4737 +}
4738 +/* }}} */
4739 +
4740 +/* {{{ apc_do_halt_compiler_register */
4741 +void apc_do_halt_compiler_register(const char *filename, long halt_offset TSRMLS_DC)
4742 +{
4743 + char *name;
4744 + char haltoff[] = "__COMPILER_HALT_OFFSET__";
4745 + int len;
4746 +
4747 + if(halt_offset > 0) {
4748 +
4749 + zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1,
4750 + filename, strlen(filename), 0);
4751 +
4752 + zend_register_long_constant(name, len+1, halt_offset, CONST_CS, 0 TSRMLS_CC);
4753 +
4754 + pefree(name, 0);
4755 + }
4756 +}
4757 +/* }}} */
4758 +
4759 +
4760 +
4761 +/* {{{ my_fixup_function */
4762 +static void my_fixup_function(Bucket *p, zend_class_entry *src, zend_class_entry *dst)
4763 +{
4764 + zend_function* zf = p->pData;
4765 +
4766 + #define SET_IF_SAME_NAME(member) \
4767 + do { \
4768 + if(src->member && !strcmp(zf->common.function_name, src->member->common.function_name)) { \
4769 + dst->member = zf; \
4770 + } \
4771 + } \
4772 + while(0)
4773 +
4774 + if(zf->common.scope == src)
4775 + {
4776 +
4777 + /* Fixing up the default functions for objects here since
4778 + * we need to compare with the newly allocated functions
4779 + *
4780 + * caveat: a sub-class method can have the same name as the
4781 + * parent's constructor and create problems.
4782 + */
4783 +
4784 + if(zf->common.fn_flags & ZEND_ACC_CTOR) dst->constructor = zf;
4785 + else if(zf->common.fn_flags & ZEND_ACC_DTOR) dst->destructor = zf;
4786 + else if(zf->common.fn_flags & ZEND_ACC_CLONE) dst->clone = zf;
4787 + else
4788 + {
4789 + SET_IF_SAME_NAME(__get);
4790 + SET_IF_SAME_NAME(__set);
4791 + SET_IF_SAME_NAME(__unset);
4792 + SET_IF_SAME_NAME(__isset);
4793 + SET_IF_SAME_NAME(__call);
4794 +#ifdef ZEND_ENGINE_2_2
4795 + SET_IF_SAME_NAME(__tostring);
4796 +#endif
4797 +#ifdef ZEND_ENGINE_2_3
4798 + SET_IF_SAME_NAME(__callstatic);
4799 +#endif
4800 + }
4801 + zf->common.scope = dst;
4802 + }
4803 + else
4804 + {
4805 + /* no other function should reach here */
4806 + assert(0);
4807 + }
4808 +
4809 + #undef SET_IF_SAME_NAME
4810 +}
4811 +/* }}} */
4812 +
4813 +#ifdef ZEND_ENGINE_2_2
4814 +/* {{{ my_fixup_property_info */
4815 +static void my_fixup_property_info(Bucket *p, zend_class_entry *src, zend_class_entry *dst)
4816 +{
4817 + zend_property_info* property_info = (zend_property_info*)p->pData;
4818 +
4819 + if(property_info->ce == src)
4820 + {
4821 + property_info->ce = dst;
4822 + }
4823 + else
4824 + {
4825 + assert(0); /* should never happen */
4826 + }
4827 +}
4828 +/* }}} */
4829 +#endif
4830 +
4831 +/* {{{ my_fixup_hashtable */
4832 +static void my_fixup_hashtable(HashTable *ht, ht_fixup_fun_t fixup, zend_class_entry *src, zend_class_entry *dst)
4833 +{
4834 + Bucket *p;
4835 + uint i;
4836 +
4837 + for (i = 0; i < ht->nTableSize; i++) {
4838 + if(!ht->arBuckets) break;
4839 + p = ht->arBuckets[i];
4840 + while (p != NULL) {
4841 + fixup(p, src, dst);
4842 + p = p->pNext;
4843 + }
4844 + }
4845 +}
4846 +/* }}} */
4847 +
4848 +
4849 +/* {{{ my_check_copy_function */
4850 +static int my_check_copy_function(Bucket* p, va_list args)
4851 +{
4852 + zend_class_entry* src = va_arg(args, zend_class_entry*);
4853 + zend_function* zf = (zend_function*)p->pData;
4854 +
4855 + return (zf->common.scope == src);
4856 +}
4857 +/* }}} */
4858 +
4859 +/* {{{ my_check_copy_default_property */
4860 +static int my_check_copy_default_property(Bucket* p, va_list args)
4861 +{
4862 + zend_class_entry* src = va_arg(args, zend_class_entry*);
4863 + zend_class_entry* parent = src->parent;
4864 + zval ** child_prop = (zval**)p->pData;
4865 + zval ** parent_prop = NULL;
4866 +
4867 + if (parent &&
4868 + zend_hash_quick_find(&parent->default_properties, p->arKey,
4869 + p->nKeyLength, p->h, (void **) &parent_prop)==SUCCESS) {
4870 +
4871 + if((parent_prop && child_prop) && (*parent_prop) == (*child_prop))
4872 + {
4873 + return 0;
4874 + }
4875 + }
4876 +
4877 + /* possibly not in the parent */
4878 + return 1;
4879 +}
4880 +/* }}} */
4881 +
4882 +
4883 +/* {{{ my_check_copy_property_info */
4884 +static int my_check_copy_property_info(Bucket* p, va_list args)
4885 +{
4886 + zend_class_entry* src = va_arg(args, zend_class_entry*);
4887 + zend_class_entry* parent = src->parent;
4888 + zend_property_info* child_info = (zend_property_info*)p->pData;
4889 + zend_property_info* parent_info = NULL;
4890 +
4891 +#ifdef ZEND_ENGINE_2_2
4892 + /* so much easier */
4893 + return (child_info->ce == src);
4894 +#endif
4895 +
4896 + if (parent &&
4897 + zend_hash_quick_find(&parent->properties_info, p->arKey, p->nKeyLength,
4898 + p->h, (void **) &parent_info)==SUCCESS) {
4899 + if(parent_info->flags & ZEND_ACC_PRIVATE)
4900 + {
4901 + return 1;
4902 + }
4903 + if((parent_info->flags & ZEND_ACC_PPP_MASK) !=
4904 + (child_info->flags & ZEND_ACC_PPP_MASK))
4905 + {
4906 + /* TODO: figure out whether ACC_CHANGED is more appropriate
4907 + * here */
4908 + return 1;
4909 + }
4910 + return 0;
4911 + }
4912 +
4913 + /* property doesn't exist in parent, copy into cached child */
4914 + return 1;
4915 +}
4916 +/* }}} */
4917 +
4918 +/* {{{ my_check_copy_static_member */
4919 +static int my_check_copy_static_member(Bucket* p, va_list args)
4920 +{
4921 + zend_class_entry* src = va_arg(args, zend_class_entry*);
4922 + HashTable * ht = va_arg(args, HashTable*);
4923 + zend_class_entry* parent = src->parent;
4924 + HashTable * parent_ht = NULL;
4925 + char * member_name;
4926 + char * class_name = NULL;
4927 +
4928 + zend_property_info *parent_info = NULL;
4929 + zend_property_info *child_info = NULL;
4930 + zval ** parent_prop = NULL;
4931 + zval ** child_prop = (zval**)(p->pData);
4932 +
4933 + if(!parent) {
4934 + return 1;
4935 + }
4936 +
4937 + /* these do not need free'ing */
4938 +#ifdef ZEND_ENGINE_2_2
4939 + zend_unmangle_property_name(p->arKey, p->nKeyLength-1, &class_name, &member_name);
4940 +#else
4941 + zend_unmangle_property_name(p->arKey, &class_name, &member_name);
4942 +#endif
4943 +
4944 + /* please refer do_inherit_property_access_check in zend_compile.c
4945 + * to understand why we lookup in properties_info.
4946 + */
4947 + if((zend_hash_find(&parent->properties_info, member_name,
4948 + strlen(member_name)+1, (void**)&parent_info) == SUCCESS)
4949 + &&
4950 + (zend_hash_find(&src->properties_info, member_name,
4951 + strlen(member_name)+1, (void**)&child_info) == SUCCESS))
4952 + {
4953 + if(child_info->flags & ZEND_ACC_STATIC &&
4954 + (parent_info->flags & ZEND_ACC_PROTECTED &&
4955 + child_info->flags & ZEND_ACC_PUBLIC))
4956 + {
4957 + /* Do not copy into static_members. zend_do_inheritance
4958 + * will automatically insert a NULL value.
4959 + * TODO: decrement refcount or fixup when copying out for exec ?
4960 + */
4961 + return 0;
4962 + }
4963 + if(ht == &(src->default_static_members))
4964 + {
4965 + parent_ht = &parent->default_static_members;
4966 + }
4967 + else
4968 + {
4969 + parent_ht = parent->static_members;
4970 + }
4971 +
4972 + if(zend_hash_quick_find(parent_ht, p->arKey,
4973 + p->nKeyLength, p->h, (void**)&parent_prop) == SUCCESS)
4974 + {
4975 + /* they point to the same zval */
4976 + if(*parent_prop == *child_prop)
4977 + {
4978 + return 0;
4979 + }
4980 + }
4981 + }
4982 +
4983 + return 1;
4984 +}
4985 +/* }}} */
4986 +
4987 +/* {{{ apc_register_optimizer(apc_optimize_function_t optimizer)
4988 + * register a optimizer callback function, returns the previous callback
4989 + */
4990 +apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC) {
4991 + apc_optimize_function_t old_optimizer = APCG(apc_optimize_function);
4992 + APCG(apc_optimize_function) = optimizer;
4993 + return old_optimizer;
4994 +}
4995 +/* }}} */
4996 +
4997 +/*
4998 + * Local variables:
4999 + * tab-width: 4
5000 + * c-basic-offset: 4
5001 + * End:
5002 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5003 + * vim<600: expandtab sw=4 ts=4 sts=4
5004 + */
5005 diff -Naur php-5.3.1.orig/ext/apc/apc_compile.h php-5.3.1/ext/apc/apc_compile.h
5006 --- php-5.3.1.orig/ext/apc/apc_compile.h 1970-01-01 01:00:00.000000000 +0100
5007 +++ php-5.3.1/ext/apc/apc_compile.h 1970-01-01 10:13:08.000000000 +0100
5008 @@ -0,0 +1,142 @@
5009 +/*
5010 + +----------------------------------------------------------------------+
5011 + | APC |
5012 + +----------------------------------------------------------------------+
5013 + | Copyright (c) 2006-2008 The PHP Group |
5014 + +----------------------------------------------------------------------+
5015 + | This source file is subject to version 3.01 of the PHP license, |
5016 + | that is bundled with this package in the file LICENSE, and is |
5017 + | available through the world-wide-web at the following url: |
5018 + | http://www.php.net/license/3_01.txt |
5019 + | If you did not receive a copy of the PHP license and are unable to |
5020 + | obtain it through the world-wide-web, please send a note to |
5021 + | license@php.net so we can mail you a copy immediately. |
5022 + +----------------------------------------------------------------------+
5023 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
5024 + | Arun C. Murthy <arunc@yahoo-inc.com> |
5025 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
5026 + +----------------------------------------------------------------------+
5027 +
5028 + This software was contributed to PHP by Community Connect Inc. in 2002
5029 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5030 + Future revisions and derivatives of this source code must acknowledge
5031 + Community Connect Inc. as the original contributor of this module by
5032 + leaving this note intact in the source code.
5033 +
5034 + All other licensing and usage conditions are those of the PHP Group.
5035 +
5036 + */
5037 +
5038 +/* $Id: apc_compile.h 275218 2009-02-05 13:16:06Z gopalv $ */
5039 +
5040 +#ifndef APC_COMPILE_H
5041 +#define APC_COMPILE_H
5042 +
5043 +/*
5044 + * This module encapsulates most of the complexity involved in deep-copying
5045 + * the Zend compiler data structures. The routines are allocator-agnostic, so
5046 + * the same function can be used for copying to and from shared memory.
5047 + */
5048 +
5049 +#include "apc.h"
5050 +#include "apc_php.h"
5051 +#include "apc_main.h"
5052 +
5053 +/* {{{ struct definition: apc_function_t */
5054 +typedef struct apc_function_t apc_function_t;
5055 +struct apc_function_t {
5056 + char* name; /* the function name */
5057 + int name_len; /* length of name */
5058 + zend_function* function; /* the zend function data structure */
5059 +};
5060 +/* }}} */
5061 +
5062 +/* {{{ struct definition: apc_class_t */
5063 +typedef struct apc_class_t apc_class_t;
5064 +struct apc_class_t {
5065 + char* name; /* the class name */
5066 + int name_len; /* length of name */
5067 + char* parent_name; /* the parent class name */
5068 + zend_class_entry* class_entry; /* the zend class data structure */
5069 +};
5070 +/* }}} */
5071 +
5072 +/* {{{ struct definition: apc_opflags_t */
5073 +typedef struct apc_opflags_t apc_opflags_t;
5074 +struct apc_opflags_t {
5075 + unsigned int has_jumps : 1; /* has jump offsets */
5076 + unsigned int deep_copy : 1; /* needs deep copy */
5077 +
5078 + /* autoglobal bits */
5079 + unsigned int _POST : 1;
5080 + unsigned int _GET : 1;
5081 + unsigned int _COOKIE : 1;
5082 + unsigned int _SERVER : 1;
5083 + unsigned int _ENV : 1;
5084 + unsigned int _FILES : 1;
5085 + unsigned int _REQUEST : 1;
5086 + unsigned int unknown_global : 1;
5087 +};
5088 +/* }}} */
5089 +
5090 +/*
5091 + * These are the top-level copy functions.
5092 + */
5093 +
5094 +extern zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC);
5095 +extern zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt);
5096 +extern apc_function_t* apc_copy_new_functions(int old_count, apc_context_t* ctxt TSRMLS_DC);
5097 +extern apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t* ctxt TSRMLS_DC);
5098 +extern zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt);
5099 +
5100 +#if 0
5101 +/*
5102 + * Deallocation functions corresponding to the copy functions above.
5103 + */
5104 +
5105 +extern void apc_free_op_array(zend_op_array* src, apc_context_t* ctxt);
5106 +extern void apc_free_functions(apc_function_t* src, apc_context_t* ctxt);
5107 +extern void apc_free_classes(apc_class_t* src, apc_context_t* ctxt);
5108 +extern void apc_free_zval(zval* src, apc_context_t* ctxt);
5109 +#endif
5110 +
5111 +/*
5112 + * These "copy-for-execution" functions must be called after retrieving an
5113 + * object from the shared cache. They do the minimal amount of work necessary
5114 + * to allow multiple processes to concurrently execute the same VM data
5115 + * structures.
5116 + */
5117 +
5118 +extern zend_op_array* apc_copy_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC);
5119 +extern zend_function* apc_copy_function_for_execution(zend_function* src, apc_context_t* ctxt);
5120 +extern zend_class_entry* apc_copy_class_entry_for_execution(zend_class_entry* src, apc_context_t* ctxt);
5121 +
5122 +/*
5123 + * The "free-after-execution" function performs a cursory clean up of the class data
5124 + * This is required to minimize memory leak warnings and to ensure correct destructor
5125 + * ordering of some variables.
5126 + */
5127 +extern void apc_free_class_entry_after_execution(zend_class_entry* src);
5128 +
5129 +/*
5130 + * Optimization callback definition and registration function.
5131 + */
5132 +typedef zend_op_array* (*apc_optimize_function_t) (zend_op_array* TSRMLS_DC);
5133 +extern apc_optimize_function_t apc_register_optimizer(apc_optimize_function_t optimizer TSRMLS_DC);
5134 +
5135 +/*
5136 + * To handle __COMPILER_HALT_OFFSET__
5137 + */
5138 +long apc_file_halt_offset(const char* filename);
5139 +void apc_do_halt_compiler_register(const char *filename, long halt_offset TSRMLS_DC);
5140 +
5141 +#endif
5142 +
5143 +/*
5144 + * Local variables:
5145 + * tab-width: 4
5146 + * c-basic-offset: 4
5147 + * End:
5148 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5149 + * vim<600: expandtab sw=4 ts=4 sts=4
5150 + */
5151 diff -Naur php-5.3.1.orig/ext/apc/apc_debug.c php-5.3.1/ext/apc/apc_debug.c
5152 --- php-5.3.1.orig/ext/apc/apc_debug.c 1970-01-01 01:00:00.000000000 +0100
5153 +++ php-5.3.1/ext/apc/apc_debug.c 1970-01-01 10:13:08.000000000 +0100
5154 @@ -0,0 +1,57 @@
5155 +/*
5156 + +----------------------------------------------------------------------+
5157 + | APC |
5158 + +----------------------------------------------------------------------+
5159 + | Copyright (c) 2006-2008 The PHP Group |
5160 + +----------------------------------------------------------------------+
5161 + | This source file is subject to version 3.01 of the PHP license, |
5162 + | that is bundled with this package in the file LICENSE, and is |
5163 + | available through the world-wide-web at the following url: |
5164 + | http://www.php.net/license/3_01.txt |
5165 + | If you did not receive a copy of the PHP license and are unable to |
5166 + | obtain it through the world-wide-web, please send a note to |
5167 + | license@php.net so we can mail you a copy immediately. |
5168 + +----------------------------------------------------------------------+
5169 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
5170 + | Arun C. Murthy <arunc@yahoo-inc.com> |
5171 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
5172 + +----------------------------------------------------------------------+
5173 +
5174 + This software was contributed to PHP by Community Connect Inc. in 2002
5175 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5176 + Future revisions and derivatives of this source code must acknowledge
5177 + Community Connect Inc. as the original contributor of this module by
5178 + leaving this note intact in the source code.
5179 +
5180 + All other licensing and usage conditions are those of the PHP Group.
5181 +*/
5182 +
5183 +/* $Id: apc_debug.c 268255 2008-11-04 05:42:11Z rasmus $ */
5184 +#include "apc.h"
5185 +#include <stdio.h>
5186 +#include "zend_compile.h"
5187 +
5188 +#ifdef __DEBUG_APC__
5189 +
5190 +#include <dlfcn.h>
5191 +
5192 +/* keep track of vld_dump_oparray() signature */
5193 +typedef void (*vld_dump_f) (zend_op_array * TSRMLS_DC);
5194 +
5195 +#endif
5196 +
5197 +void dump(zend_op_array *op_array TSRMLS_DC)
5198 +{
5199 +#ifdef __DEBUG_APC__
5200 + vld_dump_f dump_op_array = dlsym(NULL, "vld_dump_oparray");
5201 +
5202 + if(dump_op_array)
5203 + {
5204 + dump_op_array(op_array TSRMLS_CC);
5205 + }
5206 + else
5207 + {
5208 + apc_wprint("vld is not installed or something even worse.");
5209 + }
5210 +#endif
5211 +}
5212 diff -Naur php-5.3.1.orig/ext/apc/apc_debug.h php-5.3.1/ext/apc/apc_debug.h
5213 --- php-5.3.1.orig/ext/apc/apc_debug.h 1970-01-01 01:00:00.000000000 +0100
5214 +++ php-5.3.1/ext/apc/apc_debug.h 1970-01-01 10:13:08.000000000 +0100
5215 @@ -0,0 +1 @@
5216 +void dump(zend_op_array * TSRMLS_DC);
5217 diff -Naur php-5.3.1.orig/ext/apc/apc.dsp php-5.3.1/ext/apc/apc.dsp
5218 --- php-5.3.1.orig/ext/apc/apc.dsp 1970-01-01 01:00:00.000000000 +0100
5219 +++ php-5.3.1/ext/apc/apc.dsp 1970-01-01 10:13:08.000000000 +0100
5220 @@ -0,0 +1,207 @@
5221 +# Microsoft Developer Studio Project File - Name="apc" - Package Owner=<4>
5222 +# Microsoft Developer Studio Generated Build File, Format Version 6.00
5223 +# ** DO NOT EDIT **
5224 +
5225 +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
5226 +
5227 +CFG=apc - Win32 Debug_TS
5228 +!MESSAGE This is not a valid makefile. To build this project using NMAKE,
5229 +!MESSAGE use the Export Makefile command and run
5230 +!MESSAGE
5231 +!MESSAGE NMAKE /f "apc.mak".
5232 +!MESSAGE
5233 +!MESSAGE You can specify a configuration when running NMAKE
5234 +!MESSAGE by defining the macro CFG on the command line. For example:
5235 +!MESSAGE
5236 +!MESSAGE NMAKE /f "apc.mak" CFG="apc - Win32 Debug_TS"
5237 +!MESSAGE
5238 +!MESSAGE Possible choices for configuration are:
5239 +!MESSAGE
5240 +!MESSAGE "apc - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
5241 +!MESSAGE "apc - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
5242 +!MESSAGE
5243 +
5244 +# Begin Project
5245 +# PROP AllowPerConfigDependencies 0
5246 +# PROP Scc_ProjName ""
5247 +# PROP Scc_LocalPath ""
5248 +CPP=cl.exe
5249 +MTL=midl.exe
5250 +RSC=rc.exe
5251 +
5252 +!IF "$(CFG)" == "apc - Win32 Debug_TS"
5253 +
5254 +# PROP BASE Use_MFC 0
5255 +# PROP BASE Use_Debug_Libraries 1
5256 +# PROP BASE Output_Dir "Debug_TS"
5257 +# PROP BASE Intermediate_Dir "Debug_TS"
5258 +# PROP BASE Target_Dir ""
5259 +# PROP Use_MFC 0
5260 +# PROP Use_Debug_Libraries 1
5261 +# PROP Output_Dir "Debug_TS"
5262 +# PROP Intermediate_Dir "Debug_TS"
5263 +# PROP Ignore_Export_Lib 0
5264 +# PROP Target_Dir ""
5265 +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /GZ /c
5266 +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\win32" /I "..\..\..\php4\regex" /D "TSRM_LOCKS" /D HAVE_APC=1 /D "COMPILE_DL_APC" /D ZEND_DEBUG=1 /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /GZ /c
5267 +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
5268 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
5269 +# ADD BASE RSC /l 0x409 /d "_DEBUG"
5270 +# ADD RSC /l 0x409 /d "_DEBUG"
5271 +BSC32=bscmake.exe
5272 +# ADD BASE BSC32 /nologo
5273 +# ADD BSC32 /nologo
5274 +LINK32=link.exe
5275 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
5276 +# ADD LINK32 php4ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug_TS/php_apc.dll" /pdbtype:sept /libpath:"..\..\..\php4\Debug_TS"
5277 +
5278 +!ELSEIF "$(CFG)" == "apc - Win32 Release_TS"
5279 +
5280 +# PROP BASE Use_MFC 0
5281 +# PROP BASE Use_Debug_Libraries 0
5282 +# PROP BASE Output_Dir "Release_TS"
5283 +# PROP BASE Intermediate_Dir "Release_TS"
5284 +# PROP BASE Target_Dir ""
5285 +# PROP Use_MFC 0
5286 +# PROP Use_Debug_Libraries 0
5287 +# PROP Output_Dir "Release_TS"
5288 +# PROP Intermediate_Dir "Release_TS"
5289 +# PROP Ignore_Export_Lib 0
5290 +# PROP Target_Dir ""
5291 +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /c
5292 +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\php4" /I "..\..\..\php4\main" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\win32" /I "..\..\..\php4\regex" /D "TSRM_LOCKS" /D HAVE_APC=1 /D "COMPILE_DL_APC" /D ZEND_DEBUG=0 /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APC_EXPORTS" /YX /FD /c
5293 +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
5294 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
5295 +# ADD BASE RSC /l 0x409 /d "NDEBUG"
5296 +# ADD RSC /l 0x409 /d "NDEBUG"
5297 +BSC32=bscmake.exe
5298 +# ADD BASE BSC32 /nologo
5299 +# ADD BSC32 /nologo
5300 +LINK32=link.exe
5301 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
5302 +# ADD LINK32 php4ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../Release_TS/php_apc.dll" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline"
5303 +
5304 +!ENDIF
5305 +
5306 +# Begin Target
5307 +
5308 +# Name "apc - Win32 Debug_TS"
5309 +# Name "apc - Win32 Release_TS"
5310 +# Begin Group "Source Files"
5311 +
5312 +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
5313 +# Begin Source File
5314 +
5315 +SOURCE=.\apc.c
5316 +# End Source File
5317 +# Begin Source File
5318 +
5319 +SOURCE=.\apc_cache.c
5320 +# End Source File
5321 +# Begin Source File
5322 +
5323 +SOURCE=.\apc_compile.c
5324 +# End Source File
5325 +# Begin Source File
5326 +
5327 +SOURCE=.\apc_debug.c
5328 +# End Source File
5329 +# Begin Source File
5330 +
5331 +SOURCE=.\apc_fcntl_win32.c
5332 +# End Source File
5333 +# Begin Source File
5334 +
5335 +SOURCE=.\apc_main.c
5336 +# End Source File
5337 +# Begin Source File
5338 +
5339 +SOURCE=.\apc_rfc1867.c
5340 +# End Source File
5341 +# Begin Source File
5342 +
5343 +SOURCE=.\apc_shm.c
5344 +# End Source File
5345 +# Begin Source File
5346 +
5347 +SOURCE=.\apc_sma.c
5348 +# End Source File
5349 +# Begin Source File
5350 +
5351 +SOURCE=.\apc_stack.c
5352 +# End Source File
5353 +# Begin Source File
5354 +
5355 +SOURCE=.\apc_zend.c
5356 +# End Source File
5357 +# Begin Source File
5358 +
5359 +SOURCE=.\php_apc.c
5360 +# End Source File
5361 +# End Group
5362 +# Begin Group "Header Files"
5363 +
5364 +# PROP Default_Filter "h;hpp;hxx;hm;inl"
5365 +# Begin Source File
5366 +
5367 +SOURCE=.\apc.h
5368 +# End Source File
5369 +# Begin Source File
5370 +
5371 +SOURCE=.\apc_cache.h
5372 +# End Source File
5373 +# Begin Source File
5374 +
5375 +SOURCE=.\apc_compile.h
5376 +# End Source File
5377 +# Begin Source File
5378 +
5379 +SOURCE=.\apc_debug.h
5380 +# End Source File
5381 +# Begin Source File
5382 +
5383 +SOURCE=.\apc_fcntl.h
5384 +# End Source File
5385 +# Begin Source File
5386 +
5387 +SOURCE=.\apc_globals.h
5388 +# End Source File
5389 +# Begin Source File
5390 +
5391 +SOURCE=.\apc_lock.h
5392 +# End Source File
5393 +# Begin Source File
5394 +
5395 +SOURCE=.\apc_main.h
5396 +# End Source File
5397 +# Begin Source File
5398 +
5399 +SOURCE=.\apc_php.h
5400 +# End Source File
5401 +# Begin Source File
5402 +
5403 +SOURCE=.\apc_shm.h
5404 +# End Source File
5405 +# Begin Source File
5406 +
5407 +SOURCE=.\apc_sma.h
5408 +# End Source File
5409 +# Begin Source File
5410 +
5411 +SOURCE=.\apc_stack.h
5412 +# End Source File
5413 +# Begin Source File
5414 +
5415 +SOURCE=.\apc_zend.h
5416 +# End Source File
5417 +# Begin Source File
5418 +
5419 +SOURCE=.\php_apc.h
5420 +# End Source File
5421 +# End Group
5422 +# Begin Group "Resource Files"
5423 +
5424 +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
5425 +# End Group
5426 +# End Target
5427 +# End Project
5428 diff -ubrN php-5.2.5-orig/ext/apc/apc_fcntl.c php-5.2.5/ext/apc/apc_fcntl.c
5429 --- php-5.2.5-orig/ext/apc/apc_fcntl.c 1969-12-31 18:00:00.000000000 -0600
5430 +++ php-5.2.5/ext/apc/apc_fcntl.c 2007-12-26 16:51:32.000000000 -0600
5431 @@ -0,0 +1,118 @@
5432 +/*
5433 + +----------------------------------------------------------------------+
5434 + | APC |
5435 + +----------------------------------------------------------------------+
5436 + | Copyright (c) 2006-2008 The PHP Group |
5437 + +----------------------------------------------------------------------+
5438 + | This source file is subject to version 3.01 of the PHP license, |
5439 + | that is bundled with this package in the file LICENSE, and is |
5440 + | available through the world-wide-web at the following url: |
5441 + | http://www.php.net/license/3_01.txt |
5442 + | If you did not receive a copy of the PHP license and are unable to |
5443 + | obtain it through the world-wide-web, please send a note to |
5444 + | license@php.net so we can mail you a copy immediately. |
5445 + +----------------------------------------------------------------------+
5446 + | Authors: George Schlossnagle <george@omniti.com> |
5447 + | Rasmus Lerdorf <rasmus@php.net> |
5448 + +----------------------------------------------------------------------+
5449 +
5450 + This software was contributed to PHP by Community Connect Inc. in 2002
5451 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5452 + Future revisions and derivatives of this source code must acknowledge
5453 + Community Connect Inc. as the original contributor of this module by
5454 + leaving this note intact in the source code.
5455 +
5456 + All other licensing and usage conditions are those of the PHP Group.
5457 +
5458 + */
5459 +
5460 +/* $Id: apc_fcntl.c 268255 2008-11-04 05:42:11Z rasmus $ */
5461 +
5462 +#include "apc.h"
5463 +
5464 +#ifdef APC_FCNTL_LOCKS
5465 +
5466 +#include "apc_fcntl.h"
5467 +#include <unistd.h>
5468 +#include <fcntl.h>
5469 +
5470 +int apc_fcntl_create(const char* pathname)
5471 +{
5472 + int fd;
5473 + if(pathname == NULL) {
5474 + char lock_path[] = "/tmp/.apc.XXXXXX";
5475 + mktemp(lock_path);
5476 + fd = open(lock_path, O_RDWR|O_CREAT, 0666);
5477 + if(fd > 0 ) {
5478 + unlink(lock_path);
5479 + return fd;
5480 + } else {
5481 + apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", lock_path);
5482 + return -1;
5483 + }
5484 + }
5485 + fd = open(pathname, O_RDWR|O_CREAT, 0666);
5486 + if(fd > 0 ) {
5487 + unlink(pathname);
5488 + return fd;
5489 + }
5490 + apc_eprint("apc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
5491 + return -1;
5492 +}
5493 +
5494 +void apc_fcntl_destroy(int fd)
5495 +{
5496 + close(fd);
5497 +}
5498 +
5499 +static int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
5500 +{
5501 + int ret;
5502 + struct flock lock;
5503 +
5504 + lock.l_type = type;
5505 + lock.l_start = offset;
5506 + lock.l_whence = whence;
5507 + lock.l_len = len;
5508 + lock.l_pid = 0;
5509 +
5510 + do { ret = fcntl(fd, cmd, &lock) ; }
5511 + while(ret < 0 && errno == EINTR);
5512 + return(ret);
5513 +}
5514 +
5515 +void apc_fcntl_lock(int fd)
5516 +{
5517 + if(lock_reg(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0) < 0) {
5518 + apc_eprint("apc_fcntl_lock failed:");
5519 + }
5520 +}
5521 +
5522 +void apc_fcntl_rdlock(int fd)
5523 +{
5524 + if(lock_reg(fd, F_SETLKW, F_RDLCK, 0, SEEK_SET, 0) < 0) {
5525 + apc_eprint("apc_fcntl_rdlock failed:");
5526 + }
5527 +}
5528 +
5529 +zend_bool apc_fcntl_nonblocking_lock(int fd)
5530 +{
5531 + if(lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0) < 0) {
5532 + if(errno==EACCES||errno==EAGAIN) return 0;
5533 + else apc_eprint("apc_fcntl_lock failed:");
5534 + }
5535 + return 1;
5536 +}
5537 +
5538 +void apc_fcntl_unlock(int fd)
5539 +{
5540 + if(lock_reg(fd, F_SETLKW, F_UNLCK, 0, SEEK_SET, 0) < 0) {
5541 + apc_eprint("apc_fcntl_unlock failed:");
5542 + }
5543 +}
5544 +
5545 +#endif /* APC_FCNTL_LOCKS */
5546 +
5547 +/*
5548 + * Local variables:
5549 + * tab-width: 4
5550 + * c-basic-offset: 4
5551 + * End:
5552 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5553 + * vim<600: expandtab sw=4 ts=4 sts=4
5554 + */
5555 diff -Naur php-5.3.1.orig/ext/apc/apc_fcntl.h php-5.3.1/ext/apc/apc_fcntl.h
5556 --- php-5.3.1.orig/ext/apc/apc_fcntl.h 1970-01-01 01:00:00.000000000 +0100
5557 +++ php-5.3.1/ext/apc/apc_fcntl.h 1970-01-01 10:13:08.000000000 +0100
5558 @@ -0,0 +1,50 @@
5559 +/*
5560 + +----------------------------------------------------------------------+
5561 + | APC |
5562 + +----------------------------------------------------------------------+
5563 + | Copyright (c) 2006-2008 The PHP Group |
5564 + +----------------------------------------------------------------------+
5565 + | This source file is subject to version 3.01 of the PHP license, |
5566 + | that is bundled with this package in the file LICENSE, and is |
5567 + | available through the world-wide-web at the following url: |
5568 + | http://www.php.net/license/3_01.txt. |
5569 + | If you did not receive a copy of the PHP license and are unable to |
5570 + | obtain it through the world-wide-web, please send a note to |
5571 + | license@php.net so we can mail you a copy immediately. |
5572 + +----------------------------------------------------------------------+
5573 + | Authors: George Schlossnagle <george@omniti.com> |
5574 + | Rasmus Lerdorf <rasmus@php.net> |
5575 + +----------------------------------------------------------------------+
5576 +
5577 + This software was contributed to PHP by Community Connect Inc. in 2002
5578 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5579 + Future revisions and derivatives of this source code must acknowledge
5580 + Community Connect Inc. as the original contributor of this module by
5581 + leaving this note intact in the source code.
5582 +
5583 + All other licensing and usage conditions are those of the PHP Group.
5584 +
5585 + */
5586 +
5587 +/* $Id: apc_fcntl.h 268255 2008-11-04 05:42:11Z rasmus $ */
5588 +
5589 +#ifndef APC_FCNTL_H
5590 +#define APC_FCNTL_H
5591 +
5592 +
5593 +extern int apc_fcntl_create(const char* pathname);
5594 +extern void apc_fcntl_destroy(int fd);
5595 +extern void apc_fcntl_lock(int fd);
5596 +extern void apc_fcntl_rdlock(int fd);
5597 +extern void apc_fcntl_unlock(int fd);
5598 +extern unsigned char apc_fcntl_nonblocking_lock(int fd);
5599 +#endif
5600 +
5601 +/*
5602 + * Local variables:
5603 + * tab-width: 4
5604 + * c-basic-offset: 4
5605 + * End:
5606 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5607 + * vim<600: expandtab sw=4 ts=4 sts=4
5608 + */
5609 diff -Naur php-5.3.1.orig/ext/apc/apc_fcntl_win32.c php-5.3.1/ext/apc/apc_fcntl_win32.c
5610 --- php-5.3.1.orig/ext/apc/apc_fcntl_win32.c 1970-01-01 01:00:00.000000000 +0100
5611 +++ php-5.3.1/ext/apc/apc_fcntl_win32.c 1970-01-01 10:13:08.000000000 +0100
5612 @@ -0,0 +1,117 @@
5613 +/*
5614 + +----------------------------------------------------------------------+
5615 + | APC |
5616 + +----------------------------------------------------------------------+
5617 + | Copyright (c) 2006-2008 The PHP Group |
5618 + +----------------------------------------------------------------------+
5619 + | This source file is subject to version 3.01 of the PHP license, |
5620 + | that is bundled with this package in the file LICENSE, and is |
5621 + | available through the world-wide-web at the following url: |
5622 + | http://www.php.net/license/3_01.txt |
5623 + | If you did not receive a copy of the PHP license and are unable to |
5624 + | obtain it through the world-wide-web, please send a note to |
5625 + | license@php.net so we can mail you a copy immediately. |
5626 + +----------------------------------------------------------------------+
5627 + | Authors: George Schlossnagle <george@omniti.com> |
5628 + | Edin Kadribasic <edink@php.net> |
5629 + +----------------------------------------------------------------------+
5630 +
5631 + This software was contributed to PHP by Community Connect Inc. in 2002
5632 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5633 + Future revisions and derivatives of this source code must acknowledge
5634 + Community Connect Inc. as the original contributor of this module by
5635 + leaving this note intact in the source code.
5636 +
5637 + All other licensing and usage conditions are those of the PHP Group.
5638 +
5639 + */
5640 +
5641 +/* $Id: apc_fcntl_win32.c 268255 2008-11-04 05:42:11Z rasmus $ */
5642 +
5643 +#include "apc_fcntl.h"
5644 +#include "apc.h"
5645 +#include <php.h>
5646 +#include <win32/flock.h>
5647 +#include <io.h>
5648 +#include <fcntl.h>
5649 +#include <sys/types.h>
5650 +#include <sys/stat.h>
5651 +
5652 +int apc_fcntl_create(const char* pathname)
5653 +{
5654 + char *lock_file = emalloc(MAXPATHLEN);
5655 + HANDLE fd;
5656 + DWORD tmplen;
5657 + static int i=0;
5658 +
5659 + tmplen = GetTempPath(MAXPATHLEN, lock_file);
5660 + if (!tmplen) {
5661 + efree(lock_file);
5662 + return -1;
5663 + }
5664 +
5665 + snprintf(lock_file + tmplen, MAXPATHLEN - tmplen - 1, "apc.lock.%d", i++);
5666 +
5667 + fd = CreateFile(lock_file,
5668 + GENERIC_READ | GENERIC_WRITE,
5669 + FILE_SHARE_READ | FILE_SHARE_WRITE,
5670 + NULL,
5671 + OPEN_ALWAYS,
5672 + FILE_ATTRIBUTE_NORMAL,
5673 + NULL);
5674 +
5675 +
5676 + if (fd == INVALID_HANDLE_VALUE) {
5677 + apc_eprint("apc_fcntl_create: could not open %s", lock_file);
5678 + efree(lock_file);
5679 + return -1;
5680 + }
5681 +
5682 + efree(lock_file);
5683 + return (int)fd;
5684 +}
5685 +
5686 +void apc_fcntl_destroy(int fd)
5687 +{
5688 + CloseHandle((HANDLE)fd);
5689 +}
5690 +
5691 +void apc_fcntl_lock(int fd)
5692 +{
5693 + OVERLAPPED offset = {0, 0, 0, 0, NULL};
5694 +
5695 + if (!LockFileEx((HANDLE)fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &offset)) {
5696 + apc_eprint("apc_fcntl_lock failed errno:%d", GetLastError());
5697 + }
5698 +}
5699 +
5700 +void apc_fcntl_rdlock(int fd)
5701 +{
5702 + OVERLAPPED offset = {0, 0, 0, 0, NULL};
5703 +
5704 + if (!LockFileEx((HANDLE)fd, 0, 0, 1, 0, &offset)) {
5705 + apc_eprint("apc_fcntl_rdlock failed errno:%d", GetLastError());
5706 + }
5707 +}
5708 +
5709 +void apc_fcntl_unlock(int fd)
5710 +{
5711 + OVERLAPPED offset = {0, 0, 0, 0, NULL};
5712 +
5713 + if (!UnlockFileEx((HANDLE)fd, 0, 1, 0, &offset)) {
5714 + DWORD error_code = GetLastError();
5715 + /* Ignore already unlocked error */
5716 + if (error_code != ERROR_NOT_LOCKED) {
5717 + apc_eprint("apc_fcntl_unlock failed errno:%d", error_code);
5718 + }
5719 + }
5720 +}
5721 +
5722 +/*
5723 + * Local variables:
5724 + * tab-width: 4
5725 + * c-basic-offset: 4
5726 + * End:
5727 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5728 + * vim<600: expandtab sw=4 ts=4 sts=4
5729 + */
5730 diff -Naur php-5.3.1.orig/ext/apc/apc_globals.h php-5.3.1/ext/apc/apc_globals.h
5731 --- php-5.3.1.orig/ext/apc/apc_globals.h 1970-01-01 01:00:00.000000000 +0100
5732 +++ php-5.3.1/ext/apc/apc_globals.h 1970-01-01 10:13:08.000000000 +0100
5733 @@ -0,0 +1,143 @@
5734 +/*
5735 + +----------------------------------------------------------------------+
5736 + | APC |
5737 + +----------------------------------------------------------------------+
5738 + | Copyright (c) 2006-2008 The PHP Group |
5739 + +----------------------------------------------------------------------+
5740 + | This source file is subject to version 3.01 of the PHP license, |
5741 + | that is bundled with this package in the file LICENSE, and is |
5742 + | available through the world-wide-web at the following url: |
5743 + | http://www.php.net/license/3_01.txt. |
5744 + | If you did not receive a copy of the PHP license and are unable to |
5745 + | obtain it through the world-wide-web, please send a note to |
5746 + | license@php.net so we can mail you a copy immediately. |
5747 + +----------------------------------------------------------------------+
5748 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
5749 + | George Schlossnagle <george@omniti.com> |
5750 + | Rasmus Lerdorf <rasmus@php.net> |
5751 + | Arun C. Murthy <arunc@yahoo-inc.com> |
5752 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
5753 + +----------------------------------------------------------------------+
5754 +
5755 + This software was contributed to PHP by Community Connect Inc. in 2002
5756 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5757 + Future revisions and derivatives of this source code must acknowledge
5758 + Community Connect Inc. as the original contributor of this module by
5759 + leaving this note intact in the source code.
5760 +
5761 + All other licensing and usage conditions are those of the PHP Group.
5762 +
5763 + */
5764 +
5765 +/* $Id: apc_globals.h 284222 2009-07-17 01:23:57Z shire $ */
5766 +
5767 +#ifndef APC_GLOBALS_H
5768 +#define APC_GLOBALS_H
5769 +
5770 +#include "apc_cache.h"
5771 +#include "apc_stack.h"
5772 +#include "apc_php.h"
5773 +
5774 +/* {{{ struct apc_rfc1867_data */
5775 +
5776 +typedef struct _apc_rfc1867_data apc_rfc1867_data;
5777 +
5778 +struct _apc_rfc1867_data {
5779 + char tracking_key[64];
5780 + int key_length;
5781 + size_t content_length;
5782 + char filename[128];
5783 + char name[64];
5784 + char *temp_filename;
5785 + int cancel_upload;
5786 + double start_time;
5787 + size_t bytes_processed;
5788 + size_t prev_bytes_processed;
5789 + int update_freq;
5790 + double rate;
5791 +};
5792 +/* }}} */
5793 +
5794 +ZEND_BEGIN_MODULE_GLOBALS(apc)
5795 + /* configuration parameters */
5796 + zend_bool enabled; /* if true, apc is enabled (defaults to true) */
5797 + long shm_segments; /* number of shared memory segments to use */
5798 + long shm_size; /* size of each shared memory segment (in MB) */
5799 + long num_files_hint; /* parameter to apc_cache_create */
5800 + long user_entries_hint;
5801 + long gc_ttl; /* parameter to apc_cache_create */
5802 + long ttl; /* parameter to apc_cache_create */
5803 + long user_ttl;
5804 +#if APC_MMAP
5805 + char *mmap_file_mask; /* mktemp-style file-mask to pass to mmap */
5806 +#endif
5807 + char** filters; /* array of regex filters that prevent caching */
5808 + void* compiled_filters; /* compiled regex filters */
5809 +
5810 + /* module variables */
5811 + zend_bool initialized; /* true if module was initialized */
5812 + apc_stack_t* cache_stack; /* the stack of cached executable code */
5813 + zend_bool cache_by_default; /* true if files should be cached unless filtered out */
5814 + /* false if files should only be cached if filtered in */
5815 + long file_update_protection; /* Age in seconds before a file is eligible to be cached - 0 to disable */
5816 + zend_bool enable_cli; /* Flag to override turning APC off for CLI */
5817 + long max_file_size; /* Maximum size of file, in bytes that APC will be allowed to cache */
5818 + zend_bool fpstat; /* true if fullpath includes should be stat'ed */
5819 + zend_bool canonicalize; /* true if relative paths should be canonicalized in no-stat mode */
5820 + zend_bool stat_ctime; /* true if ctime in addition to mtime should be checked */
5821 + zend_bool write_lock; /* true for a global write lock */
5822 + zend_bool report_autofilter; /* true for auto-filter warnings */
5823 + zend_bool include_once; /* Override the ZEND_INCLUDE_OR_EVAL opcode handler to avoid pointless fopen()s [still experimental] */
5824 + apc_optimize_function_t apc_optimize_function; /* optimizer function callback */
5825 +#ifdef MULTIPART_EVENT_FORMDATA
5826 + zend_bool rfc1867; /* Flag to enable rfc1867 handler */
5827 + char* rfc1867_prefix; /* Key prefix */
5828 + char* rfc1867_name; /* Name of hidden field to activate upload progress/key suffix */
5829 + double rfc1867_freq; /* Update frequency as percentage or bytes */
5830 + long rfc1867_ttl; /* TTL for rfc1867 entries */
5831 + apc_rfc1867_data rfc1867_data;/* Per-request data */
5832 +#endif
5833 + HashTable copied_zvals; /* my_copy recursion detection list */
5834 + zend_bool force_file_update; /* force files to be updated during apc_compile_file */
5835 + char canon_path[MAXPATHLEN]; /* canonical path for key data */
5836 +#if APC_FILEHITS
5837 + zval *filehits; /* Files that came from the cache for this request */
5838 +#endif
5839 + zend_bool coredump_unmap; /* Trap signals that coredump and unmap shared memory */
5840 + apc_cache_t *current_cache; /* current cache being modified/read */
5841 + char *preload_path;
5842 + zend_bool file_md5; /* record md5 hash of files */
5843 + void *apc_bd_alloc_ptr; /* bindump alloc() ptr */
5844 + void *apc_bd_alloc_ubptr; /* bindump alloc() upper bound ptr */
5845 + HashTable apc_bd_alloc_list; /* bindump alloc() ptr list */
5846 + zend_bool use_request_time; /* use the SAPI request start time for TTL */
5847 + zend_bool lazy_functions; /* enable/disable lazy function loading */
5848 + HashTable *lazy_function_table; /* lazy function entry table */
5849 + zend_bool lazy_classes; /* enable/disable lazy class loading */
5850 + HashTable *lazy_class_table; /* lazy class entry table */
5851 +ZEND_END_MODULE_GLOBALS(apc)
5852 +
5853 +/* (the following declaration is defined in php_apc.c) */
5854 +ZEND_EXTERN_MODULE_GLOBALS(apc)
5855 +
5856 +#ifdef ZTS
5857 +# define APCG(v) TSRMG(apc_globals_id, zend_apc_globals *, v)
5858 +#else
5859 +# define APCG(v) (apc_globals.v)
5860 +#endif
5861 +
5862 +/* True globals */
5863 +extern apc_cache_t* apc_cache; /* the global compiler cache */
5864 +extern apc_cache_t* apc_user_cache; /* the global user content cache */
5865 +extern void* apc_compiled_filters; /* compiled filters */
5866 +
5867 +#endif
5868 +
5869 +/*
5870 + * Local variables:
5871 + * tab-width: 4
5872 + * c-basic-offset: 4
5873 + * End:
5874 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
5875 + * vim<600: expandtab sw=4 ts=4 sts=4
5876 + */
5877 diff -Naur php-5.3.1.orig/ext/apc/apc.h php-5.3.1/ext/apc/apc.h
5878 --- php-5.3.1.orig/ext/apc/apc.h 1970-01-01 01:00:00.000000000 +0100
5879 +++ php-5.3.1/ext/apc/apc.h 1970-01-01 10:13:08.000000000 +0100
5880 @@ -0,0 +1,126 @@
5881 +/*
5882 + +----------------------------------------------------------------------+
5883 + | APC |
5884 + +----------------------------------------------------------------------+
5885 + | Copyright (c) 2006-2008 The PHP Group |
5886 + +----------------------------------------------------------------------+
5887 + | This source file is subject to version 3.01 of the PHP license, |
5888 + | that is bundled with this package in the file LICENSE, and is |
5889 + | available through the world-wide-web at the following url: |
5890 + | http://www.php.net/license/3_01.txt |
5891 + | If you did not receive a copy of the PHP license and are unable to |
5892 + | obtain it through the world-wide-web, please send a note to |
5893 + | license@php.net so we can mail you a copy immediately. |
5894 + +----------------------------------------------------------------------+
5895 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
5896 + | George Schlossnagle <george@omniti.com> |
5897 + | Rasmus Lerdorf <rasmus@php.net> |
5898 + | Arun C. Murthy <arunc@yahoo-inc.com> |
5899 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
5900 + +----------------------------------------------------------------------+
5901 +
5902 + This software was contributed to PHP by Community Connect Inc. in 2002
5903 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
5904 + Future revisions and derivatives of this source code must acknowledge
5905 + Community Connect Inc. as the original contributor of this module by
5906 + leaving this note intact in the source code.
5907 +
5908 + All other licensing and usage conditions are those of the PHP Group.
5909 +
5910 + */
5911 +
5912 +/* $Id: apc.h 276125 2009-02-19 01:02:59Z shire $ */
5913 +
5914 +#ifndef APC_H
5915 +#define APC_H
5916 +
5917 +/*
5918 + * This module defines utilities and helper functions used elsewhere in APC.
5919 + */
5920 +
5921 +/* Commonly needed C library headers. */
5922 +#include <assert.h>
5923 +#include <errno.h>
5924 +#include <stdarg.h>
5925 +#include <stdio.h>
5926 +#include <stdlib.h>
5927 +#include <string.h>
5928 +#include <time.h>
5929 +
5930 +/* UNIX headers (needed for struct stat) */
5931 +#include <sys/types.h>
5932 +#include <sys/stat.h>
5933 +#ifndef PHP_WIN32
5934 +#include <unistd.h>
5935 +#endif
5936 +
5937 +#ifdef HAVE_CONFIG_H
5938 +#include <config.h>
5939 +#endif
5940 +
5941 +#include "php.h"
5942 +#include "main/php_streams.h"
5943 +
5944 +/* log levels constants (see my_log) */
5945 +enum { APC_DBG, APC_NOTICE, APC_WARNING, APC_ERROR };
5946 +
5947 +/* typedefs for extensible memory allocators */
5948 +typedef void* (*apc_malloc_t)(size_t);
5949 +typedef void (*apc_free_t) (void*);
5950 +
5951 +/* wrappers for memory allocation routines */
5952 +extern void* apc_emalloc(size_t n);
5953 +extern void* apc_erealloc(void* p, size_t n);
5954 +extern void apc_efree(void* p);
5955 +extern char* apc_estrdup(const char* s);
5956 +extern void* apc_xstrdup(const char* s, apc_malloc_t f);
5957 +extern void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f);
5958 +
5959 +/* console display functions */
5960 +extern void apc_eprint(const char* fmt, ...);
5961 +extern void apc_wprint(const char* fmt, ...);
5962 +extern void apc_dprint(const char* fmt, ...);
5963 +extern void apc_nprint(const char* fmt, ...);
5964 +
5965 +/* string and text manipulation */
5966 +extern char* apc_append(const char* s, const char* t);
5967 +extern char* apc_substr(const char* s, int start, int length);
5968 +extern char** apc_tokenize(const char* s, char delim);
5969 +
5970 +/* filesystem functions */
5971 +
5972 +typedef struct apc_fileinfo_t
5973 +{
5974 + char fullpath[MAXPATHLEN+1];
5975 + php_stream_statbuf st_buf;
5976 +} apc_fileinfo_t;
5977 +
5978 +extern int apc_search_paths(const char* filename, const char* path, apc_fileinfo_t* fileinfo);
5979 +
5980 +/* regular expression wrapper functions */
5981 +extern void* apc_regex_compile_array(char* patterns[] TSRMLS_DC);
5982 +extern void apc_regex_destroy_array(void* p);
5983 +extern int apc_regex_match_array(void* p, const char* input);
5984 +
5985 +/* apc_crc32: returns the CRC-32 checksum of the first len bytes in buf */
5986 +extern unsigned int apc_crc32(const char* buf, int len);
5987 +
5988 +/* apc_flip_hash flips keys and values for faster searching */
5989 +extern HashTable* apc_flip_hash(HashTable *hash);
5990 +
5991 +#define APC_NEGATIVE_MATCH 1
5992 +#define APC_POSITIVE_MATCH 2
5993 +
5994 +#define apc_time() \
5995 + (APCG(use_request_time) ? sapi_get_request_time(TSRMLS_C) : time(0));
5996 +
5997 +#endif
5998 +
5999 +/*
6000 + * Local variables:
6001 + * tab-width: 4
6002 + * c-basic-offset: 4
6003 + * End:
6004 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
6005 + * vim<600: expandtab sw=4 ts=4 sts=4
6006 + */
6007 diff -Naur php-5.3.1.orig/ext/apc/apc_iterator.c php-5.3.1/ext/apc/apc_iterator.c
6008 --- php-5.3.1.orig/ext/apc/apc_iterator.c 1970-01-01 01:00:00.000000000 +0100
6009 +++ php-5.3.1/ext/apc/apc_iterator.c 1970-01-01 10:13:08.000000000 +0100
6010 @@ -0,0 +1,634 @@
6011 +/*
6012 + +----------------------------------------------------------------------+
6013 + | APC |
6014 + +----------------------------------------------------------------------+
6015 + | Copyright (c) 2008 The PHP Group |
6016 + +----------------------------------------------------------------------+
6017 + | This source file is subject to version 3.01 of the PHP license, |
6018 + | that is bundled with this package in the file LICENSE, and is |
6019 + | available through the world-wide-web at the following url: |
6020 + | http://www.php.net/license/3_01.txt |
6021 + | If you did not receive a copy of the PHP license and are unable to |
6022 + | obtain it through the world-wide-web, please send a note to |
6023 + | license@php.net so we can mail you a copy immediately. |
6024 + +----------------------------------------------------------------------+
6025 + | Authors: Brian Shire <shire@.php.net> |
6026 + +----------------------------------------------------------------------+
6027 +
6028 + */
6029 +
6030 +/* $Id: apc_iterator.c 284698 2009-07-24 11:35:52Z kalle $ */
6031 +
6032 +#include "php_apc.h"
6033 +#include "apc_iterator.h"
6034 +#include "apc_cache.h"
6035 +#include "apc_zend.h"
6036 +
6037 +#include "ext/standard/md5.h"
6038 +
6039 +#include "zend_interfaces.h"
6040 +
6041 +zend_class_entry *apc_iterator_ce;
6042 +zend_object_handlers apc_iterator_object_handlers;
6043 +
6044 +
6045 +/* {{{ apc_iterator_item */
6046 +static apc_iterator_item_t* apc_iterator_item_ctor(apc_iterator_t *iterator, slot_t **slot_pp) {
6047 + zval *zvalue;
6048 + char md5str[33];
6049 + slot_t *slot = *slot_pp;
6050 + apc_context_t ctxt = {0, };
6051 + apc_iterator_item_t *item = ecalloc(1, sizeof(apc_iterator_item_t));
6052 +
6053 + if (slot->key.type == APC_CACHE_KEY_FILE) {
6054 + /* keys should be unique and with stat=1 we could have multiple files with the same name, so use '<device> <inode>' instead */
6055 + item->key_len = spprintf(&item->key, 0, "%ld %ld", (ulong)slot->key.data.file.device, (ulong)slot->key.data.file.inode);
6056 + item->filename_key = estrdup(slot->value->data.file.filename);
6057 + } else if (slot->key.type == APC_CACHE_KEY_USER) {
6058 + item->key = estrndup((char*)slot->key.data.user.identifier, slot->key.data.user.identifier_len);
6059 + item->key_len = slot->key.data.user.identifier_len;
6060 + item->filename_key = item->key;
6061 + } else if (slot->key.type == APC_CACHE_KEY_FPFILE) {
6062 + item->key = estrndup((char*)slot->key.data.fpfile.fullpath, slot->key.data.fpfile.fullpath_len);
6063 + item->key_len = slot->key.data.fpfile.fullpath_len;
6064 + } else {
6065 + apc_eprint("Internal error, invalid entry type.");
6066 + }
6067 +
6068 + ALLOC_INIT_ZVAL(item->value);
6069 + array_init(item->value);
6070 +
6071 + if (APC_ITER_TYPE & iterator->format) {
6072 + if(slot->value->type == APC_CACHE_ENTRY_FILE) {
6073 + add_assoc_string(item->value, "type", "file", 1);
6074 + } else if(slot->value->type == APC_CACHE_ENTRY_USER) {
6075 + add_assoc_string(item->value, "type", "user", 1);
6076 + }
6077 + }
6078 + if (APC_ITER_FILENAME & iterator->format) {
6079 + if(slot->value->type == APC_CACHE_ENTRY_FILE) {
6080 + if (slot->key.type == APC_CACHE_KEY_FILE) {
6081 + add_assoc_string(item->value, "filename", slot->value->data.file.filename, 1);
6082 + } else { /* APC_CACHE_FPFILE */
6083 + add_assoc_string(item->value, "filename", (char*)slot->key.data.fpfile.fullpath, 1);
6084 + }
6085 + }
6086 + }
6087 + if (APC_ITER_DEVICE & iterator->format) {
6088 + if(slot->key.type == APC_CACHE_KEY_FILE) {
6089 + add_assoc_long(item->value, "device", slot->key.data.file.device);
6090 + }
6091 + }
6092 + if (APC_ITER_INODE & iterator->format) {
6093 + if(slot->key.type == APC_CACHE_KEY_FILE) {
6094 + add_assoc_long(item->value, "inode", slot->key.data.file.inode);
6095 + }
6096 + }
6097 + if (APC_ITER_KEY & iterator->format) {
6098 + add_assoc_stringl(item->value, "key", item->key, item->key_len, 1);
6099 + }
6100 + if (APC_ITER_VALUE & iterator->format) {
6101 + if(slot->value->type == APC_CACHE_ENTRY_USER) {
6102 +
6103 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, NULL, NULL);
6104 + ctxt.copy = APC_COPY_OUT_USER;
6105 +
6106 + MAKE_STD_ZVAL(zvalue);
6107 + apc_cache_fetch_zval(zvalue, slot->value->data.user.val, &ctxt);
6108 + apc_pool_destroy(ctxt.pool);
6109 + add_assoc_zval(item->value, "value", zvalue);
6110 + }
6111 + }
6112 + if (APC_ITER_MD5 & iterator->format) {
6113 + if(slot->value->type == APC_CACHE_ENTRY_FILE) {
6114 + if(slot->key.md5) {
6115 + make_digest(md5str, slot->key.md5);
6116 + add_assoc_string(item->value, "md5", md5str, 1);
6117 + }
6118 + }
6119 + }
6120 + if (APC_ITER_NUM_HITS & iterator->format) {
6121 + add_assoc_long(item->value, "num_hits", slot->num_hits);
6122 + }
6123 + if (APC_ITER_MTIME & iterator->format) {
6124 + add_assoc_long(item->value, "mtime", slot->key.mtime);
6125 + }
6126 + if (APC_ITER_CTIME & iterator->format) {
6127 + add_assoc_long(item->value, "creation_time", slot->creation_time);
6128 + }
6129 + if (APC_ITER_DTIME & iterator->format) {
6130 + add_assoc_long(item->value, "deletion_time", slot->deletion_time);
6131 + }
6132 + if (APC_ITER_ATIME & iterator->format) {
6133 + add_assoc_long(item->value, "access_time", slot->access_time);
6134 + }
6135 + if (APC_ITER_REFCOUNT & iterator->format) {
6136 + add_assoc_long(item->value, "ref_count", slot->value->ref_count);
6137 + }
6138 + if (APC_ITER_MEM_SIZE & iterator->format) {
6139 + add_assoc_long(item->value, "mem_size", slot->value->mem_size);
6140 + }
6141 + if (APC_ITER_TTL & iterator->format) {
6142 + if(slot->value->type == APC_CACHE_ENTRY_USER) {
6143 + add_assoc_long(item->value, "ttl", slot->value->data.user.ttl);
6144 + }
6145 + }
6146 +
6147 + return item;
6148 +}
6149 +/* }}} */
6150 +
6151 +/* {{{ apc_iterator_clone */
6152 +static zend_object_value apc_iterator_clone(zval *zobject TSRMLS_DC) {
6153 + zend_object_value value = {0};
6154 + apc_eprint("APCIterator object cannot be cloned.");
6155 + return value;
6156 +}
6157 +/* }}} */
6158 +
6159 +/* {{{ apc_iterator_item_dtor */
6160 +static void apc_iterator_item_dtor(apc_iterator_item_t *item) {
6161 + if (item->filename_key && item->filename_key != item->key) {
6162 + efree(item->filename_key);
6163 + }
6164 + if (item->key) {
6165 + efree(item->key);
6166 + }
6167 + if (item->value) {
6168 + zval_ptr_dtor(&item->value);
6169 + }
6170 + efree(item);
6171 +}
6172 +/* }}} */
6173 +
6174 +/* {{{ apc_iterator_destroy */
6175 +static void apc_iterator_destroy(void *object, zend_object_handle handle TSRMLS_DC) {
6176 + apc_iterator_t *iterator = (apc_iterator_t*)object;
6177 +
6178 + if (iterator->initialized == 0) {
6179 + return;
6180 + }
6181 +
6182 + while (apc_stack_size(iterator->stack) > 0) {
6183 + apc_iterator_item_dtor(apc_stack_pop(iterator->stack));
6184 + }
6185 + if (iterator->regex) {
6186 + efree(iterator->regex);
6187 + }
6188 + if (iterator->search_hash) {
6189 + zend_hash_destroy(iterator->search_hash);
6190 + efree(iterator->search_hash);
6191 + }
6192 + iterator->initialized = 0;
6193 +
6194 +}
6195 +/* }}} */
6196 +
6197 +/* {{{ acp_iterator_free */
6198 +static void apc_iterator_free(void *object TSRMLS_DC) {
6199 + zend_object_std_dtor(object TSRMLS_CC);
6200 + efree(object);
6201 +}
6202 +/* }}} */
6203 +
6204 +/* {{{ apc_iterator_create */
6205 +static zend_object_value apc_iterator_create(zend_class_entry *ce TSRMLS_DC) {
6206 + zend_object_value retval;
6207 + apc_iterator_t *iterator;
6208 +
6209 + iterator = emalloc(sizeof(apc_iterator_t));
6210 + iterator->obj.ce = ce;
6211 + ALLOC_HASHTABLE(iterator->obj.properties);
6212 + zend_hash_init(iterator->obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
6213 + iterator->obj.guards = NULL;
6214 + iterator->initialized = 0;
6215 + retval.handle = zend_objects_store_put(iterator, apc_iterator_destroy, apc_iterator_free, NULL TSRMLS_CC);
6216 + retval.handlers = &apc_iterator_object_handlers;
6217 +
6218 + return retval;
6219 +}
6220 +/* }}} */
6221 +
6222 +/* {{{ apc_iterator_search_match
6223 + * Verify if the key matches oru search parameters
6224 + */
6225 +static int apc_iterator_search_match(apc_iterator_t *iterator, slot_t **slot) {
6226 + char *key;
6227 + int key_len;
6228 + char *fname_key = NULL;
6229 + int fname_key_len;
6230 + int rval = 1;
6231 +
6232 + if ((*slot)->key.type == APC_CACHE_KEY_FILE) {
6233 + key = estrdup((*slot)->value->data.file.filename);
6234 + key_len = strlen(key);
6235 + fname_key_len = spprintf(&fname_key, 0, "%ld %ld", (*slot)->key.data.file.device, (*slot)->key.data.file.inode);
6236 + } else if ((*slot)->key.type == APC_CACHE_KEY_USER) {
6237 + key = (char*)(*slot)->key.data.user.identifier;
6238 + key_len = (*slot)->key.data.user.identifier_len;
6239 + } else if ((*slot)->key.type == APC_CACHE_KEY_FPFILE) {
6240 + key = (char*)(*slot)->key.data.fpfile.fullpath;
6241 + key_len = (*slot)->key.data.fpfile.fullpath_len;
6242 + }
6243 +
6244 +#ifdef ITERATOR_PCRE
6245 + if (iterator->regex) {
6246 + rval = (pcre_exec(iterator->re, NULL, key, strlen(key), 0, 0, NULL, 0) >= 0);
6247 + }
6248 +#endif
6249 +
6250 + if (iterator->search_hash) {
6251 + rval = zend_hash_exists(iterator->search_hash, key, key_len+1);
6252 + if (!rval && fname_key) {
6253 + rval = zend_hash_exists(iterator->search_hash, fname_key, fname_key_len+1);
6254 + }
6255 + }
6256 +
6257 + return rval;
6258 +}
6259 +/* }}} */
6260 +
6261 +/* {{{ apc_iterator_fetch_active */
6262 +static int apc_iterator_fetch_active(apc_iterator_t *iterator) {
6263 + int count=0;
6264 + slot_t **slot;
6265 + apc_iterator_item_t *item;
6266 +
6267 + while (apc_stack_size(iterator->stack) > 0) {
6268 + apc_iterator_item_dtor(apc_stack_pop(iterator->stack));
6269 + }
6270 +
6271 + CACHE_LOCK(iterator->cache);
6272 + while(count <= iterator->chunk_size && iterator->slot_idx < iterator->cache->num_slots) {
6273 + slot = &iterator->cache->slots[iterator->slot_idx];
6274 + while(*slot) {
6275 + if (apc_iterator_search_match(iterator, slot)) {
6276 + count++;
6277 + item = apc_iterator_item_ctor(iterator, slot);
6278 + if (item) {
6279 + apc_stack_push(iterator->stack, item);
6280 + }
6281 + }
6282 + slot = &(*slot)->next;
6283 + }
6284 + iterator->slot_idx++;
6285 + }
6286 + CACHE_UNLOCK(iterator->cache);
6287 + iterator->stack_idx = 0;
6288 + return count;
6289 +}
6290 +/* }}} */
6291 +
6292 +/* {{{ apc_iterator_fetch_deleted */
6293 +static int apc_iterator_fetch_deleted(apc_iterator_t *iterator) {
6294 + int count=0;
6295 + slot_t **slot;
6296 + apc_iterator_item_t *item;
6297 +
6298 + CACHE_LOCK(iterator->cache);
6299 + slot = &iterator->cache->header->deleted_list;
6300 + while ((*slot) && count <= iterator->slot_idx) {
6301 + count++;
6302 + slot = &(*slot)->next;
6303 + }
6304 + count = 0;
6305 + while ((*slot) && count < iterator->chunk_size) {
6306 + if (apc_iterator_search_match(iterator, slot)) {
6307 + count++;
6308 + item = apc_iterator_item_ctor(iterator, slot);
6309 + if (item) {
6310 + apc_stack_push(iterator->stack, item);
6311 + }
6312 + }
6313 + slot = &(*slot)->next;
6314 + }
6315 + CACHE_UNLOCK(iterator->cache);
6316 + iterator->slot_idx += count;
6317 + iterator->stack_idx = 0;
6318 + return count;
6319 +}
6320 +/* }}} */
6321 +
6322 +/* {{{ apc_iterator_totals */
6323 +static void apc_iterator_totals(apc_iterator_t *iterator) {
6324 + slot_t **slot;
6325 + int i;
6326 +
6327 + CACHE_LOCK(iterator->cache);
6328 + for (i=0; i < iterator->cache->num_slots; i++) {
6329 + slot = &iterator->cache->slots[i];
6330 + while((*slot)) {
6331 + if (apc_iterator_search_match(iterator, slot)) {
6332 + iterator->size += (*slot)->value->mem_size;
6333 + iterator->hits += (*slot)->num_hits;
6334 + iterator->count++;
6335 + }
6336 + slot = &(*slot)->next;
6337 + }
6338 + }
6339 + CACHE_UNLOCK(iterator->cache);
6340 + iterator->totals_flag = 1;
6341 +}
6342 +/* }}} */
6343 +
6344 +/* {{{ proto object APCIterator::__costruct(string cache [, mixed search [, long format [, long chunk_size [, long list ]]]]) */
6345 +PHP_METHOD(apc_iterator, __construct) {
6346 + zval *object = getThis();
6347 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6348 + char *cachetype;
6349 + int cachetype_len;
6350 + long format = APC_ITER_ALL;
6351 + long chunk_size=0;
6352 + zval *search = NULL;
6353 + long list = APC_LIST_ACTIVE;
6354 +
6355 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zlll", &cachetype, &cachetype_len, &search, &format, &chunk_size, &list) == FAILURE) {
6356 + return;
6357 + }
6358 +
6359 + if (chunk_size < 0) {
6360 + apc_eprint("APCIterator chunk size must be greater than 0.");
6361 + return;
6362 + }
6363 +
6364 + if (format > APC_ITER_ALL) {
6365 + apc_eprint("APCIterator format is invalid.");
6366 + return;
6367 + }
6368 +
6369 + if (list == APC_LIST_ACTIVE) {
6370 + iterator->fetch = apc_iterator_fetch_active;
6371 + } else if (list == APC_LIST_DELETED) {
6372 + iterator->fetch = apc_iterator_fetch_deleted;
6373 + } else {
6374 + apc_wprint("APCIterator invalid list type.");
6375 + return;
6376 + }
6377 +
6378 + if(!strcasecmp(cachetype,"user")) {
6379 + iterator->cache = apc_user_cache;
6380 + } else {
6381 + iterator->cache = apc_cache;
6382 + }
6383 +
6384 + iterator->slot_idx = 0;
6385 + iterator->stack_idx = 0;
6386 + iterator->key_idx = 0;
6387 + iterator->chunk_size = chunk_size == 0 ? APC_DEFAULT_CHUNK_SIZE : chunk_size;
6388 + iterator->stack = apc_stack_create(chunk_size);
6389 + iterator->format = format;
6390 + iterator->totals_flag = 0;
6391 + iterator->count = 0;
6392 + iterator->size = 0;
6393 + iterator->hits = 0;
6394 + iterator->regex = NULL;
6395 + iterator->regex_len = 0;
6396 + iterator->search_hash = NULL;
6397 + if (search && Z_TYPE_P(search) == IS_STRING && Z_STRLEN_P(search)) {
6398 +#ifdef ITERATOR_PCRE
6399 + iterator->regex = estrndup(Z_STRVAL_P(search), Z_STRLEN_P(search));
6400 + iterator->regex_len = Z_STRLEN_P(search);
6401 + iterator->re = pcre_get_compiled_regex(Z_STRVAL_P(search), NULL, NULL TSRMLS_CC);
6402 +
6403 + if(!iterator->re) {
6404 + apc_eprint("Could not compile regular expression: %s", Z_STRVAL_P(search));
6405 + }
6406 +#else
6407 + apc_eprint("Regular expressions support is not enabled, please enable PCRE for APCIterator regex support");
6408 +#endif
6409 + } else if (search && Z_TYPE_P(search) == IS_ARRAY) {
6410 + Z_ADDREF_P(search);
6411 + iterator->search_hash = apc_flip_hash(Z_ARRVAL_P(search));
6412 + }
6413 + iterator->initialized = 1;
6414 +}
6415 +/* }}} */
6416 +
6417 +/* {{{ proto APCIterator::rewind() */
6418 +PHP_METHOD(apc_iterator, rewind) {
6419 + zval *object = getThis();
6420 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6421 +
6422 + if (iterator->initialized == 0) {
6423 + RETURN_FALSE;
6424 + }
6425 +
6426 + iterator->slot_idx = 0;
6427 + iterator->stack_idx = 0;
6428 + iterator->key_idx = 0;
6429 + iterator->fetch(iterator);
6430 +}
6431 +/* }}} */
6432 +
6433 +/* {{{ proto boolean APCIterator::valid() */
6434 +PHP_METHOD(apc_iterator, valid) {
6435 + zval *object = getThis();
6436 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6437 +
6438 + if (iterator->initialized == 0) {
6439 + RETURN_FALSE;
6440 + }
6441 +
6442 + if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
6443 + iterator->fetch(iterator);
6444 + }
6445 +
6446 + RETURN_BOOL(apc_stack_size(iterator->stack) == 0 ? 0 : 1);
6447 +}
6448 +/* }}} */
6449 +
6450 +/* {{{ proto mixed APCIterator::current() */
6451 +PHP_METHOD(apc_iterator, current) {
6452 + zval *object = getThis();
6453 + apc_iterator_item_t *item;
6454 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6455 + if (iterator->initialized == 0) {
6456 + RETURN_FALSE;
6457 + }
6458 + if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
6459 + if (iterator->fetch(iterator) == 0) {
6460 + RETURN_FALSE;
6461 + }
6462 + }
6463 + item = apc_stack_get(iterator->stack, iterator->stack_idx);
6464 + RETURN_ZVAL(item->value, 1, 0);
6465 +}
6466 +/* }}} */
6467 +
6468 +/* {{{ proto string APCIterator::key() */
6469 +PHP_METHOD(apc_iterator, key) {
6470 + zval *object = getThis();
6471 + apc_iterator_item_t *item;
6472 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6473 + if (iterator->initialized == 0 || apc_stack_size(iterator->stack) == 0) {
6474 + RETURN_FALSE;
6475 + }
6476 + if (apc_stack_size(iterator->stack) == iterator->stack_idx) {
6477 + if (iterator->fetch(iterator) == 0) {
6478 + RETURN_FALSE;
6479 + }
6480 + }
6481 + item = apc_stack_get(iterator->stack, iterator->stack_idx);
6482 + if (item->key) {
6483 + RETURN_STRINGL(item->key, item->key_len, 1);
6484 + } else {
6485 + RETURN_LONG(iterator->key_idx);
6486 + }
6487 +}
6488 +/* }}} */
6489 +
6490 +/* {{{ proto APCIterator::next() */
6491 +PHP_METHOD(apc_iterator, next) {
6492 + zval *object = getThis();
6493 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6494 + if (iterator->initialized == 0 || apc_stack_size(iterator->stack) == 0) {
6495 + RETURN_FALSE;
6496 + }
6497 + iterator->stack_idx++;
6498 + iterator->key_idx++;
6499 + RETURN_TRUE;
6500 +}
6501 +/* }}} */
6502 +
6503 +/* {{{ proto long APCIterator::getTotalHits() */
6504 +PHP_METHOD(apc_iterator, getTotalHits) {
6505 + zval *object = getThis();
6506 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6507 +
6508 + if (iterator->initialized == 0) {
6509 + RETURN_FALSE;
6510 + }
6511 +
6512 + if (iterator->totals_flag == 0) {
6513 + apc_iterator_totals(iterator);
6514 + }
6515 +
6516 + RETURN_LONG(iterator->hits);
6517 +}
6518 +/* }}} */
6519 +
6520 +/* {{{ proto long APCIterator:;getTotalSize() */
6521 +PHP_METHOD(apc_iterator, getTotalSize) {
6522 + zval *object = getThis();
6523 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6524 +
6525 + if (iterator->initialized == 0) {
6526 + RETURN_FALSE;
6527 + }
6528 +
6529 + if (iterator->totals_flag == 0) {
6530 + apc_iterator_totals(iterator);
6531 + }
6532 +
6533 + RETURN_LONG(iterator->size);
6534 +}
6535 +/* }}} */
6536 +
6537 +/* {{{ proto long APCIterator::getTotalCount() */
6538 +PHP_METHOD(apc_iterator, getTotalCount) {
6539 + zval *object = getThis();
6540 + apc_iterator_t *iterator = (apc_iterator_t*)zend_object_store_get_object(object TSRMLS_CC);
6541 +
6542 + if (iterator->initialized == 0) {
6543 + RETURN_FALSE;
6544 + }
6545 +
6546 + if (iterator->totals_flag == 0) {
6547 + apc_iterator_totals(iterator);
6548 + }
6549 +
6550 + RETURN_LONG(iterator->count);
6551 +}
6552 +/* }}} */
6553 +
6554 +/* {{{ apc_iterator_functions */
6555 +static function_entry apc_iterator_functions[] = {
6556 + PHP_ME(apc_iterator, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
6557 + PHP_ME(apc_iterator, rewind, NULL, ZEND_ACC_PUBLIC)
6558 + PHP_ME(apc_iterator, current, NULL, ZEND_ACC_PUBLIC)
6559 + PHP_ME(apc_iterator, key, NULL, ZEND_ACC_PUBLIC)
6560 + PHP_ME(apc_iterator, next, NULL, ZEND_ACC_PUBLIC)
6561 + PHP_ME(apc_iterator, valid, NULL, ZEND_ACC_PUBLIC)
6562 + PHP_ME(apc_iterator, getTotalHits, NULL, ZEND_ACC_PUBLIC)
6563 + PHP_ME(apc_iterator, getTotalSize, NULL, ZEND_ACC_PUBLIC)
6564 + PHP_ME(apc_iterator, getTotalCount, NULL, ZEND_ACC_PUBLIC)
6565 + {NULL, NULL, NULL}
6566 +};
6567 +/* }}} */
6568 +
6569 +/* {{{ apc_iterator_init */
6570 +int apc_iterator_init(int module_number TSRMLS_DC) {
6571 + zend_class_entry ce;
6572 +
6573 + INIT_CLASS_ENTRY(ce, APC_ITERATOR_NAME, apc_iterator_functions);
6574 + apc_iterator_ce = zend_register_internal_class(&ce TSRMLS_CC);
6575 + apc_iterator_ce->create_object = apc_iterator_create;
6576 + zend_class_implements(apc_iterator_ce TSRMLS_CC, 1, zend_ce_iterator);
6577 +
6578 + zend_register_long_constant("APC_LIST_ACTIVE", sizeof("APC_LIST_ACTIVE"), APC_LIST_ACTIVE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6579 + zend_register_long_constant("APC_LIST_DELETED", sizeof("APC_LIST_DELETED"), APC_LIST_DELETED, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6580 +
6581 + zend_register_long_constant("APC_ITER_TYPE", sizeof("APC_ITER_TYPE"), APC_ITER_TYPE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6582 + zend_register_long_constant("APC_ITER_KEY", sizeof("APC_ITER_KEY"), APC_ITER_KEY, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6583 + zend_register_long_constant("APC_ITER_FILENAME", sizeof("APC_ITER_FILENAME"), APC_ITER_FILENAME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6584 + zend_register_long_constant("APC_ITER_DEVICE", sizeof("APC_ITER_DEVICE"), APC_ITER_DEVICE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6585 + zend_register_long_constant("APC_ITER_INODE", sizeof("APC_ITER_INODE"), APC_ITER_INODE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6586 + zend_register_long_constant("APC_ITER_VALUE", sizeof("APC_ITER_VALUE"), APC_ITER_VALUE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6587 + zend_register_long_constant("APC_ITER_MD5", sizeof("APC_ITER_MD5"), APC_ITER_MD5, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6588 + zend_register_long_constant("APC_ITER_NUM_HITS", sizeof("APC_ITER_NUM_HITS"), APC_ITER_NUM_HITS, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6589 + zend_register_long_constant("APC_ITER_MTIME", sizeof("APC_ITER_MTIME"), APC_ITER_MTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6590 + zend_register_long_constant("APC_ITER_CTIME", sizeof("APC_ITER_CTIME"), APC_ITER_CTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6591 + zend_register_long_constant("APC_ITER_DTIME", sizeof("APC_ITER_DTIME"), APC_ITER_DTIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6592 + zend_register_long_constant("APC_ITER_ATIME", sizeof("APC_ITER_ATIME"), APC_ITER_ATIME, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6593 + zend_register_long_constant("APC_ITER_REFCOUNT", sizeof("APC_ITER_REFCOUNT"), APC_ITER_REFCOUNT, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6594 + zend_register_long_constant("APC_ITER_MEM_SIZE", sizeof("APC_ITER_MEM_SIZE"), APC_ITER_MEM_SIZE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6595 + zend_register_long_constant("APC_ITER_TTL", sizeof("APC_ITER_TTL"), APC_ITER_TTL, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6596 + zend_register_long_constant("APC_ITER_NONE", sizeof("APC_ITER_NONE"), APC_ITER_NONE, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6597 + zend_register_long_constant("APC_ITER_ALL", sizeof("APC_ITER_ALL"), APC_ITER_ALL, CONST_PERSISTENT | CONST_CS, module_number TSRMLS_CC);
6598 +
6599 + memcpy(&apc_iterator_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
6600 + apc_iterator_object_handlers.clone_obj = apc_iterator_clone;
6601 +
6602 + return SUCCESS;
6603 +}
6604 +/* }}} */
6605 +
6606 +
6607 +int apc_iterator_delete(zval *zobj TSRMLS_DC) {
6608 + apc_iterator_t *iterator;
6609 + zend_class_entry *ce = Z_OBJCE_P(zobj);
6610 + apc_iterator_item_t *item;
6611 +
6612 + if (!ce || !instanceof_function(ce, apc_iterator_ce TSRMLS_CC)) {
6613 + apc_eprint("apc_delete object argument must be instance of APCIterator");
6614 + return 0;
6615 + }
6616 + iterator = (apc_iterator_t*)zend_object_store_get_object(zobj TSRMLS_CC);
6617 +
6618 + if (iterator->initialized == 0) {
6619 + return 0;
6620 + }
6621 +
6622 + while (iterator->fetch(iterator)) {
6623 + while (iterator->stack_idx < apc_stack_size(iterator->stack)) {
6624 + item = apc_stack_get(iterator->stack, iterator->stack_idx++);
6625 + if (iterator->cache == apc_cache) {
6626 + apc_cache_delete(apc_cache, item->filename_key, strlen(item->filename_key)+1);
6627 + } else {
6628 + apc_cache_user_delete(apc_user_cache, item->key, item->key_len+1);
6629 + }
6630 + }
6631 + }
6632 +
6633 + return 1;
6634 +}
6635 +
6636 +
6637 +/*
6638 + * Local variables:
6639 + * tab-width: 4
6640 + * c-basic-offset: 4
6641 + * End:
6642 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
6643 + * vim<600: expandtab sw=4 ts=4 sts=4
6644 + */
6645 diff -Naur php-5.3.1.orig/ext/apc/apc_iterator.h php-5.3.1/ext/apc/apc_iterator.h
6646 --- php-5.3.1.orig/ext/apc/apc_iterator.h 1970-01-01 01:00:00.000000000 +0100
6647 +++ php-5.3.1/ext/apc/apc_iterator.h 1970-01-01 10:13:08.000000000 +0100
6648 @@ -0,0 +1,117 @@
6649 +/*
6650 + +----------------------------------------------------------------------+
6651 + | APC |
6652 + +----------------------------------------------------------------------+
6653 + | Copyright (c) 2008 The PHP Group |
6654 + +----------------------------------------------------------------------+
6655 + | This source file is subject to version 3.01 of the PHP license, |
6656 + | that is bundled with this package in the file LICENSE, and is |
6657 + | available through the world-wide-web at the following url: |
6658 + | http://www.php.net/license/3_01.txt |
6659 + | If you did not receive a copy of the PHP license and are unable to |
6660 + | obtain it through the world-wide-web, please send a note to |
6661 + | license@php.net so we can mail you a copy immediately. |
6662 + +----------------------------------------------------------------------+
6663 + | Authors: Brian Shire <shire@.php.net> |
6664 + +----------------------------------------------------------------------+
6665 +
6666 + */
6667 +
6668 +/* $Id: apc_iterator.h 277132 2009-03-14 01:50:57Z shire $ */
6669 +
6670 +#ifndef APC_ITERATOR_H
6671 +#define APC_ITERATOR_H
6672 +
6673 +#include "apc.h"
6674 +#include "apc_stack.h"
6675 +
6676 +#if HAVE_PCRE || HAVE_BUNDLED_PCRE
6677 +/* Deal with problem present until php-5.2.2 where php_pcre.h was not installed correctly */
6678 +# if !HAVE_BUNDLED_PCRE && PHP_MAJOR_VERSION == 5 && (PHP_MINOR_VERSION < 2 || (PHP_MINOR_VERSION == 2 && PHP_RELEASE_VERSION < 2))
6679 +# include "apc_php_pcre.h"
6680 +# else
6681 +# include "ext/pcre/php_pcre.h"
6682 +# endif
6683 +# include "ext/standard/php_smart_str.h"
6684 +# define ITERATOR_PCRE 1
6685 +#endif
6686 +
6687 +
6688 +#define APC_ITERATOR_NAME "APCIterator"
6689 +
6690 +#define APC_DEFAULT_CHUNK_SIZE 100
6691 +
6692 +#define APC_LIST_ACTIVE 0x1
6693 +#define APC_LIST_DELETED 0x2
6694 +
6695 +#define APC_ITER_TYPE (1L << 0)
6696 +#define APC_ITER_KEY (1L << 1)
6697 +#define APC_ITER_FILENAME (1L << 2)
6698 +#define APC_ITER_DEVICE (1L << 3)
6699 +#define APC_ITER_INODE (1L << 4)
6700 +#define APC_ITER_VALUE (1L << 5)
6701 +#define APC_ITER_MD5 (1L << 6)
6702 +#define APC_ITER_NUM_HITS (1L << 7)
6703 +#define APC_ITER_MTIME (1L << 8)
6704 +#define APC_ITER_CTIME (1L << 9)
6705 +#define APC_ITER_DTIME (1L << 10)
6706 +#define APC_ITER_ATIME (1L << 11)
6707 +#define APC_ITER_REFCOUNT (1L << 12)
6708 +#define APC_ITER_MEM_SIZE (1L << 13)
6709 +#define APC_ITER_TTL (1L << 14)
6710 +
6711 +#define APC_ITER_NONE (0x00000000L)
6712 +#define APC_ITER_ALL (0xffffffffL)
6713 +
6714 +typedef void* (*apc_iterator_item_cb_t)(slot_t **slot);
6715 +
6716 +
6717 +/* {{{ apc_iterator_t */
6718 +typedef struct _apc_iterator_t {
6719 + zend_object obj; /* must always be first */
6720 + short int initialized; /* sanity check in case __construct failed */
6721 + long format; /* format bitmask of the return values ie: key, value, info */
6722 + int (*fetch)(struct _apc_iterator_t *iterator);
6723 + /* fetch callback to fetch items from cache slots or lists */
6724 + apc_cache_t *cache; /* cache which we are iterating on */
6725 + long slot_idx; /* index to the slot array or linked list */
6726 + long chunk_size; /* number of entries to pull down per fetch */
6727 + apc_stack_t *stack; /* stack of entries pulled from cache */
6728 + int stack_idx; /* index into the current stack */
6729 +#ifdef ITERATOR_PCRE
6730 + pcre *re; /* regex filter on entry identifiers */
6731 +#endif
6732 + char *regex; /* original regex expression or NULL */
6733 + int regex_len; /* regex length */
6734 + HashTable *search_hash; /* hash of keys to iterate over */
6735 + long key_idx; /* incrementing index for numerical keys */
6736 + short int totals_flag; /* flag if totals have been calculated */
6737 + long hits; /* hit total */
6738 + size_t size; /* size total */
6739 + long count; /* count total */
6740 +} apc_iterator_t;
6741 +/* }}} */
6742 +
6743 +/* {{{ apc_iterator_item */
6744 +typedef struct _apc_iterator_item_t {
6745 + char *key; /* string key */
6746 + long key_len; /* strlen of key */
6747 + char *filename_key; /* filename key used for deletion */
6748 + zval *value;
6749 +} apc_iterator_item_t;
6750 +/* }}} */
6751 +
6752 +
6753 +extern int apc_iterator_init(int module_number TSRMLS_DC);
6754 +extern int apc_iterator_delete(zval *zobj TSRMLS_DC);
6755 +
6756 +#endif
6757 +
6758 +/*
6759 + * Local variables:
6760 + * tab-width: 4
6761 + * c-basic-offset: 4
6762 + * End:
6763 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
6764 + * vim<600: expandtab sw=4 ts=4 sts=4
6765 + */
6766 diff -Naur php-5.3.1.orig/ext/apc/apc_lock.h php-5.3.1/ext/apc/apc_lock.h
6767 --- php-5.3.1.orig/ext/apc/apc_lock.h 1970-01-01 01:00:00.000000000 +0100
6768 +++ php-5.3.1/ext/apc/apc_lock.h 1970-01-01 10:13:08.000000000 +0100
6769 @@ -0,0 +1,100 @@
6770 +/*
6771 + +----------------------------------------------------------------------+
6772 + | APC |
6773 + +----------------------------------------------------------------------+
6774 + | Copyright (c) 2006-2008 The PHP Group |
6775 + +----------------------------------------------------------------------+
6776 + | This source file is subject to version 3.01 of the PHP license, |
6777 + | that is bundled with this package in the file LICENSE, and is |
6778 + | available through the world-wide-web at the following url: |
6779 + | http://www.php.net/license/3_01.txt |
6780 + | If you did not receive a copy of the PHP license and are unable to |
6781 + | obtain it through the world-wide-web, please send a note to |
6782 + | license@php.net so we can mail you a copy immediately. |
6783 + +----------------------------------------------------------------------+
6784 + | Authors: George Schlossnagle <george@omniti.com> |
6785 + | Rasmus Lerdorf <rasmus@php.net> |
6786 + +----------------------------------------------------------------------+
6787 +
6788 + This software was contributed to PHP by Community Connect Inc. in 2002
6789 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
6790 + Future revisions and derivatives of this source code must acknowledge
6791 + Community Connect Inc. as the original contributor of this module by
6792 + leaving this note intact in the source code.
6793 +
6794 + All other licensing and usage conditions are those of the PHP Group.
6795 +
6796 + */
6797 +
6798 +/* $Id: apc_lock.h 268620 2008-11-09 02:30:49Z shire $ */
6799 +
6800 +#ifndef APC_LOCK
6801 +#define APC_LOCK
6802 +
6803 +#include "apc_sem.h"
6804 +#include "apc_fcntl.h"
6805 +#include "apc_pthreadmutex.h"
6806 +#include "apc_spin.h"
6807 +#ifdef HAVE_CONFIG_H
6808 +#include <config.h>
6809 +#endif
6810 +
6811 +/* {{{ generic locking macros */
6812 +#define CREATE_LOCK(lock) apc_lck_create(NULL, 0, 1, lock)
6813 +#define DESTROY_LOCK(lock) apc_lck_destroy(lock)
6814 +#define LOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_lock(lock); }
6815 +#define RDLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lck_rdlock(lock); }
6816 +#define UNLOCK(lock) { apc_lck_unlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
6817 +/* }}} */
6818 +
6819 +#if defined(APC_SEM_LOCKS)
6820 +#define APC_LOCK_TYPE "IPC Semaphore"
6821 +#define RDLOCK_AVAILABLE 0
6822 +#define NONBLOCKING_LOCK_AVAILABLE 1
6823 +#define apc_lck_t int
6824 +#define apc_lck_create(a,b,c,d) d=apc_sem_create(NULL,(b),(c))
6825 +#define apc_lck_destroy(a) apc_sem_destroy(a)
6826 +#define apc_lck_lock(a) apc_sem_lock(a)
6827 +#define apc_lck_nb_lock(a) apc_sem_nonblocking_lock(a)
6828 +#define apc_lck_rdlock(a) apc_sem_lock(a)
6829 +#define apc_lck_unlock(a) apc_sem_unlock(a)
6830 +#elif defined(APC_PTHREADMUTEX_LOCKS)
6831 +#define APC_LOCK_TYPE "pthread mutex Locks"
6832 +#define RDLOCK_AVAILABLE 0
6833 +#define NONBLOCKING_LOCK_AVAILABLE 1
6834 +#define apc_lck_t pthread_mutex_t
6835 +#define apc_lck_create(a,b,c,d) apc_pthreadmutex_create((pthread_mutex_t*)&d)
6836 +#define apc_lck_destroy(a) apc_pthreadmutex_destroy(&a)
6837 +#define apc_lck_lock(a) apc_pthreadmutex_lock(&a)
6838 +#define apc_lck_nb_lock(a) apc_pthreadmutex_nonblocking_lock(&a)
6839 +#define apc_lck_rdlock(a) apc_pthreadmutex_lock(&a)
6840 +#define apc_lck_unlock(a) apc_pthreadmutex_unlock(&a)
6841 +#elif defined(APC_SPIN_LOCKS)
6842 +#define APC_LOCK_TYPE "spin Locks"
6843 +#define RDLOCK_AVAILABLE 0
6844 +#define NONBLOCKING_LOCK_AVAILABLE APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE
6845 +#define apc_lck_t slock_t
6846 +#define apc_lck_create(a,b,c,d) apc_slock_create((slock_t*)&(d))
6847 +#define apc_lck_destroy(a) apc_slock_destroy(&a)
6848 +#define apc_lck_lock(a) apc_slock_lock(&a)
6849 +#define apc_lck_nb_lock(a) apc_slock_nonblocking_lock(&a)
6850 +#define apc_lck_rdlock(a) apc_slock_lock(&a)
6851 +#define apc_lck_unlock(a) apc_slock_unlock(&a)
6852 +#else
6853 +#define APC_LOCK_TYPE "File Locks"
6854 +#define RDLOCK_AVAILABLE 1
6855 +#ifdef PHP_WIN32
6856 +#define NONBLOCKING_LOCK_AVAILABLE 0
6857 +#else
6858 +#define NONBLOCKING_LOCK_AVAILABLE 1
6859 +#endif
6860 +#define apc_lck_t int
6861 +#define apc_lck_create(a,b,c,d) d=apc_fcntl_create((a))
6862 +#define apc_lck_destroy(a) apc_fcntl_destroy(a)
6863 +#define apc_lck_lock(a) apc_fcntl_lock(a)
6864 +#define apc_lck_nb_lock(a) apc_fcntl_nonblocking_lock(a)
6865 +#define apc_lck_rdlock(a) apc_fcntl_rdlock(a)
6866 +#define apc_lck_unlock(a) apc_fcntl_unlock(a)
6867 +#endif
6868 +
6869 +#endif
6870 diff -Naur php-5.3.1.orig/ext/apc/apc_main.c php-5.3.1/ext/apc/apc_main.c
6871 --- php-5.3.1.orig/ext/apc/apc_main.c 1970-01-01 01:00:00.000000000 +0100
6872 +++ php-5.3.1/ext/apc/apc_main.c 1970-01-01 10:13:08.000000000 +0100
6873 @@ -0,0 +1,957 @@
6874 +/*
6875 + +----------------------------------------------------------------------+
6876 + | APC |
6877 + +----------------------------------------------------------------------+
6878 + | Copyright (c) 2006-2008 The PHP Group |
6879 + +----------------------------------------------------------------------+
6880 + | This source file is subject to version 3.01 of the PHP license, |
6881 + | that is bundled with this package in the file LICENSE, and is |
6882 + | available through the world-wide-web at the following url: |
6883 + | http://www.php.net/license/3_01.txt |
6884 + | If you did not receive a copy of the PHP license and are unable to |
6885 + | obtain it through the world-wide-web, please send a note to |
6886 + | license@php.net so we can mail you a copy immediately. |
6887 + +----------------------------------------------------------------------+
6888 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
6889 + | Rasmus Lerdorf <rasmus@php.net> |
6890 + | Arun C. Murthy <arunc@yahoo-inc.com> |
6891 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
6892 + +----------------------------------------------------------------------+
6893 +
6894 + This software was contributed to PHP by Community Connect Inc. in 2002
6895 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
6896 + Future revisions and derivatives of this source code must acknowledge
6897 + Community Connect Inc. as the original contributor of this module by
6898 + leaving this note intact in the source code.
6899 +
6900 + All other licensing and usage conditions are those of the PHP Group.
6901 +
6902 + */
6903 +
6904 +/* $Id: apc_main.c 284282 2009-07-17 21:50:33Z shire $ */
6905 +
6906 +#include "apc_php.h"
6907 +#include "apc_main.h"
6908 +#include "apc.h"
6909 +#include "apc_lock.h"
6910 +#include "apc_cache.h"
6911 +#include "apc_compile.h"
6912 +#include "apc_globals.h"
6913 +#include "apc_sma.h"
6914 +#include "apc_stack.h"
6915 +#include "apc_zend.h"
6916 +#include "apc_pool.h"
6917 +#include "SAPI.h"
6918 +#include "php_scandir.h"
6919 +#include "ext/standard/php_var.h"
6920 +#include "ext/standard/md5.h"
6921 +
6922 +/* {{{ module variables */
6923 +
6924 +/* pointer to the original Zend engine compile_file function */
6925 +typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC);
6926 +static zend_compile_t *old_compile_file;
6927 +
6928 +/* }}} */
6929 +
6930 +/* {{{ get/set old_compile_file (to interact with other extensions that need the compile hook) */
6931 +static zend_compile_t* set_compile_hook(zend_compile_t *ptr)
6932 +{
6933 + zend_compile_t *retval = old_compile_file;
6934 +
6935 + if (ptr != NULL) old_compile_file = ptr;
6936 + return retval;
6937 +}
6938 +/* }}} */
6939 +
6940 +/* {{{ install_function */
6941 +static int install_function(apc_function_t fn, apc_context_t* ctxt, int lazy TSRMLS_DC)
6942 +{
6943 + int status;
6944 +
6945 +
6946 + if(lazy && fn.name[0] != '\0' && strncmp(fn.name, "__autoload", fn.name_len) != 0) {
6947 + status = zend_hash_add(APCG(lazy_function_table),
6948 + fn.name,
6949 + fn.name_len+1,
6950 + &fn,
6951 + sizeof(apc_function_t),
6952 + NULL);
6953 + } else {
6954 + zend_function *func = apc_copy_function_for_execution(fn.function, ctxt);
6955 + status = zend_hash_add(EG(function_table),
6956 + fn.name,
6957 + fn.name_len+1,
6958 + func,
6959 + sizeof(fn.function[0]),
6960 + NULL);
6961 + efree(func);
6962 + }
6963 +
6964 + if (status == FAILURE) {
6965 + /* apc_eprint("Cannot redeclare %s()", fn.name); */
6966 + }
6967 +
6968 + return status;
6969 +}
6970 +/* }}} */
6971 +
6972 +/* {{{ apc_lookup_function_hook */
6973 +int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) {
6974 + apc_function_t *fn;
6975 + int status = FAILURE;
6976 + apc_context_t ctxt = {0,};
6977 + TSRMLS_FETCH();
6978 +
6979 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect);
6980 + ctxt.copy = APC_COPY_OUT_OPCODE;
6981 +
6982 + if(zend_hash_quick_find(APCG(lazy_function_table), name, len, hash, (void**)&fn) == SUCCESS) {
6983 + *fe = apc_copy_function_for_execution(fn->function, &ctxt);
6984 + status = zend_hash_add(EG(function_table),
6985 + fn->name,
6986 + fn->name_len+1,
6987 + *fe,
6988 + sizeof(zend_function),
6989 + NULL);
6990 + }
6991 +
6992 + return status;
6993 +}
6994 +/* }}} */
6995 +
6996 +/* {{{ install_class */
6997 +static int install_class(apc_class_t cl, apc_context_t* ctxt, int lazy TSRMLS_DC)
6998 +{
6999 + zend_class_entry* class_entry = cl.class_entry;
7000 + zend_class_entry* parent = NULL;
7001 + int status;
7002 + zend_class_entry** allocated_ce = NULL;
7003 +
7004 + /* Special case for mangled names. Mangled names are unique to a file.
7005 + * There is no way two classes with the same mangled name will occur,
7006 + * unless a file is included twice. And if in case, a file is included
7007 + * twice, all mangled name conflicts can be ignored and the class redeclaration
7008 + * error may be deferred till runtime of the corresponding DECLARE_CLASS
7009 + * calls.
7010 + */
7011 +
7012 + if(cl.name_len != 0 && cl.name[0] == '\0') {
7013 + if(zend_hash_exists(CG(class_table), cl.name, cl.name_len+1)) {
7014 + return SUCCESS;
7015 + }
7016 + }
7017 +
7018 + if(lazy && cl.name_len != 0 && cl.name[0] != '\0') {
7019 + status = zend_hash_add(APCG(lazy_class_table),
7020 + cl.name,
7021 + cl.name_len+1,
7022 + &cl,
7023 + sizeof(apc_class_t),
7024 + NULL);
7025 + if(status == FAILURE) {
7026 + zend_error(E_ERROR, "Cannot redeclare class %s", cl.name);
7027 + }
7028 + return status;
7029 + }
7030 +
7031 + /*
7032 + * XXX: We need to free this somewhere...
7033 + */
7034 + allocated_ce = apc_php_malloc(sizeof(zend_class_entry*));
7035 +
7036 + if(!allocated_ce) {
7037 + return FAILURE;
7038 + }
7039 +
7040 + *allocated_ce =
7041 + class_entry =
7042 + apc_copy_class_entry_for_execution(cl.class_entry, ctxt);
7043 +
7044 +
7045 + /* restore parent class pointer for compile-time inheritance */
7046 + if (cl.parent_name != NULL) {
7047 + zend_class_entry** parent_ptr = NULL;
7048 + /*
7049 + * __autoload brings in the old issues with mixed inheritance.
7050 + * When a statically inherited class triggers autoload, it runs
7051 + * afoul of a potential require_once "parent.php" in the previous
7052 + * line, which when executed provides the parent class, but right
7053 + * now goes and hits __autoload which could fail.
7054 + *
7055 + * missing parent == re-compile.
7056 + *
7057 + * whether __autoload is enabled or not, because __autoload errors
7058 + * cause php to die.
7059 + *
7060 + * Aside: Do NOT pass *strlen(cl.parent_name)+1* because
7061 + * zend_lookup_class_ex does it internally anyway!
7062 + */
7063 + status = zend_lookup_class_ex(cl.parent_name,
7064 + strlen(cl.parent_name),
7065 + 0,
7066 + &parent_ptr TSRMLS_CC);
7067 + if (status == FAILURE) {
7068 + if(APCG(report_autofilter)) {
7069 + apc_wprint("Dynamic inheritance detected for class %s", cl.name);
7070 + }
7071 + class_entry->parent = NULL;
7072 + return status;
7073 + }
7074 + else {
7075 + parent = *parent_ptr;
7076 + class_entry->parent = parent;
7077 + zend_do_inheritance(class_entry, parent TSRMLS_CC);
7078 + }
7079 +
7080 +
7081 + }
7082 +
7083 + status = zend_hash_add(EG(class_table),
7084 + cl.name,
7085 + cl.name_len+1,
7086 + allocated_ce,
7087 + sizeof(zend_class_entry*),
7088 + NULL);
7089 +
7090 + if (status == FAILURE) {
7091 + apc_eprint("Cannot redeclare class %s", cl.name);
7092 + }
7093 + return status;
7094 +}
7095 +/* }}} */
7096 +
7097 +/* {{{ apc_lookup_class_hook */
7098 +int apc_lookup_class_hook(char *name, int len, ulong hash, zend_class_entry ***ce) {
7099 +
7100 + apc_class_t *cl;
7101 + apc_context_t ctxt = {0,};
7102 + TSRMLS_FETCH();
7103 +
7104 + if(zend_is_compiling(TSRMLS_C)) { return FAILURE; }
7105 +
7106 + if(zend_hash_quick_find(APCG(lazy_class_table), name, len, hash, (void**)&cl) == FAILURE) {
7107 + return FAILURE;
7108 + }
7109 +
7110 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect);
7111 + ctxt.copy = APC_COPY_OUT_OPCODE;
7112 +
7113 + if(install_class(*cl, &ctxt, 0 TSRMLS_CC) == FAILURE) {
7114 + apc_wprint("apc_lookup_class_hook: could not install %s", name);
7115 + return FAILURE;
7116 + }
7117 +
7118 + if(zend_hash_quick_find(EG(class_table), name, len, hash, (void**)ce) == FAILURE) {
7119 + apc_wprint("apc_lookup_class_hook: known error trying to fetch class %s", name);
7120 + return FAILURE;
7121 + }
7122 +
7123 + return SUCCESS;
7124 +
7125 +}
7126 +/* }}} */
7127 +
7128 +/* {{{ uninstall_class */
7129 +static int uninstall_class(apc_class_t cl TSRMLS_DC)
7130 +{
7131 + int status;
7132 +
7133 + status = zend_hash_del(EG(class_table),
7134 + cl.name,
7135 + cl.name_len+1);
7136 + if (status == FAILURE) {
7137 + apc_eprint("Cannot delete class %s", cl.name);
7138 + }
7139 + return status;
7140 +}
7141 +/* }}} */
7142 +
7143 +/* {{{ copy_function_name (taken from zend_builtin_functions.c to ensure future compatibility with APC) */
7144 +static int copy_function_name(apc_function_t *pf TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
7145 +{
7146 + zval *internal_ar = va_arg(args, zval *),
7147 + *user_ar = va_arg(args, zval *);
7148 + zend_function *func = pf->function;
7149 +
7150 + if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
7151 + return 0;
7152 + }
7153 +
7154 + if (func->type == ZEND_INTERNAL_FUNCTION) {
7155 + add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
7156 + } else if (func->type == ZEND_USER_FUNCTION) {
7157 + add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
7158 + }
7159 +
7160 + return 0;
7161 +}
7162 +
7163 +/* {{{ copy_class_or_interface_name (taken from zend_builtin_functions.c to ensure future compatibility with APC) */
7164 +static int copy_class_or_interface_name(apc_class_t *cl TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
7165 +{
7166 + zval *array = va_arg(args, zval *);
7167 + zend_uint mask = va_arg(args, zend_uint);
7168 + zend_uint comply = va_arg(args, zend_uint);
7169 + zend_uint comply_mask = (comply)? mask:0;
7170 + zend_class_entry *ce = cl->class_entry;
7171 +
7172 + if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
7173 + && (comply_mask == (ce->ce_flags & mask))) {
7174 + add_next_index_stringl(array, ce->name, ce->name_length, 1);
7175 + }
7176 + return ZEND_HASH_APPLY_KEEP;
7177 +}
7178 +/* }}} */
7179 +
7180 +/* }}} */
7181 +
7182 +/* {{{ apc_defined_function_hook */
7183 +int apc_defined_function_hook(zval *internal, zval *user) {
7184 + TSRMLS_FETCH();
7185 + zend_hash_apply_with_arguments(APCG(lazy_function_table) TSRMLS_CC, (apply_func_args_t) copy_function_name, 2, internal, user);
7186 + return 1;
7187 +}
7188 +/* }}} */
7189 +
7190 +/* {{{ apc_declared_class_hook */
7191 +int apc_declared_class_hook(zval *classes, zend_uint mask, zend_uint comply) {
7192 + TSRMLS_FETCH();
7193 + zend_hash_apply_with_arguments(APCG(lazy_class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, classes, mask, comply);
7194 + return 1;
7195 +}
7196 +/* }}} */
7197 +
7198 +/* {{{ compare_file_handles */
7199 +static int compare_file_handles(void* a, void* b)
7200 +{
7201 + zend_file_handle* fh1 = (zend_file_handle*)a;
7202 + zend_file_handle* fh2 = (zend_file_handle*)b;
7203 + return (fh1->type == fh2->type &&
7204 + fh1->filename == fh2->filename &&
7205 + fh1->opened_path == fh2->opened_path);
7206 +}
7207 +/* }}} */
7208 +
7209 +/* {{{ cached_compile */
7210 +static zend_op_array* cached_compile(zend_file_handle* h,
7211 + int type,
7212 + apc_context_t* ctxt TSRMLS_DC)
7213 +{
7214 + apc_cache_entry_t* cache_entry;
7215 + int i, ii;
7216 +
7217 + cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack));
7218 + assert(cache_entry != NULL);
7219 +
7220 + if (cache_entry->data.file.classes) {
7221 + for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
7222 + if(install_class(cache_entry->data.file.classes[i], ctxt, APCG(lazy_classes) TSRMLS_CC) == FAILURE) {
7223 + goto default_compile;
7224 + }
7225 + }
7226 + }
7227 +
7228 + if (cache_entry->data.file.functions) {
7229 + for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
7230 + install_function(cache_entry->data.file.functions[i], ctxt, APCG(lazy_functions) TSRMLS_CC);
7231 + }
7232 + }
7233 +
7234 + apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
7235 +
7236 +
7237 + return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
7238 +
7239 +default_compile:
7240 +
7241 + if(APCG(report_autofilter)) {
7242 + apc_wprint("Autofiltering %s", h->opened_path);
7243 + }
7244 +
7245 + if(cache_entry->data.file.classes) {
7246 + for(ii = 0; ii < i ; ii++) {
7247 + uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC);
7248 + }
7249 + }
7250 +
7251 + apc_stack_pop(APCG(cache_stack)); /* pop out cache_entry */
7252 +
7253 + apc_cache_release(apc_cache, cache_entry);
7254 +
7255 + /* cannot free up cache data yet, it maybe in use */
7256 +
7257 + zend_llist_del_element(&CG(open_files), h, compare_file_handles); /* We leak fds without this hack */
7258 +
7259 + /* WARNING: zend_llist shallow copies - so element delete via the
7260 + * zend_file_handle_dtor leaves h->opened_path dangling onto bad memory.
7261 + */
7262 +
7263 + h->opened_path = NULL;
7264 + h->type = ZEND_HANDLE_FILENAME;
7265 + if(h->free_filename) h->filename = NULL;
7266 +
7267 + return NULL;
7268 +}
7269 +/* }}} */
7270 +
7271 +/* {{{ apc_compile_cache_entry */
7272 +zend_bool apc_compile_cache_entry(apc_cache_key_t key, zend_file_handle* h, int type, time_t t, zend_op_array** op_array, apc_cache_entry_t** cache_entry TSRMLS_DC) {
7273 + int num_functions, num_classes;
7274 + apc_function_t* alloc_functions;
7275 + zend_op_array* alloc_op_array;
7276 + apc_class_t* alloc_classes;
7277 + char *path;
7278 + apc_context_t ctxt;
7279 +
7280 + /* remember how many functions and classes existed before compilation */
7281 + num_functions = zend_hash_num_elements(CG(function_table));
7282 + num_classes = zend_hash_num_elements(CG(class_table));
7283 +
7284 + /* compile the file using the default compile function, *
7285 + * we set *op_array here so we return opcodes during *
7286 + * a failure. We should not return prior to this line. */
7287 + *op_array = old_compile_file(h, type TSRMLS_CC);
7288 + if (*op_array == NULL) {
7289 + return FAILURE;
7290 + }
7291 +
7292 + ctxt.pool = apc_pool_create(APC_MEDIUM_POOL, apc_sma_malloc, apc_sma_free,
7293 + apc_sma_protect, apc_sma_unprotect);
7294 + if (!ctxt.pool) {
7295 + apc_wprint("Unable to allocate memory for pool.");
7296 + return FAILURE;
7297 + }
7298 + ctxt.copy = APC_COPY_IN_OPCODE;
7299 +
7300 + if(APCG(file_md5)) {
7301 + int n;
7302 + unsigned char buf[1024];
7303 + PHP_MD5_CTX context;
7304 + php_stream *stream;
7305 + char *filename;
7306 +
7307 + if(h->opened_path) {
7308 + filename = h->opened_path;
7309 + } else {
7310 + filename = h->filename;
7311 + }
7312 + stream = php_stream_open_wrapper(filename, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
7313 + if(stream) {
7314 + PHP_MD5Init(&context);
7315 + while((n = php_stream_read(stream, (char*)buf, sizeof(buf))) > 0) {
7316 + PHP_MD5Update(&context, buf, n);
7317 + }
7318 + PHP_MD5Final(key.md5, &context);
7319 + php_stream_close(stream);
7320 + if(n<0) {
7321 + apc_wprint("Error while reading '%s' for md5 generation.", filename);
7322 + }
7323 + } else {
7324 + apc_wprint("Unable to open '%s' for md5 generation.", filename);
7325 + }
7326 + }
7327 +
7328 + if(!(alloc_op_array = apc_copy_op_array(NULL, *op_array, &ctxt TSRMLS_CC))) {
7329 + goto freepool;
7330 + }
7331 +
7332 + if(!(alloc_functions = apc_copy_new_functions(num_functions, &ctxt TSRMLS_CC))) {
7333 + goto freepool;
7334 + }
7335 + if(!(alloc_classes = apc_copy_new_classes(*op_array, num_classes, &ctxt TSRMLS_CC))) {
7336 + goto freepool;
7337 + }
7338 +
7339 + path = h->opened_path;
7340 + if(!path) path=h->filename;
7341 +
7342 +#ifdef __DEBUG_APC__
7343 + fprintf(stderr,"2. h->opened_path=[%s] h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename);
7344 +#endif
7345 +
7346 + if(!(*cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes, &ctxt))) {
7347 + goto freepool;
7348 + }
7349 +
7350 + return SUCCESS;
7351 +
7352 +freepool:
7353 + apc_pool_destroy(ctxt.pool);
7354 + ctxt.pool = NULL;
7355 +
7356 + return FAILURE;
7357 +
7358 +}
7359 +/* }}} */
7360 +
7361 +/* {{{ my_compile_file
7362 + Overrides zend_compile_file */
7363 +static zend_op_array* my_compile_file(zend_file_handle* h,
7364 + int type TSRMLS_DC)
7365 +{
7366 + apc_cache_key_t key;
7367 + apc_cache_entry_t* cache_entry;
7368 + zend_op_array* op_array = NULL;
7369 + time_t t;
7370 + apc_context_t ctxt = {0,};
7371 + int bailout=0;
7372 +
7373 + if (!APCG(enabled) || apc_cache_busy(apc_cache)) {
7374 + return old_compile_file(h, type TSRMLS_CC);
7375 + }
7376 +
7377 + /* check our regular expression filters */
7378 + if (APCG(filters) && APCG(compiled_filters) && h->opened_path) {
7379 + int ret = apc_regex_match_array(APCG(compiled_filters), h->opened_path);
7380 +
7381 + if(ret == APC_NEGATIVE_MATCH || (ret != APC_POSITIVE_MATCH && !APCG(cache_by_default))) {
7382 + return old_compile_file(h, type TSRMLS_CC);
7383 + }
7384 + } else if(!APCG(cache_by_default)) {
7385 + return old_compile_file(h, type TSRMLS_CC);
7386 + }
7387 + APCG(current_cache) = apc_cache;
7388 +
7389 +
7390 + t = apc_time();
7391 +
7392 +#ifdef __DEBUG_APC__
7393 + fprintf(stderr,"1. h->opened_path=[%s] h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename);
7394 +#endif
7395 +
7396 + /* try to create a cache key; if we fail, give up on caching */
7397 + if (!apc_cache_make_file_key(&key, h->filename, PG(include_path), t TSRMLS_CC)) {
7398 + return old_compile_file(h, type TSRMLS_CC);
7399 + }
7400 +
7401 +
7402 + if(!APCG(force_file_update)) {
7403 + /* search for the file in the cache */
7404 + cache_entry = apc_cache_find(apc_cache, key, t);
7405 + ctxt.force_update = 0;
7406 + } else {
7407 + cache_entry = NULL;
7408 + ctxt.force_update = 1;
7409 + }
7410 +
7411 + if (cache_entry != NULL) {
7412 + int dummy = 1;
7413 +
7414 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free,
7415 + apc_sma_protect, apc_sma_unprotect);
7416 + if (!ctxt.pool) {
7417 + apc_wprint("Unable to allocate memory for pool.");
7418 + return old_compile_file(h, type TSRMLS_CC);
7419 + }
7420 + ctxt.copy = APC_COPY_OUT_OPCODE;
7421 +
7422 + if (h->opened_path == NULL) {
7423 + h->opened_path = estrdup(cache_entry->data.file.filename);
7424 + }
7425 + zend_hash_add(&EG(included_files), h->opened_path, strlen(h->opened_path)+1, (void *)&dummy, sizeof(int), NULL);
7426 +
7427 + zend_llist_add_element(&CG(open_files), h); /* We leak fds without this hack */
7428 +
7429 + apc_stack_push(APCG(cache_stack), cache_entry);
7430 + op_array = cached_compile(h, type, &ctxt TSRMLS_CC);
7431 + if(op_array) {
7432 +#ifdef APC_FILEHITS
7433 + /* If the file comes from the cache, add it to the global request file list */
7434 + add_next_index_string(APCG(filehits), h->filename, 1);
7435 +#endif
7436 + /* this is an unpool, which has no cleanup - this only free's the pool header */
7437 + apc_pool_destroy(ctxt.pool);
7438 + return op_array;
7439 + }
7440 + if(APCG(report_autofilter)) {
7441 + apc_wprint("Recompiling %s", cache_entry->data.file.filename);
7442 + }
7443 + /* TODO: check what happens with EG(included_files) */
7444 + }
7445 +
7446 + /* Make sure the mtime reflects the files last known mtime in the case of fpstat==0 */
7447 + if(key.type == APC_CACHE_KEY_FPFILE) {
7448 + apc_fileinfo_t fileinfo;
7449 + struct stat *tmp_buf = NULL;
7450 + if(!strcmp(SG(request_info).path_translated, h->filename)) {
7451 + tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */
7452 + }
7453 + if(tmp_buf) {
7454 + fileinfo.st_buf.sb = *tmp_buf;
7455 + } else {
7456 + if (apc_search_paths(h->filename, PG(include_path), &fileinfo) != 0) {
7457 +#ifdef __DEBUG_APC__
7458 + fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",h->filename,SG(request_info).path_translated);
7459 +#endif
7460 + return op_array;
7461 + }
7462 + }
7463 + key.mtime = fileinfo.st_buf.sb.st_mtime;
7464 + }
7465 +
7466 + HANDLE_BLOCK_INTERRUPTIONS();
7467 +
7468 +#if NONBLOCKING_LOCK_AVAILABLE
7469 + if(APCG(write_lock)) {
7470 + if(!apc_cache_write_lock(apc_cache)) {
7471 + HANDLE_UNBLOCK_INTERRUPTIONS();
7472 + return old_compile_file(h, type TSRMLS_CC);
7473 + }
7474 + }
7475 +#endif
7476 +
7477 + zend_try {
7478 + if (apc_compile_cache_entry(key, h, type, t, &op_array, &cache_entry TSRMLS_CC) == SUCCESS) {
7479 + ctxt.pool = cache_entry->pool;
7480 + ctxt.copy = APC_COPY_IN_OPCODE;
7481 + if (apc_cache_insert(apc_cache, key, cache_entry, &ctxt, t) != 1) {
7482 + apc_pool_destroy(ctxt.pool);
7483 + ctxt.pool = NULL;
7484 + }
7485 + }
7486 + } zend_catch {
7487 + bailout=1; /* in the event of a bailout, ensure we don't create a dead-lock */
7488 + } zend_end_try();
7489 +
7490 + APCG(current_cache) = NULL;
7491 +
7492 +#if NONBLOCKING_LOCK_AVAILABLE
7493 + if(APCG(write_lock)) {
7494 + apc_cache_write_unlock(apc_cache);
7495 + }
7496 +#endif
7497 + HANDLE_UNBLOCK_INTERRUPTIONS();
7498 +
7499 + if (bailout) zend_bailout();
7500 +
7501 + return op_array;
7502 +}
7503 +/* }}} */
7504 +
7505 +/* {{{ data preload */
7506 +
7507 +extern int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC);
7508 +
7509 +static zval* data_unserialize(const char *filename)
7510 +{
7511 + zval* retval;
7512 + long len = 0;
7513 + struct stat sb;
7514 + char *contents, *tmp;
7515 + FILE *fp;
7516 + php_unserialize_data_t var_hash;
7517 + TSRMLS_FETCH();
7518 +
7519 + if(VCWD_STAT(filename, &sb) == -1) {
7520 + return NULL;
7521 + }
7522 +
7523 + fp = fopen(filename, "rb");
7524 +
7525 + len = sizeof(char)*sb.st_size;
7526 +
7527 + tmp = contents = malloc(len);
7528 +
7529 + if(!contents) {
7530 + return NULL;
7531 + }
7532 +
7533 + if(fread(contents, 1, len, fp) < 1) {
7534 + free(contents);
7535 + return NULL;
7536 + }
7537 +
7538 + MAKE_STD_ZVAL(retval);
7539 +
7540 + PHP_VAR_UNSERIALIZE_INIT(var_hash);
7541 +
7542 + /* I wish I could use json */
7543 + if(!php_var_unserialize(&retval, (const unsigned char**)&tmp, (const unsigned char*)(contents+len), &var_hash TSRMLS_CC)) {
7544 + zval_ptr_dtor(&retval);
7545 + return NULL;
7546 + }
7547 +
7548 + PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
7549 +
7550 + free(contents);
7551 + fclose(fp);
7552 +
7553 + return retval;
7554 +}
7555 +
7556 +static int apc_load_data(const char *data_file TSRMLS_DC)
7557 +{
7558 + char *p;
7559 + char key[MAXPATHLEN] = {0,};
7560 + unsigned int key_len;
7561 + zval *data;
7562 +
7563 + p = strrchr(data_file, DEFAULT_SLASH);
7564 +
7565 + if(p && p[1]) {
7566 + strlcpy(key, p+1, sizeof(key));
7567 + p = strrchr(key, '.');
7568 +
7569 + if(p) {
7570 + p[0] = '\0';
7571 + key_len = strlen(key);
7572 +
7573 + data = data_unserialize(data_file);
7574 + if(data) {
7575 + _apc_store(key, key_len, data, 0, 1 TSRMLS_CC);
7576 + }
7577 + return 1;
7578 + }
7579 + }
7580 +
7581 + return 0;
7582 +}
7583 +
7584 +static int apc_walk_dir(const char *path TSRMLS_DC)
7585 +{
7586 + char file[MAXPATHLEN]={0,};
7587 + int ndir, i;
7588 + char *p = NULL;
7589 + struct dirent **namelist = NULL;
7590 +
7591 + if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0)
7592 + {
7593 + for (i = 0; i < ndir; i++)
7594 + {
7595 + /* check for extension */
7596 + if (!(p = strrchr(namelist[i]->d_name, '.'))
7597 + || (p && strcmp(p, ".data")))
7598 + {
7599 + free(namelist[i]);
7600 + continue;
7601 + }
7602 + snprintf(file, MAXPATHLEN, "%s%c%s",
7603 + path, DEFAULT_SLASH, namelist[i]->d_name);
7604 + if(!apc_load_data(file TSRMLS_CC))
7605 + {
7606 + /* print error */
7607 + }
7608 + free(namelist[i]);
7609 + }
7610 + free(namelist);
7611 + }
7612 +
7613 + return 1;
7614 +}
7615 +
7616 +void apc_data_preload(TSRMLS_D)
7617 +{
7618 + if(!APCG(preload_path)) return;
7619 +
7620 + apc_walk_dir(APCG(preload_path) TSRMLS_CC);
7621 +}
7622 +/* }}} */
7623 +
7624 +/* {{{ module init and shutdown */
7625 +
7626 +int apc_module_init(int module_number TSRMLS_DC)
7627 +{
7628 + /* apc initialization */
7629 +#if APC_MMAP
7630 + apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, APCG(mmap_file_mask));
7631 +#else
7632 + apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, NULL);
7633 +#endif
7634 + apc_cache = apc_cache_create(APCG(num_files_hint), APCG(gc_ttl), APCG(ttl));
7635 + apc_user_cache = apc_cache_create(APCG(user_entries_hint), APCG(gc_ttl), APCG(user_ttl));
7636 +
7637 + /* override compilation */
7638 + old_compile_file = zend_compile_file;
7639 + zend_compile_file = my_compile_file;
7640 + REGISTER_LONG_CONSTANT("\000apc_magic", (long)&set_compile_hook, CONST_PERSISTENT | CONST_CS);
7641 + REGISTER_LONG_CONSTANT("\000apc_compile_file", (long)&my_compile_file, CONST_PERSISTENT | CONST_CS);
7642 +
7643 + apc_pool_init();
7644 +
7645 + apc_data_preload(TSRMLS_C);
7646 +
7647 +#if APC_HAVE_LOOKUP_HOOKS
7648 + if(APCG(lazy_functions)) {
7649 + zend_set_lookup_function_hook(apc_lookup_function_hook TSRMLS_CC);
7650 + zend_set_defined_function_hook(apc_defined_function_hook TSRMLS_CC);
7651 + }
7652 + if(APCG(lazy_classes)) {
7653 + zend_set_lookup_class_hook(apc_lookup_class_hook TSRMLS_CC);
7654 + zend_set_declared_class_hook(apc_declared_class_hook TSRMLS_CC);
7655 + }
7656 +#else
7657 + if(APCG(lazy_functions) || APCG(lazy_classes)) {
7658 + apc_wprint("Lazy function/class loading not available with this version of PHP, please disable APC lazy loading.");
7659 + APCG(lazy_functions) = APCG(lazy_classes) = 0;
7660 + }
7661 +#endif
7662 +
7663 + APCG(initialized) = 1;
7664 + return 0;
7665 +}
7666 +
7667 +int apc_module_shutdown(TSRMLS_D)
7668 +{
7669 + if (!APCG(initialized))
7670 + return 0;
7671 +
7672 + /* restore compilation */
7673 + zend_compile_file = old_compile_file;
7674 +
7675 + /*
7676 + * In case we got interrupted by a SIGTERM or something else during execution
7677 + * we may have cache entries left on the stack that we need to check to make
7678 + * sure that any functions or classes these may have added to the global function
7679 + * and class tables are removed before we blow away the memory that hold them.
7680 + *
7681 + * This is merely to remove memory leak warnings - as the process is terminated
7682 + * immediately after shutdown. The following while loop can be removed without
7683 + * affecting anything else.
7684 + */
7685 + while (apc_stack_size(APCG(cache_stack)) > 0) {
7686 + int i;
7687 + apc_cache_entry_t* cache_entry = (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
7688 + if (cache_entry->data.file.functions) {
7689 + for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
7690 + zend_hash_del(EG(function_table),
7691 + cache_entry->data.file.functions[i].name,
7692 + cache_entry->data.file.functions[i].name_len+1);
7693 + }
7694 + }
7695 + if (cache_entry->data.file.classes) {
7696 + for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
7697 + zend_hash_del(EG(class_table),
7698 + cache_entry->data.file.classes[i].name,
7699 + cache_entry->data.file.classes[i].name_len+1);
7700 + }
7701 + }
7702 + apc_cache_release(apc_cache, cache_entry);
7703 + }
7704 +
7705 + apc_cache_destroy(apc_cache);
7706 + apc_cache_destroy(apc_user_cache);
7707 + apc_sma_cleanup();
7708 +
7709 + APCG(initialized) = 0;
7710 + return 0;
7711 +}
7712 +
7713 +/* }}} */
7714 +
7715 +/* {{{ process init and shutdown */
7716 +int apc_process_init(int module_number TSRMLS_DC)
7717 +{
7718 + return 0;
7719 +}
7720 +
7721 +int apc_process_shutdown(TSRMLS_D)
7722 +{
7723 + return 0;
7724 +}
7725 +/* }}} */
7726 +
7727 +
7728 +/* {{{ apc_deactivate */
7729 +static void apc_deactivate(TSRMLS_D)
7730 +{
7731 + /* The execution stack was unwound, which prevented us from decrementing
7732 + * the reference counts on active cache entries in `my_execute`.
7733 + */
7734 + while (apc_stack_size(APCG(cache_stack)) > 0) {
7735 + int i;
7736 + zend_class_entry* zce = NULL;
7737 + void ** centry = (void*)(&zce);
7738 + zend_class_entry** pzce = NULL;
7739 +
7740 + apc_cache_entry_t* cache_entry =
7741 + (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
7742 +
7743 + if (cache_entry->data.file.classes) {
7744 + for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
7745 + centry = (void**)&pzce; /* a triple indirection to get zend_class_entry*** */
7746 + if(zend_hash_find(EG(class_table),
7747 + cache_entry->data.file.classes[i].name,
7748 + cache_entry->data.file.classes[i].name_len+1,
7749 + (void**)centry) == FAILURE)
7750 + {
7751 + /* double inclusion of conditional classes ends up failing
7752 + * this lookup the second time around.
7753 + */
7754 + continue;
7755 + }
7756 +
7757 + zce = *pzce;
7758 +
7759 + zend_hash_del(EG(class_table),
7760 + cache_entry->data.file.classes[i].name,
7761 + cache_entry->data.file.classes[i].name_len+1);
7762 +
7763 + apc_free_class_entry_after_execution(zce);
7764 + }
7765 + }
7766 + apc_cache_release(apc_cache, cache_entry);
7767 + }
7768 +}
7769 +/* }}} */
7770 +
7771 +/* {{{ request init and shutdown */
7772 +
7773 +int apc_request_init(TSRMLS_D)
7774 +{
7775 + apc_stack_clear(APCG(cache_stack));
7776 + if (!APCG(compiled_filters) && APCG(filters)) {
7777 + /* compile regex filters here to avoid race condition between MINIT of PCRE and APC.
7778 + * This should be moved to apc_cache_create() if this race condition between modules is resolved */
7779 + APCG(compiled_filters) = apc_regex_compile_array(APCG(filters) TSRMLS_CC);
7780 + }
7781 +
7782 + if(APCG(lazy_functions)) {
7783 + APCG(lazy_function_table) = emalloc(sizeof(HashTable));
7784 + zend_hash_init(APCG(lazy_function_table), 0, NULL, NULL, 0);
7785 + }
7786 + if(APCG(lazy_classes)) {
7787 + APCG(lazy_class_table) = emalloc(sizeof(HashTable));
7788 + zend_hash_init(APCG(lazy_class_table), 0, NULL, NULL, 0);
7789 + }
7790 +
7791 +#ifdef APC_FILEHITS
7792 + ALLOC_INIT_ZVAL(APCG(filehits));
7793 + array_init(APCG(filehits));
7794 +#endif
7795 +
7796 + return 0;
7797 +}
7798 +
7799 +int apc_request_shutdown(TSRMLS_D)
7800 +{
7801 +
7802 + if(APCG(lazy_class_table)) {
7803 + zend_hash_destroy(APCG(lazy_class_table));
7804 + efree(APCG(lazy_class_table));
7805 + }
7806 + if(APCG(lazy_function_table)) {
7807 + zend_hash_destroy(APCG(lazy_function_table));
7808 + efree(APCG(lazy_function_table));
7809 + }
7810 +
7811 + apc_deactivate(TSRMLS_C);
7812 +
7813 +#ifdef APC_FILEHITS
7814 + zval_ptr_dtor(&APCG(filehits));
7815 +#endif
7816 +
7817 + return 0;
7818 +}
7819 +
7820 +/* }}} */
7821 +
7822 +
7823 +/*
7824 + * Local variables:
7825 + * tab-width: 4
7826 + * c-basic-offset: 4
7827 + * End:
7828 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
7829 + * vim<600: expandtab sw=4 ts=4 sts=4
7830 + */
7831 diff -Naur php-5.3.1.orig/ext/apc/apc_main.h php-5.3.1/ext/apc/apc_main.h
7832 --- php-5.3.1.orig/ext/apc/apc_main.h 1970-01-01 01:00:00.000000000 +0100
7833 +++ php-5.3.1/ext/apc/apc_main.h 1970-01-01 10:13:08.000000000 +0100
7834 @@ -0,0 +1,74 @@
7835 +/*
7836 + +----------------------------------------------------------------------+
7837 + | APC |
7838 + +----------------------------------------------------------------------+
7839 + | Copyright (c) 2006-2008 The PHP Group |
7840 + +----------------------------------------------------------------------+
7841 + | This source file is subject to version 3.01 of the PHP license, |
7842 + | that is bundled with this package in the file LICENSE, and is |
7843 + | available through the world-wide-web at the following url: |
7844 + | http://www.php.net/license/3_01.txt |
7845 + | If you did not receive a copy of the PHP license and are unable to |
7846 + | obtain it through the world-wide-web, please send a note to |
7847 + | license@php.net so we can mail you a copy immediately. |
7848 + +----------------------------------------------------------------------+
7849 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
7850 + | George Schlossnagle <george@omniti.com> |
7851 + | Rasmus Lerdorf <rasmus@php.net> |
7852 + | Arun C. Murthy <arunc@yahoo-inc.com> |
7853 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
7854 + +----------------------------------------------------------------------+
7855 +
7856 + This software was contributed to PHP by Community Connect Inc. in 2002
7857 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
7858 + Future revisions and derivatives of this source code must acknowledge
7859 + Community Connect Inc. as the original contributor of this module by
7860 + leaving this note intact in the source code.
7861 +
7862 + All other licensing and usage conditions are those of the PHP Group.
7863 +
7864 + */
7865 +
7866 +/* $Id: apc_main.h 268255 2008-11-04 05:42:11Z rasmus $ */
7867 +
7868 +#ifndef APC_MAIN_H
7869 +#define APC_MAIN_H
7870 +
7871 +#include "apc_pool.h"
7872 +
7873 +/*
7874 + * This module provides the primary interface between PHP and APC.
7875 + */
7876 +
7877 +extern int apc_module_init(int module_number TSRMLS_DC);
7878 +extern int apc_module_shutdown(TSRMLS_D);
7879 +extern int apc_process_init(int module_number TSRMLS_DC);
7880 +extern int apc_process_shutdown(TSRMLS_D);
7881 +extern int apc_request_init(TSRMLS_D);
7882 +extern int apc_request_shutdown(TSRMLS_D);
7883 +
7884 +typedef enum _apc_copy_type {
7885 + APC_NO_COPY = 0,
7886 + APC_COPY_IN_OPCODE,
7887 + APC_COPY_OUT_OPCODE,
7888 + APC_COPY_IN_USER,
7889 + APC_COPY_OUT_USER
7890 +} apc_copy_type;
7891 +
7892 +typedef struct _apc_context_t
7893 +{
7894 + apc_pool *pool;
7895 + apc_copy_type copy;
7896 + unsigned int force_update:1;
7897 +} apc_context_t;
7898 +
7899 +#endif
7900 +
7901 +/*
7902 + * Local variables:
7903 + * tab-width: 4
7904 + * c-basic-offset: 4
7905 + * End:
7906 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
7907 + * vim<600: expandtab sw=4 ts=4 sts=4
7908 + */
7909 diff -Naur php-5.3.1.orig/ext/apc/apc_mmap.c php-5.3.1/ext/apc/apc_mmap.c
7910 --- php-5.3.1.orig/ext/apc/apc_mmap.c 1970-01-01 01:00:00.000000000 +0100
7911 +++ php-5.3.1/ext/apc/apc_mmap.c 1970-01-01 10:13:08.000000000 +0100
7912 @@ -0,0 +1,175 @@
7913 +/*
7914 + +----------------------------------------------------------------------+
7915 + | APC |
7916 + +----------------------------------------------------------------------+
7917 + | Copyright (c) 2006-2008 The PHP Group |
7918 + +----------------------------------------------------------------------+
7919 + | This source file is subject to version 3.01 of the PHP license, |
7920 + | that is bundled with this package in the file LICENSE, and is |
7921 + | available through the world-wide-web at the following url: |
7922 + | http://www.php.net/license/3_01.txt |
7923 + | If you did not receive a copy of the PHP license and are unable to |
7924 + | obtain it through the world-wide-web, please send a note to |
7925 + | license@php.net so we can mail you a copy immediately. |
7926 + +----------------------------------------------------------------------+
7927 + | Authors: Rasmus Lerdorf <rasmus@php.net> |
7928 + +----------------------------------------------------------------------+
7929 +
7930 + This software was contributed to PHP by Community Connect Inc. in 2002
7931 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
7932 + Future revisions and derivatives of this source code must acknowledge
7933 + Community Connect Inc. as the original contributor of this module by
7934 + leaving this note intact in the source code.
7935 +
7936 + All other licensing and usage conditions are those of the PHP Group.
7937 +
7938 + */
7939 +
7940 +/* $Id: apc_mmap.c 287248 2009-08-13 15:13:52Z gopalv $ */
7941 +
7942 +#include "apc.h"
7943 +#include "apc_mmap.h"
7944 +#include "apc_lock.h"
7945 +
7946 +#if APC_MMAP
7947 +
7948 +#include <fcntl.h>
7949 +#include <sys/types.h>
7950 +#include <sys/mman.h>
7951 +
7952 +/*
7953 + * Some operating systems (like FreeBSD) have a MAP_NOSYNC flag that
7954 + * tells whatever update daemons might be running to not flush dirty
7955 + * vm pages to disk unless absolutely necessary. My guess is that
7956 + * most systems that don't have this probably default to only synching
7957 + * to disk when absolutely necessary.
7958 + */
7959 +#ifndef MAP_NOSYNC
7960 +#define MAP_NOSYNC 0
7961 +#endif
7962 +
7963 +/* support for systems where MAP_ANONYMOUS is defined but not MAP_ANON, ie: HP-UX bug #14615 */
7964 +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
7965 +# define MAP_ANON MAP_ANONYMOUS
7966 +#endif
7967 +
7968 +apc_segment_t apc_mmap(char *file_mask, size_t size)
7969 +{
7970 + apc_segment_t segment;
7971 +
7972 + int fd = -1;
7973 + int flags = MAP_SHARED | MAP_NOSYNC;
7974 + int remap = 1;
7975 +
7976 + /* If no filename was provided, do an anonymous mmap */
7977 + if(!file_mask || (file_mask && !strlen(file_mask))) {
7978 +#if !defined(MAP_ANON)
7979 + apc_eprint("Anonymous mmap does not apear to be available on this system (MAP_ANON/MAP_ANONYMOUS). Please see the apc.mmap_file_mask INI option.");
7980 +#else
7981 + fd = -1;
7982 + flags = MAP_SHARED | MAP_ANON;
7983 + remap = 0;
7984 +#endif
7985 + } else if(!strcmp(file_mask,"/dev/zero")) {
7986 + fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
7987 + if(fd == -1) {
7988 + apc_eprint("apc_mmap: open on /dev/zero failed:");
7989 + goto error;
7990 + }
7991 + remap = 0; /* cannot remap */
7992 + } else if(strstr(file_mask,".shm")) {
7993 + /*
7994 + * If the filemask contains .shm we try to do a POSIX-compliant shared memory
7995 + * backed mmap which should avoid synchs on some platforms. At least on
7996 + * FreeBSD this implies MAP_NOSYNC and on Linux it is equivalent of mmap'ing
7997 + * a file in a mounted shmfs. For this to work on Linux you need to make sure
7998 + * you actually have shmfs mounted. Also on Linux, make sure the file_mask you
7999 + * pass in has a leading / and no other /'s. eg. /apc.shm.XXXXXX
8000 + * On FreeBSD these are mapped onto the regular filesystem so you can put whatever
8001 + * path you want here.
8002 + */
8003 + if(!mktemp(file_mask)) {
8004 + apc_eprint("apc_mmap: mktemp on %s failed:", file_mask);
8005 + goto error;
8006 + }
8007 + fd = shm_open(file_mask, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
8008 + if(fd == -1) {
8009 + apc_eprint("apc_mmap: shm_open on %s failed:", file_mask);
8010 + goto error;
8011 + }
8012 + if (ftruncate(fd, size) < 0) {
8013 + close(fd);
8014 + shm_unlink(file_mask);
8015 + apc_eprint("apc_mmap: ftruncate failed:");
8016 + goto error;
8017 + }
8018 + shm_unlink(file_mask);
8019 + } else {
8020 + /*
8021 + * Otherwise we do a normal filesystem mmap
8022 + */
8023 + fd = mkstemp(file_mask);
8024 + if(fd == -1) {
8025 + apc_eprint("apc_mmap: mkstemp on %s failed:", file_mask);
8026 + goto error;
8027 + }
8028 + if (ftruncate(fd, size) < 0) {
8029 + close(fd);
8030 + unlink(file_mask);
8031 + apc_eprint("apc_mmap: ftruncate failed:");
8032 + goto error;
8033 + }
8034 + unlink(file_mask);
8035 + }
8036 +
8037 + segment.shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0);
8038 +
8039 +#ifdef APC_MEMPROTECT
8040 + if(remap) {
8041 + segment.roaddr = (void *)mmap(NULL, size, PROT_READ, flags, fd, 0);
8042 + } else {
8043 + segment.roaddr = NULL;
8044 + }
8045 +#endif
8046 +
8047 + if((long)segment.shmaddr == -1) {
8048 + apc_eprint("apc_mmap: mmap failed:");
8049 + }
8050 +
8051 + if(fd != -1) close(fd);
8052 +
8053 + return segment;
8054 +
8055 +error:
8056 +
8057 + segment.shmaddr = (void*)-1;
8058 +#ifdef APC_MEMPROTECT
8059 + segment.roaddr = NULL;
8060 +#endif
8061 + return segment;
8062 +}
8063 +
8064 +void apc_unmap(apc_segment_t *segment)
8065 +{
8066 + if (munmap(segment->shmaddr, segment->size) < 0) {
8067 + apc_wprint("apc_unmap: munmap failed:");
8068 + }
8069 +
8070 +#ifdef APC_MEMPROTECT
8071 + if (segment->roaddr && munmap(segment->roaddr, segment->size) < 0) {
8072 + apc_wprint("apc_unmap: munmap failed:");
8073 + }
8074 +#endif
8075 +
8076 +}
8077 +
8078 +#endif
8079 +
8080 +/*
8081 + * Local variables:
8082 + * tab-width: 4
8083 + * c-basic-offset: 4
8084 + * End:
8085 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
8086 + * vim<600: expandtab sw=4 ts=4 sts=4
8087 + */
8088 diff -Naur php-5.3.1.orig/ext/apc/apc_mmap.h php-5.3.1/ext/apc/apc_mmap.h
8089 --- php-5.3.1.orig/ext/apc/apc_mmap.h 1970-01-01 01:00:00.000000000 +0100
8090 +++ php-5.3.1/ext/apc/apc_mmap.h 1970-01-01 10:13:08.000000000 +0100
8091 @@ -0,0 +1,54 @@
8092 +/*
8093 + +----------------------------------------------------------------------+
8094 + | APC |
8095 + +----------------------------------------------------------------------+
8096 + | Copyright (c) 2006-2009 The PHP Group |
8097 + +----------------------------------------------------------------------+
8098 + | This source file is subject to version 3.01 of the PHP license, |
8099 + | that is bundled with this package in the file LICENSE, and is |
8100 + | available through the world-wide-web at the following url: |
8101 + | http://www.php.net/license/3_01.txt |
8102 + | If you did not receive a copy of the PHP license and are unable to |
8103 + | obtain it through the world-wide-web, please send a note to |
8104 + | license@php.net so we can mail you a copy immediately. |
8105 + +----------------------------------------------------------------------+
8106 + | Authors: Gopal V <gopalv@php.net>
8107 + +----------------------------------------------------------------------+
8108 +
8109 + This software was contributed to PHP by Community Connect Inc. in 2002
8110 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
8111 + Future revisions and derivatives of this source code must acknowledge
8112 + Community Connect Inc. as the original contributor of this module by
8113 + leaving this note intact in the source code.
8114 +
8115 + All other licensing and usage conditions are those of the PHP Group.
8116 +
8117 + */
8118 +
8119 +/* $Id: apc_mmap.h 273456 2009-01-13 14:43:58Z gopalv $ */
8120 +
8121 +#ifndef APC_MMAP_H
8122 +#define APC_MMAP_H
8123 +
8124 +#include <limits.h>
8125 +
8126 +#include "apc.h"
8127 +#include "apc_sma.h"
8128 +
8129 +/* Wrapper functions for shared memory mapped files */
8130 +
8131 +#if APC_MMAP
8132 +apc_segment_t apc_mmap(char *file_mask, size_t size);
8133 +void apc_unmap(apc_segment_t* segment);
8134 +#endif
8135 +
8136 +#endif
8137 +
8138 +/*
8139 + * Local variables:
8140 + * tab-width: 4
8141 + * c-basic-offset: 4
8142 + * End:
8143 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
8144 + * vim<600: expandtab sw=4 ts=4 sts=4
8145 + */
8146 diff -Naur php-5.3.1.orig/ext/apc/apc.php php-5.3.1/ext/apc/apc.php
8147 --- php-5.3.1.orig/ext/apc/apc.php 1970-01-01 01:00:00.000000000 +0100
8148 +++ php-5.3.1/ext/apc/apc.php 1970-01-01 10:13:08.000000000 +0100
8149 @@ -0,0 +1,1362 @@
8150 +<?php
8151 +/*
8152 + +----------------------------------------------------------------------+
8153 + | APC |
8154 + +----------------------------------------------------------------------+
8155 + | Copyright (c) 2006-2008 The PHP Group |
8156 + +----------------------------------------------------------------------+
8157 + | This source file is subject to version 3.01 of the PHP license, |
8158 + | that is bundled with this package in the file LICENSE, and is |
8159 + | available through the world-wide-web at the following url: |
8160 + | http://www.php.net/license/3_01.txt |
8161 + | If you did not receive a copy of the PHP license and are unable to |
8162 + | obtain it through the world-wide-web, please send a note to |
8163 + | license@php.net so we can mail you a copy immediately. |
8164 + +----------------------------------------------------------------------+
8165 + | Authors: Ralf Becker <beckerr@php.net> |
8166 + | Rasmus Lerdorf <rasmus@php.net> |
8167 + | Ilia Alshanetsky <ilia@prohost.org> |
8168 + +----------------------------------------------------------------------+
8169 +
8170 + All other licensing and usage conditions are those of the PHP Group.
8171 +
8172 + */
8173 +
8174 +$VERSION='$Id: apc.php 271315 2008-12-16 07:15:07Z shire $';
8175 +
8176 +////////// READ OPTIONAL CONFIGURATION FILE ////////////
8177 +if (file_exists("apc.conf.php")) include("apc.conf.php");
8178 +////////////////////////////////////////////////////////
8179 +
8180 +////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
8181 +
8182 +defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if
8183 + // no other authentication is available
8184 + // If set to 0:
8185 + // There will be no further authentication. You
8186 + // will have to handle this by yourself!
8187 + // If set to 1:
8188 + // You need to change ADMIN_PASSWORD to make
8189 + // this work!
8190 +defaults('ADMIN_USERNAME','apc'); // Admin Username
8191 +defaults('ADMIN_PASSWORD','password'); // Admin Password - CHANGE THIS TO ENABLE!!!
8192 +
8193 +// (beckerr) I'm using a clear text password here, because I've no good idea how to let
8194 +// users generate a md5 or crypt password in a easy way to fill it in above
8195 +
8196 +//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
8197 +defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
8198 +
8199 +defaults('GRAPH_SIZE',200); // Image size
8200 +
8201 +//defaults('PROXY', 'tcp://127.0.0.1:8080');
8202 +
8203 +////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
8204 +
8205 +
8206 +// "define if not defined"
8207 +function defaults($d,$v) {
8208 + if (!defined($d)) define($d,$v); // or just @define(...)
8209 +}
8210 +
8211 +// rewrite $PHP_SELF to block XSS attacks
8212 +//
8213 +$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : '';
8214 +$time = time();
8215 +$host = php_uname('n');
8216 +if($host) { $host = '('.$host.')'; }
8217 +if ($_SERVER['SERVER_ADDR']) {
8218 + $host .= ' ('.$_SERVER['SERVER_ADDR'].')';
8219 +}
8220 +
8221 +// operation constants
8222 +define('OB_HOST_STATS',1);
8223 +define('OB_SYS_CACHE',2);
8224 +define('OB_USER_CACHE',3);
8225 +define('OB_SYS_CACHE_DIR',4);
8226 +define('OB_VERSION_CHECK',9);
8227 +
8228 +// check validity of input variables
8229 +$vardom=array(
8230 + 'OB' => '/^\d+$/', // operational mode switch
8231 + 'CC' => '/^[01]$/', // clear cache requested
8232 + 'DU' => '/^.*$/', // Delete User Key
8233 + 'SH' => '/^[a-z0-9]+$/', // shared object description
8234 +
8235 + 'IMG' => '/^[123]$/', // image to generate
8236 + 'LO' => '/^1$/', // login requested
8237 +
8238 + 'COUNT' => '/^\d+$/', // number of line displayed in list
8239 + 'SCOPE' => '/^[AD]$/', // list view scope
8240 + 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
8241 + 'SORT2' => '/^[DA]$/', // second sort key
8242 + 'AGGR' => '/^\d+$/', // aggregation by dir level
8243 + 'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level
8244 +);
8245 +
8246 +// default cache mode
8247 +$cache_mode='opcode';
8248 +
8249 +// cache scope
8250 +$scope_list=array(
8251 + 'A' => 'cache_list',
8252 + 'D' => 'deleted_list'
8253 +);
8254 +
8255 +// handle POST and GET requests
8256 +if (empty($_REQUEST)) {
8257 + if (!empty($_GET) && !empty($_POST)) {
8258 + $_REQUEST = array_merge($_GET, $_POST);
8259 + } else if (!empty($_GET)) {
8260 + $_REQUEST = $_GET;
8261 + } else if (!empty($_POST)) {
8262 + $_REQUEST = $_POST;
8263 + } else {
8264 + $_REQUEST = array();
8265 + }
8266 +}
8267 +
8268 +// check parameter syntax
8269 +foreach($vardom as $var => $dom) {
8270 + if (!isset($_REQUEST[$var])) {
8271 + $MYREQUEST[$var]=NULL;
8272 + } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) {
8273 + $MYREQUEST[$var]=$_REQUEST[$var];
8274 + } else {
8275 + $MYREQUEST[$var]=$_REQUEST[$var]=NULL;
8276 + }
8277 +}
8278 +
8279 +// check parameter sematics
8280 +if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
8281 +if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
8282 +if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
8283 +if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
8284 +if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
8285 +if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
8286 +
8287 +$MY_SELF=
8288 + "$PHP_SELF".
8289 + "?SCOPE=".$MYREQUEST['SCOPE'].
8290 + "&SORT1=".$MYREQUEST['SORT1'].
8291 + "&SORT2=".$MYREQUEST['SORT2'].
8292 + "&COUNT=".$MYREQUEST['COUNT'];
8293 +$MY_SELF_WO_SORT=
8294 + "$PHP_SELF".
8295 + "?SCOPE=".$MYREQUEST['SCOPE'].
8296 + "&COUNT=".$MYREQUEST['COUNT'];
8297 +
8298 +// authentication needed?
8299 +//
8300 +if (!USE_AUTHENTICATION) {
8301 + $AUTHENTICATED=1;
8302 +} else {
8303 + $AUTHENTICATED=0;
8304 + if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
8305 +
8306 + if (!isset($_SERVER['PHP_AUTH_USER']) ||
8307 + !isset($_SERVER['PHP_AUTH_PW']) ||
8308 + $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
8309 + $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
8310 + Header("WWW-Authenticate: Basic realm=\"APC Login\"");
8311 + Header("HTTP/1.0 401 Unauthorized");
8312 +
8313 + echo <<<EOB
8314 + <html><body>
8315 + <h1>Rejected!</h1>
8316 + <big>Wrong Username or Password!</big><br/>&nbsp;<br/>&nbsp;
8317 + <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
8318 + </body></html>
8319 +EOB;
8320 + exit;
8321 +
8322 + } else {
8323 + $AUTHENTICATED=1;
8324 + }
8325 + }
8326 +}
8327 +
8328 +// select cache mode
8329 +if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
8330 + $cache_mode='user';
8331 +}
8332 +// clear cache
8333 +if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
8334 + apc_clear_cache($cache_mode);
8335 +}
8336 +
8337 +if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
8338 + apc_delete($MYREQUEST['DU']);
8339 +}
8340 +
8341 +if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
8342 + echo "No cache info available. APC does not appear to be running.";
8343 + exit;
8344 +}
8345 +
8346 +$cache_user = apc_cache_info('user', 1);
8347 +$mem=apc_sma_info();
8348 +if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
8349 +
8350 +// don't cache this page
8351 +//
8352 +header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
8353 +header("Cache-Control: post-check=0, pre-check=0", false);
8354 +header("Pragma: no-cache"); // HTTP/1.0
8355 +
8356 +function duration($ts) {
8357 + global $time;
8358 + $years = (int)((($time - $ts)/(7*86400))/52.177457);
8359 + $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
8360 + $weeks = (int)(($rem)/(7*86400));
8361 + $days = (int)(($rem)/86400) - $weeks*7;
8362 + $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
8363 + $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
8364 + $str = '';
8365 + if($years==1) $str .= "$years year, ";
8366 + if($years>1) $str .= "$years years, ";
8367 + if($weeks==1) $str .= "$weeks week, ";
8368 + if($weeks>1) $str .= "$weeks weeks, ";
8369 + if($days==1) $str .= "$days day,";
8370 + if($days>1) $str .= "$days days,";
8371 + if($hours == 1) $str .= " $hours hour and";
8372 + if($hours>1) $str .= " $hours hours and";
8373 + if($mins == 1) $str .= " 1 minute";
8374 + else $str .= " $mins minutes";
8375 + return $str;
8376 +}
8377 +
8378 +// create graphics
8379 +//
8380 +function graphics_avail() {
8381 + return extension_loaded('gd');
8382 +}
8383 +if (isset($MYREQUEST['IMG']))
8384 +{
8385 + if (!graphics_avail()) {
8386 + exit(0);
8387 + }
8388 +
8389 + function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
8390 + $r=$diameter/2;
8391 + $w=deg2rad((360+$start+($end-$start)/2)%360);
8392 +
8393 +
8394 + if (function_exists("imagefilledarc")) {
8395 + // exists only if GD 2.0.1 is avaliable
8396 + imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
8397 + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
8398 + imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
8399 + } else {
8400 + imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
8401 + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
8402 + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
8403 + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
8404 + imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
8405 + imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
8406 + }
8407 + if ($text) {
8408 + if ($placeindex>0) {
8409 + imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
8410 + imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
8411 +
8412 + } else {
8413 + imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
8414 + }
8415 + }
8416 + }
8417 +
8418 + function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
8419 + $r=$diameter/2;
8420 + $w=deg2rad((360+$start+($end-$start)/2)%360);
8421 +
8422 + if ($placeindex>0) {
8423 + imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
8424 + imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
8425 +
8426 + } else {
8427 + imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
8428 + }
8429 + }
8430 +
8431 + function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
8432 + global $col_black;
8433 + $x1=$x+$w-1;
8434 + $y1=$y+$h-1;
8435 +
8436 + imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
8437 + if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
8438 + else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
8439 + imagerectangle($im, $x, $y1, $x1, $y, $color1);
8440 + if ($text) {
8441 + if ($placeindex>0) {
8442 +
8443 + if ($placeindex<16)
8444 + {
8445 + $px=5;
8446 + $py=$placeindex*12+6;
8447 + imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
8448 + imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
8449 + imagestring($im,2,$px,$py-6,$text,$color1);
8450 +
8451 + } else {
8452 + if ($placeindex<31) {
8453 + $px=$x+40*2;
8454 + $py=($placeindex-15)*12+6;
8455 + } else {
8456 + $px=$x+40*2+100*intval(($placeindex-15)/15);
8457 + $py=($placeindex%15)*12+6;
8458 + }
8459 + imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
8460 + imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
8461 + imagestring($im,2,$px+2,$py-6,$text,$color1);
8462 + }
8463 + } else {
8464 + imagestring($im,4,$x+5,$y1-16,$text,$color1);
8465 + }
8466 + }
8467 + }
8468 +
8469 +
8470 + $size = GRAPH_SIZE; // image size
8471 + if ($MYREQUEST['IMG']==3)
8472 + $image = imagecreate(2*$size+150, $size+10);
8473 + else
8474 + $image = imagecreate($size+50, $size+10);
8475 +
8476 + $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
8477 + $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
8478 + $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
8479 + $col_black = imagecolorallocate($image, 0, 0, 0);
8480 + imagecolortransparent($image,$col_white);
8481 +
8482 + switch ($MYREQUEST['IMG']) {
8483 +
8484 + case 1:
8485 + $s=$mem['num_seg']*$mem['seg_size'];
8486 + $a=$mem['avail_mem'];
8487 + $x=$y=$size/2;
8488 + $fuzz = 0.000001;
8489 +
8490 + // This block of code creates the pie chart. It is a lot more complex than you
8491 + // would expect because we try to visualize any memory fragmentation as well.
8492 + $angle_from = 0;
8493 + $string_placement=array();
8494 + for($i=0; $i<$mem['num_seg']; $i++) {
8495 + $ptr = 0;
8496 + $free = $mem['block_lists'][$i];
8497 + uasort($free, 'block_sort');
8498 + foreach($free as $block) {
8499 + if($block['offset']!=$ptr) { // Used block
8500 + $angle_to = $angle_from+($block['offset']-$ptr)/$s;
8501 + if(($angle_to+$fuzz)>1) $angle_to = 1;
8502 + if( ($angle_to*360) - ($angle_from*360) >= 1) {
8503 + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
8504 + if (($angle_to-$angle_from)>0.05) {
8505 + array_push($string_placement, array($angle_from,$angle_to));
8506 + }
8507 + }
8508 + $angle_from = $angle_to;
8509 + }
8510 + $angle_to = $angle_from+($block['size'])/$s;
8511 + if(($angle_to+$fuzz)>1) $angle_to = 1;
8512 + if( ($angle_to*360) - ($angle_from*360) >= 1) {
8513 + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
8514 + if (($angle_to-$angle_from)>0.05) {
8515 + array_push($string_placement, array($angle_from,$angle_to));
8516 + }
8517 + }
8518 + $angle_from = $angle_to;
8519 + $ptr = $block['offset']+$block['size'];
8520 + }
8521 + if ($ptr < $mem['seg_size']) { // memory at the end
8522 + $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
8523 + if(($angle_to+$fuzz)>1) $angle_to = 1;
8524 + fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
8525 + if (($angle_to-$angle_from)>0.05) {
8526 + array_push($string_placement, array($angle_from,$angle_to));
8527 + }
8528 + }
8529 + }
8530 + foreach ($string_placement as $angle) {
8531 + text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
8532 + }
8533 + break;
8534 +
8535 + case 2:
8536 + $s=$cache['num_hits']+$cache['num_misses'];
8537 + $a=$cache['num_hits'];
8538 +
8539 + fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
8540 + fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
8541 + break;
8542 +
8543 + case 3:
8544 + $s=$mem['num_seg']*$mem['seg_size'];
8545 + $a=$mem['avail_mem'];
8546 + $x=130;
8547 + $y=1;
8548 + $j=1;
8549 +
8550 + // This block of code creates the bar chart. It is a lot more complex than you
8551 + // would expect because we try to visualize any memory fragmentation as well.
8552 + for($i=0; $i<$mem['num_seg']; $i++) {
8553 + $ptr = 0;
8554 + $free = $mem['block_lists'][$i];
8555 + uasort($free, 'block_sort');
8556 + foreach($free as $block) {
8557 + if($block['offset']!=$ptr) { // Used block
8558 + $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
8559 + if ($h>0) {
8560 + $j++;
8561 + if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
8562 + else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
8563 + }
8564 + $y+=$h;
8565 + }
8566 + $h=(GRAPH_SIZE-5)*($block['size'])/$s;
8567 + if ($h>0) {
8568 + $j++;
8569 + if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
8570 + else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
8571 + }
8572 + $y+=$h;
8573 + $ptr = $block['offset']+$block['size'];
8574 + }
8575 + if ($ptr < $mem['seg_size']) { // memory at the end
8576 + $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
8577 + if ($h > 0) {
8578 + fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
8579 + }
8580 + }
8581 + }
8582 + break;
8583 + case 4:
8584 + $s=$cache['num_hits']+$cache['num_misses'];
8585 + $a=$cache['num_hits'];
8586 +
8587 + fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
8588 + fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
8589 + break;
8590 +
8591 + }
8592 + header("Content-type: image/png");
8593 + imagepng($image);
8594 + exit;
8595 +}
8596 +
8597 +// pretty printer for byte values
8598 +//
8599 +function bsize($s) {
8600 + foreach (array('','K','M','G') as $i => $k) {
8601 + if ($s < 1024) break;
8602 + $s/=1024;
8603 + }
8604 + return sprintf("%5.1f %sBytes",$s,$k);
8605 +}
8606 +
8607 +// sortable table header in "scripts for this host" view
8608 +function sortheader($key,$name,$extra='') {
8609 + global $MYREQUEST, $MY_SELF_WO_SORT;
8610 +
8611 + if ($MYREQUEST['SORT1']==$key) {
8612 + $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
8613 + }
8614 + return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
8615 +
8616 +}
8617 +
8618 +// create menu entry
8619 +function menu_entry($ob,$title) {
8620 + global $MYREQUEST,$MY_SELF;
8621 + if ($MYREQUEST['OB']!=$ob) {
8622 + return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
8623 + } else if (empty($MYREQUEST['SH'])) {
8624 + return "<li><span class=active>$title</span></li>";
8625 + } else {
8626 + return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
8627 + }
8628 +}
8629 +
8630 +function put_login_link($s="Login")
8631 +{
8632 + global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
8633 + // needs ADMIN_PASSWORD to be changed!
8634 + //
8635 + if (!USE_AUTHENTICATION) {
8636 + return;
8637 + } else if (ADMIN_PASSWORD=='password')
8638 + {
8639 + print <<<EOB
8640 + <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
8641 +EOB;
8642 + } else if ($AUTHENTICATED) {
8643 + print <<<EOB
8644 + '{$_SERVER['PHP_AUTH_USER']}'&nbsp;logged&nbsp;in!
8645 +EOB;
8646 + } else{
8647 + print <<<EOB
8648 + <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
8649 +EOB;
8650 + }
8651 +}
8652 +
8653 +function block_sort($array1, $array2)
8654 +{
8655 + if ($array1['offset'] > $array2['offset']) {
8656 + return 1;
8657 + } else {
8658 + return -1;
8659 + }
8660 +}
8661 +
8662 +
8663 +?>
8664 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
8665 +<html>
8666 +<head><title>APC INFO <?php echo $host ?></title>
8667 +<style><!--
8668 +body { background:white; font-size:100.01%; margin:0; padding:0; }
8669 +body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
8670 +* html body {font-size:0.8em}
8671 +* html p {font-size:0.8em}
8672 +* html td {font-size:0.8em}
8673 +* html th {font-size:0.8em}
8674 +* html input {font-size:0.8em}
8675 +* html submit {font-size:0.8em}
8676 +td { vertical-align:top }
8677 +a { color:black; font-weight:none; text-decoration:none; }
8678 +a:hover { text-decoration:underline; }
8679 +div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
8680 +
8681 +
8682 +div.head div.login {
8683 + position:absolute;
8684 + right: 1em;
8685 + top: 1.2em;
8686 + color:white;
8687 + width:6em;
8688 + }
8689 +div.head div.login a {
8690 + position:absolute;
8691 + right: 0em;
8692 + background:rgb(119,123,180);
8693 + border:solid rgb(102,102,153) 2px;
8694 + color:white;
8695 + font-weight:bold;
8696 + padding:0.1em 0.5em 0.1em 0.5em;
8697 + text-decoration:none;
8698 + }
8699 +div.head div.login a:hover {
8700 + background:rgb(193,193,244);
8701 + }
8702 +
8703 +h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
8704 +* html h1.apc { margin-bottom:-7px; }
8705 +h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
8706 +h1.apc div.logo span.logo {
8707 + background:rgb(119,123,180);
8708 + color:black;
8709 + border-right: solid black 1px;
8710 + border-bottom: solid black 1px;
8711 + font-style:italic;
8712 + font-size:1em;
8713 + padding-left:1.2em;
8714 + padding-right:1.2em;
8715 + text-align:right;
8716 + }
8717 +h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
8718 +h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
8719 +h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
8720 +hr.apc {
8721 + background:white;
8722 + border-bottom:solid rgb(102,102,153) 1px;
8723 + border-style:none;
8724 + border-top:solid rgb(102,102,153) 10px;
8725 + height:12px;
8726 + margin:0;
8727 + margin-top:1px;
8728 + padding:0;
8729 +}
8730 +
8731 +ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
8732 +ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
8733 +ol.menu a {
8734 + background:rgb(153,153,204);
8735 + border:solid rgb(102,102,153) 2px;
8736 + color:white;
8737 + font-weight:bold;
8738 + margin-right:0em;
8739 + padding:0.1em 0.5em 0.1em 0.5em;
8740 + text-decoration:none;
8741 + margin-left: 5px;
8742 + }
8743 +ol.menu a.child_active {
8744 + background:rgb(153,153,204);
8745 + border:solid rgb(102,102,153) 2px;
8746 + color:white;
8747 + font-weight:bold;
8748 + margin-right:0em;
8749 + padding:0.1em 0.5em 0.1em 0.5em;
8750 + text-decoration:none;
8751 + border-left: solid black 5px;
8752 + margin-left: 0px;
8753 + }
8754 +ol.menu span.active {
8755 + background:rgb(153,153,204);
8756 + border:solid rgb(102,102,153) 2px;
8757 + color:black;
8758 + font-weight:bold;
8759 + margin-right:0em;
8760 + padding:0.1em 0.5em 0.1em 0.5em;
8761 + text-decoration:none;
8762 + border-left: solid black 5px;
8763 + }
8764 +ol.menu span.inactive {
8765 + background:rgb(193,193,244);
8766 + border:solid rgb(182,182,233) 2px;
8767 + color:white;
8768 + font-weight:bold;
8769 + margin-right:0em;
8770 + padding:0.1em 0.5em 0.1em 0.5em;
8771 + text-decoration:none;
8772 + margin-left: 5px;
8773 + }
8774 +ol.menu a:hover {
8775 + background:rgb(193,193,244);
8776 + text-decoration:none;
8777 + }
8778 +
8779 +
8780 +div.info {
8781 + background:rgb(204,204,204);
8782 + border:solid rgb(204,204,204) 1px;
8783 + margin-bottom:1em;
8784 + }
8785 +div.info h2 {
8786 + background:rgb(204,204,204);
8787 + color:black;
8788 + font-size:1em;
8789 + margin:0;
8790 + padding:0.1em 1em 0.1em 1em;
8791 + }
8792 +div.info table {
8793 + border:solid rgb(204,204,204) 1px;
8794 + border-spacing:0;
8795 + width:100%;
8796 + }
8797 +div.info table th {
8798 + background:rgb(204,204,204);
8799 + color:white;
8800 + margin:0;
8801 + padding:0.1em 1em 0.1em 1em;
8802 + }
8803 +div.info table th a.sortable { color:black; }
8804 +div.info table tr.tr-0 { background:rgb(238,238,238); }
8805 +div.info table tr.tr-1 { background:rgb(221,221,221); }
8806 +div.info table td { padding:0.3em 1em 0.3em 1em; }
8807 +div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
8808 +div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
8809 +div.info table td h3 {
8810 + color:black;
8811 + font-size:1.1em;
8812 + margin-left:-0.3em;
8813 + }
8814 +
8815 +div.graph { margin-bottom:1em }
8816 +div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
8817 +div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
8818 +div.graph table td.td-0 { background:rgb(238,238,238); }
8819 +div.graph table td.td-1 { background:rgb(221,221,221); }
8820 +div.graph table td { padding:0.2em 1em 0.4em 1em; }
8821 +
8822 +div.div1,div.div2 { margin-bottom:1em; width:35em; }
8823 +div.div3 { position:absolute; left:40em; top:1em; width:580px; }
8824 +//div.div3 { position:absolute; left:37em; top:1em; right:1em; }
8825 +
8826 +div.sorting { margin:1.5em 0em 1.5em 2em }
8827 +.center { text-align:center }
8828 +.aright { position:absolute;right:1em }
8829 +.right { text-align:right }
8830 +.ok { color:rgb(0,200,0); font-weight:bold}
8831 +.failed { color:rgb(200,0,0); font-weight:bold}
8832 +
8833 +span.box {
8834 + border: black solid 1px;
8835 + border-right:solid black 2px;
8836 + border-bottom:solid black 2px;
8837 + padding:0 0.5em 0 0.5em;
8838 + margin-right:1em;
8839 +}
8840 +span.green { background:#60F060; padding:0 0.5em 0 0.5em}
8841 +span.red { background:#D06030; padding:0 0.5em 0 0.5em }
8842 +
8843 +div.authneeded {
8844 + background:rgb(238,238,238);
8845 + border:solid rgb(204,204,204) 1px;
8846 + color:rgb(200,0,0);
8847 + font-size:1.2em;
8848 + font-weight:bold;
8849 + padding:2em;
8850 + text-align:center;
8851 + }
8852 +
8853 +input {
8854 + background:rgb(153,153,204);
8855 + border:solid rgb(102,102,153) 2px;
8856 + color:white;
8857 + font-weight:bold;
8858 + margin-right:1em;
8859 + padding:0.1em 0.5em 0.1em 0.5em;
8860 + }
8861 +//-->
8862 +</style>
8863 +</head>
8864 +<body>
8865 +<div class="head">
8866 + <h1 class="apc">
8867 + <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
8868 + <div class="nameinfo">Opcode Cache</div>
8869 + </h1>
8870 + <div class="login">
8871 + <?php put_login_link(); ?>
8872 + </div>
8873 + <hr class="apc">
8874 +</div>
8875 +<?php
8876 +
8877 +
8878 +// Display main Menu
8879 +echo <<<EOB
8880 + <ol class=menu>
8881 + <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
8882 +EOB;
8883 +echo
8884 + menu_entry(1,'View Host Stats'),
8885 + menu_entry(2,'System Cache Entries');
8886 +if ($AUTHENTICATED) {
8887 + echo menu_entry(4,'Per-Directory Entries');
8888 +}
8889 +echo
8890 + menu_entry(3,'User Cache Entries'),
8891 + menu_entry(9,'Version Check');
8892 +
8893 +if ($AUTHENTICATED) {
8894 + echo <<<EOB
8895 + <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascipt:return confirm('Are you sure?');">Clear $cache_mode Cache</a></li>
8896 +EOB;
8897 +}
8898 +echo <<<EOB
8899 + </ol>
8900 +EOB;
8901 +
8902 +
8903 +// CONTENT
8904 +echo <<<EOB
8905 + <div class=content>
8906 +EOB;
8907 +
8908 +// MAIN SWITCH STATEMENT
8909 +
8910 +switch ($MYREQUEST['OB']) {
8911 +
8912 +
8913 +
8914 +
8915 +
8916 +// -----------------------------------------------
8917 +// Host Stats
8918 +// -----------------------------------------------
8919 +case OB_HOST_STATS:
8920 + $mem_size = $mem['num_seg']*$mem['seg_size'];
8921 + $mem_avail= $mem['avail_mem'];
8922 + $mem_used = $mem_size-$mem_avail;
8923 + $seg_size = bsize($mem['seg_size']);
8924 + $req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
8925 + $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
8926 + $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
8927 + $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
8928 + $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
8929 + $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
8930 + $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
8931 + $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
8932 + $apcversion = phpversion('apc');
8933 + $phpversion = phpversion();
8934 + $number_files = $cache['num_entries'];
8935 + $size_files = bsize($cache['mem_size']);
8936 + $number_vars = $cache_user['num_entries'];
8937 + $size_vars = bsize($cache_user['mem_size']);
8938 + $i=0;
8939 + echo <<< EOB
8940 + <div class="info div1"><h2>General Cache Information</h2>
8941 + <table cellspacing=0><tbody>
8942 + <tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
8943 + <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
8944 +EOB;
8945 +
8946 + if(!empty($_SERVER['SERVER_NAME']))
8947 + echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
8948 + if(!empty($_SERVER['SERVER_SOFTWARE']))
8949 + echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
8950 +
8951 + echo <<<EOB
8952 + <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
8953 + <br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
8954 + </td></tr>
8955 +EOB;
8956 + echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
8957 + echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
8958 + echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
8959 + echo <<<EOB
8960 + </tbody></table>
8961 + </div>
8962 +
8963 + <div class="info div1"><h2>File Cache Information</h2>
8964 + <table cellspacing=0><tbody>
8965 + <tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
8966 + <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
8967 + <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
8968 + <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
8969 + <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
8970 + <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
8971 + <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
8972 + <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
8973 + </tbody></table>
8974 + </div>
8975 +
8976 + <div class="info div1"><h2>User Cache Information</h2>
8977 + <table cellspacing=0><tbody>
8978 + <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
8979 + <tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
8980 + <tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
8981 + <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
8982 + <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
8983 + <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
8984 + <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
8985 + <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
8986 +
8987 + </tbody></table>
8988 + </div>
8989 +
8990 + <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
8991 +EOB;
8992 +
8993 + $j = 0;
8994 + foreach (ini_get_all('apc') as $k => $v) {
8995 + echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
8996 + $j = 1 - $j;
8997 + }
8998 +
8999 + if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
9000 + $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
9001 + else
9002 + $mem_note = "Memory Usage";
9003 +
9004 + echo <<< EOB
9005 + </tbody></table>
9006 + </div>
9007 +
9008 + <div class="graph div3"><h2>Host Status Diagrams</h2>
9009 + <table cellspacing=0><tbody>
9010 +EOB;
9011 + $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
9012 + echo <<<EOB
9013 + <tr>
9014 + <td class=td-0>$mem_note</td>
9015 + <td class=td-1>Hits &amp; Misses</td>
9016 + </tr>
9017 +EOB;
9018 +
9019 + echo
9020 + graphics_avail() ?
9021 + '<tr>'.
9022 + "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
9023 + "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
9024 + : "",
9025 + '<tr>',
9026 + '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
9027 + '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
9028 + '</tr>',
9029 + '<tr>',
9030 + '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
9031 + '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
9032 + echo <<< EOB
9033 + </tr>
9034 + </tbody></table>
9035 +
9036 + <br/>
9037 + <h2>Detailed Memory Usage and Fragmentation</h2>
9038 + <table cellspacing=0><tbody>
9039 + <tr>
9040 + <td class=td-0 colspan=2><br/>
9041 +EOB;
9042 +
9043 + // Fragementation: (freeseg - 1) / total_seg
9044 + $nseg = $freeseg = $fragsize = $freetotal = 0;
9045 + for($i=0; $i<$mem['num_seg']; $i++) {
9046 + $ptr = 0;
9047 + foreach($mem['block_lists'][$i] as $block) {
9048 + if ($block['offset'] != $ptr) {
9049 + ++$nseg;
9050 + }
9051 + $ptr = $block['offset'] + $block['size'];
9052 + /* Only consider blocks <5M for the fragmentation % */
9053 + if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
9054 + $freetotal+=$block['size'];
9055 + }
9056 + $freeseg += count($mem['block_lists'][$i]);
9057 + }
9058 +
9059 + if ($freeseg > 1) {
9060 + $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
9061 + } else {
9062 + $frag = "0%";
9063 + }
9064 +
9065 + if (graphics_avail()) {
9066 + $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
9067 + echo <<<EOB
9068 + <img alt="" $size src="$PHP_SELF?IMG=3&$time">
9069 +EOB;
9070 + }
9071 + echo <<<EOB
9072 + </br>Fragmentation: $frag
9073 + </td>
9074 + </tr>
9075 +EOB;
9076 + if(isset($mem['adist'])) {
9077 + foreach($mem['adist'] as $i=>$v) {
9078 + $cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
9079 + if($i==0) $range = "1";
9080 + else $range = "$cur - $nxt";
9081 + echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
9082 + }
9083 + }
9084 + echo <<<EOB
9085 + </tbody></table>
9086 + </div>
9087 +EOB;
9088 +
9089 + break;
9090 +
9091 +
9092 +// -----------------------------------------------
9093 +// User Cache Entries
9094 +// -----------------------------------------------
9095 +case OB_USER_CACHE:
9096 + if (!$AUTHENTICATED) {
9097 + echo '<div class="error">You need to login to see the user values here!<br/>&nbsp;<br/>';
9098 + put_login_link("Login now!");
9099 + echo '</div>';
9100 + break;
9101 + }
9102 + $fieldname='info';
9103 + $fieldheading='User Entry Label';
9104 + $fieldkey='info';
9105 +
9106 +// -----------------------------------------------
9107 +// System Cache Entries
9108 +// -----------------------------------------------
9109 +case OB_SYS_CACHE:
9110 + if (!isset($fieldname))
9111 + {
9112 + $fieldname='filename';
9113 + $fieldheading='Script Filename';
9114 + if(ini_get("apc.stat")) $fieldkey='inode';
9115 + else $fieldkey='filename';
9116 + }
9117 + if (!empty($MYREQUEST['SH']))
9118 + {
9119 + echo <<< EOB
9120 + <div class="info"><table cellspacing=0><tbody>
9121 + <tr><th>Attribute</th><th>Value</th></tr>
9122 +EOB;
9123 +
9124 + $m=0;
9125 + foreach($scope_list as $j => $list) {
9126 + foreach($cache[$list] as $i => $entry) {
9127 + if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
9128 + foreach($entry as $k => $value) {
9129 + if (!$AUTHENTICATED) {
9130 + // hide all path entries if not logged in
9131 + $value=preg_replace('/^.*(\\/|\\\\)/','<i>&lt;hidden&gt;</i>/',$value);
9132 + }
9133 +
9134 + if ($k == "num_hits") {
9135 + $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
9136 + }
9137 + if ($k == 'deletion_time') {
9138 + if(!$entry['deletion_time']) $value = "None";
9139 + }
9140 + echo
9141 + "<tr class=tr-$m>",
9142 + "<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
9143 + "<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"</td>",
9144 + "</tr>";
9145 + $m=1-$m;
9146 + }
9147 + if($fieldkey=='info') {
9148 + echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
9149 + $output = var_export(apc_fetch($entry[$fieldkey]),true);
9150 + echo htmlspecialchars($output);
9151 + echo "</pre></td></tr>\n";
9152 + }
9153 + break;
9154 + }
9155 + }
9156 +
9157 + echo <<<EOB
9158 + </tbody></table>
9159 + </div>
9160 +EOB;
9161 + break;
9162 + }
9163 +
9164 + $cols=6;
9165 + echo <<<EOB
9166 + <div class=sorting><form>Scope:
9167 + <input type=hidden name=OB value={$MYREQUEST['OB']}>
9168 + <select name=SCOPE>
9169 +EOB;
9170 + echo
9171 + "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
9172 + "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
9173 + "</select>",
9174 + ", Sorting:<select name=SORT1>",
9175 + "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
9176 + "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
9177 + "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
9178 + "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
9179 + "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
9180 + "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
9181 + "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
9182 + if($fieldname=='info') echo
9183 + "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
9184 + echo
9185 + '</select>',
9186 + '<select name=SORT2>',
9187 + '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
9188 + '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
9189 + '</select>',
9190 + '<select name=COUNT onChange="form.submit()">',
9191 + '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
9192 + '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
9193 + '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
9194 + '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
9195 + '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
9196 + '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
9197 + '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
9198 + '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
9199 + '</select>',
9200 + '&nbsp; Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
9201 + '&nbsp;<input type=submit value="GO!">',
9202 + '</form></div>';
9203 +
9204 + if (isset($MYREQUEST['SEARCH'])) {
9205 + // Don't use preg_quote because we want the user to be able to specify a
9206 + // regular expression subpattern.
9207 + $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i';
9208 + if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
9209 + echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
9210 + break;
9211 + }
9212 + }
9213 +
9214 + echo
9215 + '<div class="info"><table cellspacing=0><tbody>',
9216 + '<tr>',
9217 + '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
9218 + '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
9219 + '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
9220 + '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
9221 + '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
9222 + '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
9223 +
9224 + if($fieldname=='info') {
9225 + $cols+=2;
9226 + echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
9227 + }
9228 + echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
9229 +
9230 + // builds list with alpha numeric sortable keys
9231 + //
9232 + $list = array();
9233 + foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
9234 + switch($MYREQUEST['SORT1']) {
9235 + case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
9236 + case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
9237 + case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
9238 + case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
9239 + case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
9240 + case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
9241 + case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
9242 + case 'S': $k=''; break;
9243 + }
9244 + if (!$AUTHENTICATED) {
9245 + // hide all path entries if not logged in
9246 + $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry);
9247 + } else {
9248 + $list[$k.$entry[$fieldname]]=$entry;
9249 + }
9250 + }
9251 +
9252 + if ($list) {
9253 +
9254 + // sort list
9255 + //
9256 + switch ($MYREQUEST['SORT2']) {
9257 + case "A": krsort($list); break;
9258 + case "D": ksort($list); break;
9259 + }
9260 +
9261 + // output list
9262 + $i=0;
9263 + foreach($list as $k => $entry) {
9264 + if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
9265 + $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8');
9266 + echo
9267 + '<tr class=tr-',$i%2,'>',
9268 + "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$field_value,'</a></td>',
9269 + '<td class="td-n center">',$entry['num_hits'],'</td>',
9270 + '<td class="td-n right">',$entry['mem_size'],'</td>',
9271 + '<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
9272 + '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
9273 + '<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
9274 +
9275 + if($fieldname=='info') {
9276 + if($entry['ttl'])
9277 + echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
9278 + else
9279 + echo '<td class="td-n center">None</td>';
9280 + }
9281 + if ($entry['deletion_time']) {
9282 +
9283 + echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>';
9284 + } else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
9285 +
9286 + echo '<td class="td-last center">';
9287 + echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
9288 + echo '</td>';
9289 + } else {
9290 + echo '<td class="td-last center"> &nbsp; </td>';
9291 + }
9292 + echo '</tr>';
9293 + $i++;
9294 + if ($i == $MYREQUEST['COUNT'])
9295 + break;
9296 + }
9297 + }
9298 +
9299 + } else {
9300 + echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
9301 + }
9302 + echo <<< EOB
9303 + </tbody></table>
9304 +EOB;
9305 +
9306 + if ($list && $i < count($list)) {
9307 + echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
9308 + }
9309 +
9310 + echo <<< EOB
9311 + </div>
9312 +EOB;
9313 + break;
9314 +
9315 +
9316 +// -----------------------------------------------
9317 +// Per-Directory System Cache Entries
9318 +// -----------------------------------------------
9319 +case OB_SYS_CACHE_DIR:
9320 + if (!$AUTHENTICATED) {
9321 + break;
9322 + }
9323 +
9324 + echo <<<EOB
9325 + <div class=sorting><form>Scope:
9326 + <input type=hidden name=OB value={$MYREQUEST['OB']}>
9327 + <select name=SCOPE>
9328 +EOB;
9329 + echo
9330 + "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
9331 + "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
9332 + "</select>",
9333 + ", Sorting:<select name=SORT1>",
9334 + "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
9335 + "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
9336 + "<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
9337 + "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
9338 + "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
9339 + "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
9340 + '</select>',
9341 + '<select name=SORT2>',
9342 + '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
9343 + '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
9344 + '</select>',
9345 + '<select name=COUNT onChange="form.submit()">',
9346 + '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
9347 + '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
9348 + '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
9349 + '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
9350 + '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
9351 + '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
9352 + '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
9353 + '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
9354 + '</select>',
9355 + ", Group By Dir Level:<select name=AGGR>",
9356 + "<option value='' selected>None</option>";
9357 + for ($i = 1; $i < 10; $i++)
9358 + echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
9359 + echo '</select>',
9360 + '&nbsp;<input type=submit value="GO!">',
9361 + '</form></div>',
9362 +
9363 + '<div class="info"><table cellspacing=0><tbody>',
9364 + '<tr>',
9365 + '<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
9366 + '<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
9367 + '<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
9368 + '<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
9369 + '<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
9370 + '<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
9371 + '</tr>';
9372 +
9373 + // builds list with alpha numeric sortable keys
9374 + //
9375 + $tmp = $list = array();
9376 + foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
9377 + $n = dirname($entry['filename']);
9378 + if ($MYREQUEST['AGGR'] > 0) {
9379 + $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
9380 + }
9381 + if (!isset($tmp[$n])) {
9382 + $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
9383 + }
9384 + $tmp[$n]['hits'] += $entry['num_hits'];
9385 + $tmp[$n]['size'] += $entry['mem_size'];
9386 + ++$tmp[$n]['ents'];
9387 + }
9388 +
9389 + foreach ($tmp as $k => $v) {
9390 + switch($MYREQUEST['SORT1']) {
9391 + case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
9392 + case 'T': $kn=sprintf('%015d-',$v['ents']); break;
9393 + case 'H': $kn=sprintf('%015d-',$v['hits']); break;
9394 + case 'Z': $kn=sprintf('%015d-',$v['size']); break;
9395 + case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
9396 + case 'S': $kn = $k; break;
9397 + }
9398 + $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
9399 + }
9400 +
9401 + if ($list) {
9402 +
9403 + // sort list
9404 + //
9405 + switch ($MYREQUEST['SORT2']) {
9406 + case "A": krsort($list); break;
9407 + case "D": ksort($list); break;
9408 + }
9409 +
9410 + // output list
9411 + $i = 0;
9412 + foreach($list as $entry) {
9413 + echo
9414 + '<tr class=tr-',$i%2,'>',
9415 + "<td class=td-0>",$entry[0],'</a></td>',
9416 + '<td class="td-n center">',$entry[1],'</td>',
9417 + '<td class="td-n center">',$entry[2],'</td>',
9418 + '<td class="td-n center">',$entry[3],'</td>',
9419 + '<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
9420 + '<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
9421 + '</tr>';
9422 +
9423 + if (++$i == $MYREQUEST['COUNT']) break;
9424 + }
9425 +
9426 + } else {
9427 + echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
9428 + }
9429 + echo <<< EOB
9430 + </tbody></table>
9431 +EOB;
9432 +
9433 + if ($list && $i < count($list)) {
9434 + echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
9435 + }
9436 +
9437 + echo <<< EOB
9438 + </div>
9439 +EOB;
9440 + break;
9441 +
9442 +// -----------------------------------------------
9443 +// Version check
9444 +// -----------------------------------------------
9445 +case OB_VERSION_CHECK:
9446 + echo <<<EOB
9447 + <div class="info"><h2>APC Version Information</h2>
9448 + <table cellspacing=0><tbody>
9449 + <tr>
9450 + <th></th>
9451 + </tr>
9452 +EOB;
9453 + if (defined('PROXY')) {
9454 + $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) );
9455 + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt);
9456 + } else {
9457 + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
9458 + }
9459 + if (!$rss) {
9460 + echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
9461 + } else {
9462 + $apcversion = phpversion('apc');
9463 +
9464 + preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
9465 + echo '<tr class="tr-0 center"><td>';
9466 + if (version_compare($apcversion, $match[1], '>=')) {
9467 + echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
9468 + $i = 3;
9469 + } else {
9470 + echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
9471 + newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
9472 + http://pecl.php.net/package/APC/'.$match[1].'</a>
9473 + </div>';
9474 + $i = -1;
9475 + }
9476 + echo '</td></tr>';
9477 + echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
9478 +
9479 + preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
9480 + next($match[2]); next($match[2]);
9481 +
9482 + while (list(,$v) = each($match[2])) {
9483 + list(,$ver) = explode(' ', $v, 2);
9484 + if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
9485 + break;
9486 + } else if (!$i--) {
9487 + break;
9488 + }
9489 + echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v)."</a></b><br><blockquote>";
9490 + echo nl2br(htmlspecialchars(current($match[2])))."</blockquote>";
9491 + next($match[2]);
9492 + }
9493 + echo '</td></tr>';
9494 + }
9495 + echo <<< EOB
9496 + </tbody></table>
9497 + </div>
9498 +EOB;
9499 + break;
9500 +
9501 +}
9502 +
9503 +echo <<< EOB
9504 + </div>
9505 +EOB;
9506 +
9507 +?>
9508 +
9509 +<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
9510 +</body>
9511 +</html>
9512 diff -Naur php-5.3.1.orig/ext/apc/apc_php.h php-5.3.1/ext/apc/apc_php.h
9513 --- php-5.3.1.orig/ext/apc/apc_php.h 1970-01-01 01:00:00.000000000 +0100
9514 +++ php-5.3.1/ext/apc/apc_php.h 1970-01-01 10:13:08.000000000 +0100
9515 @@ -0,0 +1,74 @@
9516 +/*
9517 + +----------------------------------------------------------------------+
9518 + | APC |
9519 + +----------------------------------------------------------------------+
9520 + | Copyright (c) 2006-2008 The PHP Group |
9521 + +----------------------------------------------------------------------+
9522 + | This source file is subject to version 3.01 of the PHP license, |
9523 + | that is bundled with this package in the file LICENSE, and is |
9524 + | available through the world-wide-web at the following url: |
9525 + | http://www.php.net/license/3_01.txt |
9526 + | If you did not receive a copy of the PHP license and are unable to |
9527 + | obtain it through the world-wide-web, please send a note to |
9528 + | license@php.net so we can mail you a copy immediately. |
9529 + +----------------------------------------------------------------------+
9530 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
9531 + | George Schlossnagle <george@omniti.com> |
9532 + | Rasmus Lerdorf <rasmus@php.net> |
9533 + | Arun C. Murthy <arunc@yahoo-inc.com> |
9534 + | Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
9535 + +----------------------------------------------------------------------+
9536 +
9537 + This software was contributed to PHP by Community Connect Inc. in 2002
9538 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
9539 + Future revisions and derivatives of this source code must acknowledge
9540 + Community Connect Inc. as the original contributor of this module by
9541 + leaving this note intact in the source code.
9542 +
9543 + All other licensing and usage conditions are those of the PHP Group.
9544 +
9545 + */
9546 +
9547 +/* $Id: apc_php.h 268255 2008-11-04 05:42:11Z rasmus $ */
9548 +
9549 +#ifndef APC_PHP_H
9550 +#define APC_PHP_H
9551 +
9552 +/*
9553 + * The purpose of this header file is to include all PHP and Zend headers that
9554 + * are typically needed elsewhere in APC. This makes it easy to insure that
9555 + * all required headers are available.
9556 + */
9557 +
9558 +#include "php.h"
9559 +#include "zend.h"
9560 +#include "zend_API.h"
9561 +#include "zend_compile.h"
9562 +#include "zend_hash.h"
9563 +#include "zend_extensions.h"
9564 +
9565 +#if ZEND_MODULE_API_NO > 20060613
9566 +#define ZEND_ENGINE_2_3
9567 +#endif
9568 +#if ZEND_MODULE_API_NO > 20050922
9569 +#define ZEND_ENGINE_2_2
9570 +#endif
9571 +#if ZEND_MODULE_API_NO > 20050921
9572 +#define ZEND_ENGINE_2_1
9573 +#endif
9574 +#ifdef ZEND_ENGINE_2_1
9575 +#include "zend_vm.h"
9576 +#endif
9577 +
9578 +#include "rfc1867.h"
9579 +
9580 +#endif
9581 +
9582 +/*
9583 + * Local variables:
9584 + * tab-width: 4
9585 + * c-basic-offset: 4
9586 + * End:
9587 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
9588 + * vim<600: expandtab sw=4 ts=4 sts=4
9589 + */
9590 diff -Naur php-5.3.1.orig/ext/apc/apc_pool.c php-5.3.1/ext/apc/apc_pool.c
9591 --- php-5.3.1.orig/ext/apc/apc_pool.c 1970-01-01 01:00:00.000000000 +0100
9592 +++ php-5.3.1/ext/apc/apc_pool.c 1970-01-01 10:13:08.000000000 +0100
9593 @@ -0,0 +1,484 @@
9594 +/*
9595 + +----------------------------------------------------------------------+
9596 + | APC |
9597 + +----------------------------------------------------------------------+
9598 + | Copyright (c) 2008 The PHP Group |
9599 + +----------------------------------------------------------------------+
9600 + | This source file is subject to version 3.01 of the PHP license, |
9601 + | that is bundled with this package in the file LICENSE, and is |
9602 + | available through the world-wide-web at the following url: |
9603 + | http://www.php.net/license/3_01.txt. |
9604 + | If you did not receive a copy of the PHP license and are unable to |
9605 + | obtain it through the world-wide-web, please send a note to |
9606 + | license@php.net so we can mail you a copy immediately. |
9607 + +----------------------------------------------------------------------+
9608 + | Authors: Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
9609 + +----------------------------------------------------------------------+
9610 +
9611 + This software was contributed to PHP by Yahoo! Inc. in 2008.
9612 +
9613 + Future revisions and derivatives of this source code must acknowledge
9614 + Yahoo! Inc. as the original contributor of this module by
9615 + leaving this note intact in the source code.
9616 +
9617 + All other licensing and usage conditions are those of the PHP Group.
9618 +
9619 + */
9620 +
9621 +/* $Id: apc_pool.c 281353 2009-05-28 23:45:08Z kalle $ */
9622 +
9623 +
9624 +#include "apc_pool.h"
9625 +#include <assert.h>
9626 +
9627 +#ifdef HAVE_VALGRIND_MEMCHECK_H
9628 +#include <valgrind/memcheck.h>
9629 +#endif
9630 +
9631 +
9632 +/* {{{ forward references */
9633 +static apc_pool* apc_unpool_create(apc_pool_type type, apc_malloc_t, apc_free_t, apc_protect_t, apc_unprotect_t);
9634 +static apc_pool* apc_realpool_create(apc_pool_type type, apc_malloc_t, apc_free_t, apc_protect_t, apc_unprotect_t);
9635 +/* }}} */
9636 +
9637 +/* {{{ apc_pool_create */
9638 +apc_pool* apc_pool_create(apc_pool_type pool_type,
9639 + apc_malloc_t allocate,
9640 + apc_free_t deallocate,
9641 + apc_protect_t protect,
9642 + apc_unprotect_t unprotect)
9643 +{
9644 + if(pool_type == APC_UNPOOL) {
9645 + return apc_unpool_create(pool_type, allocate, deallocate,
9646 + protect, unprotect );
9647 + }
9648 +
9649 + return apc_realpool_create(pool_type, allocate, deallocate,
9650 + protect, unprotect );
9651 +}
9652 +/* }}} */
9653 +
9654 +/* {{{ apc_pool_destroy */
9655 +void apc_pool_destroy(apc_pool *pool)
9656 +{
9657 + apc_free_t deallocate = pool->deallocate;
9658 + apc_pcleanup_t cleanup = pool->cleanup;
9659 +
9660 + cleanup(pool);
9661 + deallocate(pool);
9662 +}
9663 +/* }}} */
9664 +
9665 +/* {{{ apc_unpool implementation */
9666 +
9667 +typedef struct _apc_unpool apc_unpool;
9668 +
9669 +struct _apc_unpool {
9670 + apc_pool parent;
9671 + /* apc_unpool is a lie! */
9672 +};
9673 +
9674 +static void* apc_unpool_alloc(apc_pool* pool, size_t size)
9675 +{
9676 + apc_unpool *upool = (apc_unpool*)pool;
9677 +
9678 + apc_malloc_t allocate = upool->parent.allocate;
9679 +
9680 + upool->parent.size += size;
9681 + upool->parent.used += size;
9682 +
9683 + return allocate(size);
9684 +}
9685 +
9686 +static void apc_unpool_free(apc_pool* pool, void *ptr)
9687 +{
9688 + apc_unpool *upool = (apc_unpool*) pool;
9689 +
9690 + apc_free_t deallocate = upool->parent.deallocate;
9691 +
9692 + deallocate(ptr);
9693 +}
9694 +
9695 +static void apc_unpool_cleanup(apc_pool* pool)
9696 +{
9697 +}
9698 +
9699 +static apc_pool* apc_unpool_create(apc_pool_type type,
9700 + apc_malloc_t allocate, apc_free_t deallocate,
9701 + apc_protect_t protect, apc_unprotect_t unprotect)
9702 +{
9703 + apc_unpool* upool = allocate(sizeof(apc_unpool));
9704 +
9705 + if (!upool) {
9706 + return NULL;
9707 + }
9708 +
9709 + upool->parent.type = type;
9710 + upool->parent.allocate = allocate;
9711 + upool->parent.deallocate = deallocate;
9712 +
9713 + upool->parent.protect = protect;
9714 + upool->parent.unprotect = unprotect;
9715 +
9716 + upool->parent.palloc = apc_unpool_alloc;
9717 + upool->parent.pfree = apc_unpool_free;
9718 +
9719 + upool->parent.cleanup = apc_unpool_cleanup;
9720 +
9721 + upool->parent.used = 0;
9722 + upool->parent.size = 0;
9723 +
9724 + return &(upool->parent);
9725 +}
9726 +/* }}} */
9727 +
9728 +
9729 +/*{{{ apc_realpool implementation */
9730 +
9731 +/* {{{ typedefs */
9732 +typedef struct _pool_block
9733 +{
9734 + size_t avail;
9735 + size_t capacity;
9736 + unsigned char *mark;
9737 + struct _pool_block *next;
9738 + unsigned :0; /* this should align to word */
9739 + /* data comes here */
9740 +}pool_block;
9741 +
9742 +/*
9743 + parts in ? are optional and turned on for fun, memory loss,
9744 + and for something else that I forgot about ... ah, debugging
9745 +
9746 + |--------> data[] |<-- non word boundary (too)
9747 + +-------------+--------------+-----------+-------------+-------------->>>
9748 + | pool_block | ?sizeinfo<1> | block<1> | ?redzone<1> | ?sizeinfo<2>
9749 + | | (size_t) | | padded left |
9750 + +-------------+--------------+-----------+-------------+-------------->>>
9751 + */
9752 +
9753 +typedef struct _apc_realpool apc_realpool;
9754 +
9755 +struct _apc_realpool
9756 +{
9757 + struct _apc_pool parent;
9758 +
9759 + size_t dsize;
9760 + void *owner;
9761 +
9762 + pool_block *head;
9763 + pool_block first;
9764 +};
9765 +
9766 +/* }}} */
9767 +
9768 +/* {{{ redzone code */
9769 +static const unsigned char decaff[] = {
9770 + 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
9771 + 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
9772 + 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad,
9773 + 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad
9774 +};
9775 +
9776 +/* a redzone is at least 4 (0xde,0xca,0xc0,0xff) bytes */
9777 +#define REDZONE_SIZE(size) \
9778 + ((ALIGNWORD((size)) > ((size) + 4)) ? \
9779 + (ALIGNWORD((size)) - (size)) : /* does not change realsize */\
9780 + ALIGNWORD((size)) - (size) + ALIGNWORD((sizeof(char)))) /* adds 1 word to realsize */
9781 +
9782 +#define SIZEINFO_SIZE ALIGNWORD(sizeof(size_t))
9783 +
9784 +#define MARK_REDZONE(block, redsize) do {\
9785 + memcpy(block, decaff, redsize );\
9786 + } while(0)
9787 +
9788 +#define CHECK_REDZONE(block, redsize) (memcmp(block, decaff, redsize) == 0)
9789 +
9790 +/* }}} */
9791 +
9792 +#define INIT_POOL_BLOCK(rpool, entry, size) do {\
9793 + (entry)->avail = (entry)->capacity = (size);\
9794 + (entry)->mark = ((unsigned char*)(entry)) + ALIGNWORD(sizeof(pool_block));\
9795 + (entry)->next = (rpool)->head;\
9796 + (rpool)->head = (entry);\
9797 +} while(0)
9798 +
9799 +/* {{{ create_pool_block */
9800 +static pool_block* create_pool_block(apc_realpool *rpool, size_t size)
9801 +{
9802 + apc_malloc_t allocate = rpool->parent.allocate;
9803 +
9804 + size_t realsize = sizeof(pool_block) + ALIGNWORD(size);
9805 +
9806 + pool_block* entry = allocate(realsize);
9807 +
9808 + if (!entry) {
9809 + return NULL;
9810 + }
9811 +
9812 + INIT_POOL_BLOCK(rpool, entry, size);
9813 +
9814 + rpool->parent.size += realsize;
9815 +
9816 + return entry;
9817 +}
9818 +/* }}} */
9819 +
9820 +/* {{{ apc_realpool_alloc */
9821 +static void* apc_realpool_alloc(apc_pool *pool, size_t size)
9822 +{
9823 + apc_realpool *rpool = (apc_realpool*)pool;
9824 + unsigned char *p = NULL;
9825 + size_t realsize = ALIGNWORD(size);
9826 + size_t poolsize;
9827 + unsigned char *redzone = NULL;
9828 + size_t redsize = 0;
9829 + size_t *sizeinfo= NULL;
9830 +
9831 + pool_block *entry;
9832 +
9833 + if(APC_POOL_HAS_REDZONES(pool)) {
9834 + redsize = REDZONE_SIZE(size); /* redsize might be re-using word size padding */
9835 + realsize = size + redsize; /* recalculating realsize */
9836 + } else {
9837 + redsize = realsize - size; /* use padding space */
9838 + }
9839 +
9840 + if(APC_POOL_HAS_SIZEINFO(pool)) {
9841 + realsize += ALIGNWORD(sizeof(size_t));
9842 + }
9843 +
9844 +
9845 + for(entry = rpool->head; entry != NULL; entry = entry->next) {
9846 + if(entry->avail >= realsize) {
9847 + goto found;
9848 + }
9849 + }
9850 +
9851 + poolsize = ALIGNSIZE(realsize, rpool->dsize);
9852 +
9853 + entry = create_pool_block(rpool, poolsize);
9854 +
9855 + if(!entry) {
9856 + return NULL;
9857 + }
9858 +
9859 +found:
9860 + p = entry->mark;
9861 +
9862 + if(APC_POOL_HAS_SIZEINFO(pool)) {
9863 + sizeinfo = (size_t*)p;
9864 + p += SIZEINFO_SIZE;
9865 + *sizeinfo = size;
9866 + }
9867 +
9868 + redzone = p + size;
9869 +
9870 + if(APC_POOL_HAS_REDZONES(pool)) {
9871 + MARK_REDZONE(redzone, redsize);
9872 + }
9873 +
9874 +#ifdef VALGRIND_MAKE_MEM_NOACCESS
9875 + if(redsize != 0) {
9876 + VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize);
9877 + }
9878 +#endif
9879 +
9880 + entry->avail -= realsize;
9881 + entry->mark += realsize;
9882 + pool->used += realsize;
9883 +
9884 +#ifdef VALGRIND_MAKE_MEM_UNDEFINED
9885 + /* need to write before reading data off this */
9886 + VALGRIND_MAKE_MEM_UNDEFINED(p, size);
9887 +#endif
9888 +
9889 + return (void*)p;
9890 +}
9891 +/* }}} */
9892 +
9893 +/* {{{ apc_realpool_check_integrity */
9894 +/*
9895 + * Checking integrity at runtime, does an
9896 + * overwrite check only when the sizeinfo
9897 + * is set.
9898 + */
9899 +static int apc_realpool_check_integrity(apc_realpool *rpool)
9900 +{
9901 + apc_pool *pool = &(rpool->parent);
9902 + pool_block *entry;
9903 + size_t *sizeinfo = NULL;
9904 + unsigned char *start;
9905 + size_t realsize;
9906 + unsigned char *redzone;
9907 + size_t redsize;
9908 +
9909 + for(entry = rpool->head; entry != NULL; entry = entry->next) {
9910 + start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block));
9911 + if((entry->mark - start) != (entry->capacity - entry->avail)) {
9912 + return 0;
9913 + }
9914 + }
9915 +
9916 + if(!APC_POOL_HAS_REDZONES(pool) ||
9917 + !APC_POOL_HAS_SIZEINFO(pool)) {
9918 + return 1;
9919 + }
9920 +
9921 + for(entry = rpool->head; entry != NULL; entry = entry->next) {
9922 + start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block));
9923 +
9924 + while(start < entry->mark) {
9925 + sizeinfo = (size_t*)start;
9926 + /* redzone starts where real data ends, in a non-word boundary
9927 + * redsize is at least 4 bytes + whatever's needed to make it
9928 + * to another word boundary.
9929 + */
9930 + redzone = start + SIZEINFO_SIZE + (*sizeinfo);
9931 + redsize = REDZONE_SIZE(*sizeinfo);
9932 +#ifdef VALGRIND_MAKE_MEM_DEFINED
9933 + VALGRIND_MAKE_MEM_DEFINED(redzone, redsize);
9934 +#endif
9935 + if(!CHECK_REDZONE(redzone, redsize))
9936 + {
9937 + /*
9938 + fprintf(stderr, "Redzone check failed for %p\n",
9939 + start + ALIGNWORD(sizeof(size_t)));*/
9940 + return 0;
9941 + }
9942 +#ifdef VALGRIND_MAKE_MEM_NOACCESS
9943 + VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize);
9944 +#endif
9945 + realsize = SIZEINFO_SIZE + *sizeinfo + redsize;
9946 + start += realsize;
9947 + }
9948 + }
9949 +
9950 + return 1;
9951 +}
9952 +/* }}} */
9953 +
9954 +/* {{{ apc_pool_free */
9955 +/*
9956 + * free does not do anything other than
9957 + * check for redzone values when free'ing
9958 + * data areas.
9959 + */
9960 +static void apc_realpool_free(apc_pool *pool, void *p)
9961 +{
9962 +}
9963 +/* }}} */
9964 +
9965 +static void apc_realpool_cleanup(apc_pool *pool)
9966 +{
9967 + pool_block *entry;
9968 + pool_block *tmp;
9969 + apc_realpool *rpool = (apc_realpool*)pool;
9970 + apc_free_t deallocate = pool->deallocate;
9971 +
9972 + assert(apc_realpool_check_integrity(rpool)!=0);
9973 +
9974 + entry = rpool->head;
9975 +
9976 + while(entry->next != NULL) {
9977 + tmp = entry->next;
9978 + deallocate(entry);
9979 + entry = tmp;
9980 + }
9981 +}
9982 +
9983 +/* {{{ apc_realpool_create */
9984 +static apc_pool* apc_realpool_create(apc_pool_type type, apc_malloc_t allocate, apc_free_t deallocate,
9985 + apc_protect_t protect, apc_unprotect_t unprotect)
9986 +{
9987 +
9988 + size_t dsize = 0;
9989 + apc_realpool *rpool;
9990 +
9991 + switch(type & APC_POOL_SIZE_MASK) {
9992 + case APC_SMALL_POOL:
9993 + dsize = 512;
9994 + break;
9995 +
9996 + case APC_LARGE_POOL:
9997 + dsize = 8192;
9998 + break;
9999 +
10000 + case APC_MEDIUM_POOL:
10001 + dsize = 4096;
10002 + break;
10003 +
10004 + default:
10005 + return NULL;
10006 + }
10007 +
10008 + rpool = (apc_realpool*)allocate(sizeof(apc_realpool) + ALIGNWORD(dsize));
10009 +
10010 + if(!rpool) {
10011 + return NULL;
10012 + }
10013 +
10014 + rpool->parent.type = type;
10015 +
10016 + rpool->parent.allocate = allocate;
10017 + rpool->parent.deallocate = deallocate;
10018 +
10019 + rpool->parent.size = sizeof(apc_realpool) + ALIGNWORD(dsize);
10020 +
10021 + rpool->parent.palloc = apc_realpool_alloc;
10022 + rpool->parent.pfree = apc_realpool_free;
10023 +
10024 + rpool->parent.protect = protect;
10025 + rpool->parent.unprotect = unprotect;
10026 +
10027 + rpool->parent.cleanup = apc_realpool_cleanup;
10028 +
10029 + rpool->dsize = dsize;
10030 + rpool->head = NULL;
10031 +
10032 + INIT_POOL_BLOCK(rpool, &(rpool->first), dsize);
10033 +
10034 + return &(rpool->parent);
10035 +}
10036 +
10037 +
10038 +/* }}} */
10039 +
10040 +/* {{{ apc_pool_init */
10041 +void apc_pool_init()
10042 +{
10043 + /* put all ye sanity checks here */
10044 + assert(sizeof(decaff) > REDZONE_SIZE(ALIGNWORD(sizeof(char))));
10045 + assert(sizeof(pool_block) == ALIGNWORD(sizeof(pool_block)));
10046 + assert((APC_POOL_SIZE_MASK & (APC_POOL_SIZEINFO | APC_POOL_REDZONES)) == 0);
10047 +}
10048 +/* }}} */
10049 +
10050 +/* {{{ apc_pstrdup */
10051 +void* apc_pstrdup(const char* s, apc_pool* pool)
10052 +{
10053 + return s != NULL ? apc_pmemcpy(s, strlen(s)+1, pool) : NULL;
10054 +}
10055 +/* }}} */
10056 +
10057 +/* {{{ apc_pmemcpy */
10058 +void* apc_pmemcpy(const void* p, size_t n, apc_pool* pool)
10059 +{
10060 + void* q;
10061 +
10062 + if (p != NULL && (q = apc_pool_alloc(pool, n)) != NULL) {
10063 + memcpy(q, p, n);
10064 + return q;
10065 + }
10066 + return NULL;
10067 +}
10068 +/* }}} */
10069 +
10070 +/*
10071 + * Local variables:
10072 + * tab-width: 4
10073 + * c-basic-offset: 4
10074 + * End:
10075 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10076 + * vim<600: expandtab sw=4 ts=4 sts=4
10077 + */
10078 diff -Naur php-5.3.1.orig/ext/apc/apc_pool.h php-5.3.1/ext/apc/apc_pool.h
10079 --- php-5.3.1.orig/ext/apc/apc_pool.h 1970-01-01 01:00:00.000000000 +0100
10080 +++ php-5.3.1/ext/apc/apc_pool.h 1970-01-01 10:13:08.000000000 +0100
10081 @@ -0,0 +1,102 @@
10082 +/*
10083 + +----------------------------------------------------------------------+
10084 + | APC |
10085 + +----------------------------------------------------------------------+
10086 + | Copyright (c) 2008 The PHP Group |
10087 + +----------------------------------------------------------------------+
10088 + | This source file is subject to version 3.01 of the PHP license, |
10089 + | that is bundled with this package in the file LICENSE, and is |
10090 + | available through the world-wide-web at the following url: |
10091 + | http://www.php.net/license/3_01.txt. |
10092 + | If you did not receive a copy of the PHP license and are unable to |
10093 + | obtain it through the world-wide-web, please send a note to |
10094 + | license@php.net so we can mail you a copy immediately. |
10095 + +----------------------------------------------------------------------+
10096 + | Authors: Gopal Vijayaraghavan <gopalv@yahoo-inc.com> |
10097 + +----------------------------------------------------------------------+
10098 +
10099 + This software was contributed to PHP by Yahoo! Inc. in 2008.
10100 +
10101 + Future revisions and derivatives of this source code must acknowledge
10102 + Yahoo! Inc. as the original contributor of this module by
10103 + leaving this note intact in the source code.
10104 +
10105 + All other licensing and usage conditions are those of the PHP Group.
10106 +
10107 + */
10108 +
10109 +/* $Id: apc_pool.h 275212 2009-02-05 08:36:26Z gopalv $ */
10110 +
10111 +#ifndef APC_POOL_H
10112 +#define APC_POOL_H
10113 +
10114 +#include "apc.h"
10115 +#include "apc_sma.h"
10116 +
10117 +typedef enum {
10118 + APC_UNPOOL = 0x0,
10119 + APC_SMALL_POOL = 0x1,
10120 + APC_MEDIUM_POOL = 0x2,
10121 + APC_LARGE_POOL = 0x3,
10122 + APC_POOL_SIZE_MASK = 0x7, /* waste a bit */
10123 + APC_POOL_REDZONES = 0x08,
10124 + APC_POOL_SIZEINFO = 0x10,
10125 + APC_POOL_OPT_MASK = 0x18
10126 +} apc_pool_type;
10127 +
10128 +#define APC_POOL_HAS_SIZEINFO(pool) ((pool->type & APC_POOL_SIZEINFO)!=0)
10129 +#define APC_POOL_HAS_REDZONES(pool) ((pool->type & APC_POOL_REDZONES)!=0)
10130 +
10131 +typedef struct _apc_pool apc_pool;
10132 +
10133 +typedef void (*apc_pcleanup_t)(apc_pool *pool);
10134 +
10135 +typedef void* (*apc_palloc_t)(apc_pool *pool, size_t size);
10136 +typedef void (*apc_pfree_t) (apc_pool *pool, void* p);
10137 +
10138 +typedef void* (*apc_protect_t) (void *p);
10139 +typedef void* (*apc_unprotect_t)(void *p);
10140 +
10141 +struct _apc_pool {
10142 + apc_pool_type type;
10143 +
10144 + apc_malloc_t allocate;
10145 + apc_free_t deallocate;
10146 +
10147 + apc_palloc_t palloc;
10148 + apc_pfree_t pfree;
10149 +
10150 + apc_protect_t protect;
10151 + apc_unprotect_t unprotect;
10152 +
10153 + apc_pcleanup_t cleanup;
10154 +
10155 + size_t size;
10156 + size_t used;
10157 +
10158 + /* apc_realpool and apc_unpool add more here */
10159 +};
10160 +
10161 +#define apc_pool_alloc(pool, size) ((pool)->palloc((pool), (size)))
10162 +#define apc_pool_free (pool, ptr) ((pool)->pfree((pool), (ptr)))
10163 +
10164 +#define apc_pool_protect (pool, ptr) (pool->protect ? \
10165 + (pool)->protect((ptr)) : (ptr))
10166 +
10167 +#define apc_pool_unprotect (pool, ptr) (pool->unprotect ? \
10168 + (pool)->unprotect((ptr)) : (ptr))
10169 +
10170 +extern void apc_pool_init();
10171 +
10172 +extern apc_pool* apc_pool_create(apc_pool_type pool_type,
10173 + apc_malloc_t allocate,
10174 + apc_free_t deallocate,
10175 + apc_protect_t protect,
10176 + apc_unprotect_t unprotect);
10177 +
10178 +extern void apc_pool_destroy(apc_pool* pool);
10179 +
10180 +extern void* apc_pmemcpy(const void* p, size_t n, apc_pool* pool);
10181 +extern void* apc_pstrdup(const char* s, apc_pool* pool);
10182 +
10183 +#endif
10184 diff -Naur php-5.3.1.orig/ext/apc/apc_pthreadmutex.c php-5.3.1/ext/apc/apc_pthreadmutex.c
10185 --- php-5.3.1.orig/ext/apc/apc_pthreadmutex.c 1970-01-01 01:00:00.000000000 +0100
10186 +++ php-5.3.1/ext/apc/apc_pthreadmutex.c 1970-01-01 10:13:08.000000000 +0100
10187 @@ -0,0 +1,111 @@
10188 +/*
10189 + +----------------------------------------------------------------------+
10190 + | APC |
10191 + +----------------------------------------------------------------------+
10192 + | Copyright (c) 2006-2008 The PHP Group |
10193 + +----------------------------------------------------------------------+
10194 + | This source file is subject to version 3.01 of the PHP license, |
10195 + | that is bundled with this package in the file LICENSE, and is |
10196 + | available through the world-wide-web at the following url: |
10197 + | http://www.php.net/license/3_01.txt |
10198 + | If you did not receive a copy of the PHP license and are unable to |
10199 + | obtain it through the world-wide-web, please send a note to |
10200 + | license@php.net so we can mail you a copy immediately. |
10201 + +----------------------------------------------------------------------+
10202 + | Authors: Brian Shire <shire@php.net> |
10203 + +----------------------------------------------------------------------+
10204 +
10205 + */
10206 +
10207 +/* $Id: apc_pthreadmutex.c 268255 2008-11-04 05:42:11Z rasmus $ */
10208 +
10209 +#include "apc_pthreadmutex.h"
10210 +
10211 +#ifdef APC_PTHREADMUTEX_LOCKS
10212 +
10213 +pthread_mutex_t *apc_pthreadmutex_create(pthread_mutex_t *lock)
10214 +{
10215 + int result;
10216 + pthread_mutexattr_t* attr;
10217 + attr = malloc(sizeof(pthread_mutexattr_t));
10218 +
10219 + result = pthread_mutexattr_init(attr);
10220 + if(result == ENOMEM) {
10221 + apc_eprint("pthread mutex error: Insufficient memory exists to create the mutex attribute object.");
10222 + } else if(result == EINVAL) {
10223 + apc_eprint("pthread mutex error: attr does not point to writeable memory.");
10224 + } else if(result == EFAULT) {
10225 + apc_eprint("pthread mutex error: attr is an invalid pointer.");
10226 + }
10227 +
10228 +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
10229 + result = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ADAPTIVE_NP);
10230 + if (result == EINVAL) {
10231 + apc_eprint("pthread_mutexattr_settype: unable to set adaptive mutexes");
10232 + }
10233 +#endif
10234 +
10235 + /* pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ERRORCHECK); */
10236 + result = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
10237 + if(result == EINVAL) {
10238 + apc_eprint("pthread mutex error: attr is not an initialized mutex attribute object, or pshared is not a valid process-shared state setting.");
10239 + } else if(result == EFAULT) {
10240 + apc_eprint("pthread mutex error: attr is an invalid pointer.");
10241 + } else if(result == ENOTSUP) {
10242 + apc_eprint("pthread mutex error: pshared was set to PTHREAD_PROCESS_SHARED.");
10243 + }
10244 +
10245 + if(pthread_mutex_init(lock, attr)) {
10246 + apc_eprint("unable to initialize pthread lock");
10247 + }
10248 + return lock;
10249 +}
10250 +
10251 +void apc_pthreadmutex_destroy(pthread_mutex_t *lock)
10252 +{
10253 + return; /* we don't actually destroy the mutex, as it would destroy it for all processes */
10254 +}
10255 +
10256 +void apc_pthreadmutex_lock(pthread_mutex_t *lock)
10257 +{
10258 + int result;
10259 + result = pthread_mutex_lock(lock);
10260 + if(result == EINVAL) {
10261 + apc_eprint("unable to obtain pthread lock (EINVAL)");
10262 + } else if(result == EDEADLK) {
10263 + apc_eprint("unable to obtain pthread lock (EDEADLK)");
10264 + }
10265 +}
10266 +
10267 +void apc_pthreadmutex_unlock(pthread_mutex_t *lock)
10268 +{
10269 + if(pthread_mutex_unlock(lock)) {
10270 + apc_eprint("unable to unlock pthread lock");
10271 + }
10272 +}
10273 +
10274 +zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock)
10275 +{
10276 + int rval;
10277 + rval = pthread_mutex_trylock(lock);
10278 + if(rval == EBUSY) { /* Lock is already held */
10279 + return 0;
10280 + } else if(rval == 0) { /* Obtained lock */
10281 + return 1;
10282 + } else { /* Other error */
10283 + apc_eprint("unable to obtain pthread trylock");
10284 + return 0;
10285 + }
10286 +}
10287 +
10288 +
10289 +#endif
10290 +
10291 +/*
10292 + * Local variables:
10293 + * tab-width: 4
10294 + * c-basic-offset: 4
10295 + * End:
10296 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10297 + * vim<600: expandtab sw=4 ts=4 sts=4
10298 + */
10299 diff -Naur php-5.3.1.orig/ext/apc/apc_pthreadmutex.h php-5.3.1/ext/apc/apc_pthreadmutex.h
10300 --- php-5.3.1.orig/ext/apc/apc_pthreadmutex.h 1970-01-01 01:00:00.000000000 +0100
10301 +++ php-5.3.1/ext/apc/apc_pthreadmutex.h 1970-01-01 10:13:08.000000000 +0100
10302 @@ -0,0 +1,48 @@
10303 +/*
10304 + +----------------------------------------------------------------------+
10305 + | APC |
10306 + +----------------------------------------------------------------------+
10307 + | Copyright (c) 2006-2008 The PHP Group |
10308 + +----------------------------------------------------------------------+
10309 + | This source file is subject to version 3.01 of the PHP license, |
10310 + | that is bundled with this package in the file LICENSE, and is |
10311 + | available through the world-wide-web at the following url: |
10312 + | http://www.php.net/license/3_01.txt |
10313 + | If you did not receive a copy of the PHP license and are unable to |
10314 + | obtain it through the world-wide-web, please send a note to |
10315 + | license@php.net so we can mail you a copy immediately. |
10316 + +----------------------------------------------------------------------+
10317 + | Authors: Brian Shire <shire@php.net> |
10318 + +----------------------------------------------------------------------+
10319 +
10320 + */
10321 +
10322 +/* $Id: apc_pthreadmutex.h 268255 2008-11-04 05:42:11Z rasmus $ */
10323 +
10324 +#ifndef APC_PTHREADMUTEX_H
10325 +#define APC_PTHREADMUTEX_H
10326 +
10327 +#include "apc.h"
10328 +
10329 +#ifdef APC_PTHREADMUTEX_LOCKS
10330 +
10331 +#include <pthread.h>
10332 +
10333 +pthread_mutex_t *apc_pthreadmutex_create();
10334 +void apc_pthreadmutex_destroy(pthread_mutex_t *lock);
10335 +void apc_pthreadmutex_lock(pthread_mutex_t *lock);
10336 +void apc_pthreadmutex_unlock(pthread_mutex_t *lock);
10337 +zend_bool apc_pthreadmutex_nonblocking_lock(pthread_mutex_t *lock);
10338 +
10339 +#endif
10340 +
10341 +#endif
10342 +
10343 +/*
10344 + * Local variables:
10345 + * tab-width: 4
10346 + * c-basic-offset: 4
10347 + * End:
10348 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10349 + * vim<600: expandtab sw=4 ts=4 sts=4
10350 + */
10351 diff -Naur php-5.3.1.orig/ext/apc/apc_rfc1867.c php-5.3.1/ext/apc/apc_rfc1867.c
10352 --- php-5.3.1.orig/ext/apc/apc_rfc1867.c 1970-01-01 01:00:00.000000000 +0100
10353 +++ php-5.3.1/ext/apc/apc_rfc1867.c 1970-01-01 10:13:08.000000000 +0100
10354 @@ -0,0 +1,214 @@
10355 +/*
10356 + +----------------------------------------------------------------------+
10357 + | APC |
10358 + +----------------------------------------------------------------------+
10359 + | Copyright (c) 2006-2008 The PHP Group |
10360 + +----------------------------------------------------------------------+
10361 + | This source file is subject to version 3.01 of the PHP license, |
10362 + | that is bundled with this package in the file LICENSE, and is |
10363 + | available through the world-wide-web at the following url: |
10364 + | http://www.php.net/license/3_01.txt |
10365 + | If you did not receive a copy of the PHP license and are unable to |
10366 + | obtain it through the world-wide-web, please send a note to |
10367 + | license@php.net so we can mail you a copy immediately. |
10368 + +----------------------------------------------------------------------+
10369 + | Authors: Rasmus Lerdorf <rasmus@php.net> |
10370 + +----------------------------------------------------------------------+
10371 +
10372 + This software was contributed to PHP by Community Connect Inc. in 2002
10373 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
10374 + Future revisions and derivatives of this source code must acknowledge
10375 + Community Connect Inc. as the original contributor of this module by
10376 + leaving this note intact in the source code.
10377 +
10378 + All other licensing and usage conditions are those of the PHP Group.
10379 +
10380 + */
10381 +
10382 +/* $Id: apc_rfc1867.c 284580 2009-07-22 06:05:31Z kalle $*/
10383 +
10384 +#include "apc.h"
10385 +#include "apc_globals.h"
10386 +#include "rfc1867.h"
10387 +
10388 +#ifdef PHP_WIN32
10389 +#include "win32/time.h"
10390 +#endif
10391 +
10392 +#ifdef MULTIPART_EVENT_FORMDATA
10393 +extern int _apc_store(char *strkey, int strkey_len, const zval *val, const uint ttl, const int exclusive TSRMLS_DC);
10394 +extern int _apc_update(char *strkey, int strkey_len, apc_cache_updater_t updater, void* data TSRMLS_DC);
10395 +
10396 +static int update_bytes_processed(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
10397 + int *bytes_ptr = (int*)data;
10398 + zval* val = entry->data.user.val;
10399 +
10400 + if(Z_TYPE_P(val) == IS_ARRAY) {
10401 + HashTable *ht = val->value.ht;
10402 + Bucket* curr = NULL;
10403 + for (curr = ht->pListHead; curr != NULL; curr = curr->pListNext) {
10404 + if(curr->nKeyLength == 8 &&
10405 + (!memcmp(curr->arKey, "current", curr->nKeyLength))) {
10406 + zval* current = ((zval**)curr->pData)[0];
10407 + current->value.lval = *bytes_ptr;
10408 + return 1;
10409 + }
10410 + }
10411 + }
10412 +
10413 + return 0;
10414 +}
10415 +
10416 +static double my_time() {
10417 + struct timeval a;
10418 + double t;
10419 + gettimeofday(&a, NULL);
10420 + t = a.tv_sec + (a.tv_usec/1000000.00);
10421 + return t;
10422 +}
10423 +
10424 +
10425 +#define RFC1867_DATA(name) \
10426 + ((request_data)->name)
10427 +
10428 +int apc_rfc1867_progress(uint event, void *event_data, void **extra TSRMLS_DC) {
10429 + apc_rfc1867_data *request_data = &APCG(rfc1867_data);
10430 + zval *track = NULL;
10431 +
10432 + switch (event) {
10433 + case MULTIPART_EVENT_START:
10434 + {
10435 + multipart_event_start *data = (multipart_event_start *) event_data;
10436 +
10437 + RFC1867_DATA(content_length) = data->content_length;
10438 + RFC1867_DATA(tracking_key)[0] = '\0';
10439 + RFC1867_DATA(name)[0] = '\0';
10440 + RFC1867_DATA(cancel_upload) = 0;
10441 + RFC1867_DATA(temp_filename) = NULL;
10442 + RFC1867_DATA(filename)[0] = '\0';
10443 + RFC1867_DATA(key_length) = 0;
10444 + RFC1867_DATA(start_time) = my_time();
10445 + RFC1867_DATA(bytes_processed) = 0;
10446 + RFC1867_DATA(rate) = 0;
10447 + RFC1867_DATA(update_freq) = (int) APCG(rfc1867_freq);
10448 +
10449 + if(RFC1867_DATA(update_freq) < 0) { // frequency is a percentage, not bytes
10450 + RFC1867_DATA(update_freq) = (int) (RFC1867_DATA(content_length) * APCG(rfc1867_freq) / 100);
10451 + }
10452 + }
10453 + break;
10454 +
10455 + case MULTIPART_EVENT_FORMDATA:
10456 + {
10457 + int prefix_len = strlen(APCG(rfc1867_prefix));
10458 + multipart_event_formdata *data = (multipart_event_formdata *) event_data;
10459 + if(data->name && !strncasecmp(data->name, APCG(rfc1867_name), strlen(APCG(rfc1867_name)))
10460 + && data->value && data->length && data->length < sizeof(RFC1867_DATA(tracking_key)) - prefix_len) {
10461 +
10462 + strlcat(RFC1867_DATA(tracking_key), APCG(rfc1867_prefix), 63);
10463 + strlcat(RFC1867_DATA(tracking_key), *data->value, 63);
10464 + RFC1867_DATA(key_length) = data->length + prefix_len;
10465 + RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
10466 + }
10467 + }
10468 + break;
10469 +
10470 + case MULTIPART_EVENT_FILE_START:
10471 + if(*RFC1867_DATA(tracking_key)) {
10472 + multipart_event_file_start *data = (multipart_event_file_start *) event_data;
10473 +
10474 + RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
10475 + strncpy(RFC1867_DATA(filename),*data->filename,127);
10476 + RFC1867_DATA(temp_filename) = NULL;
10477 + strncpy(RFC1867_DATA(name),data->name,63);
10478 + ALLOC_INIT_ZVAL(track);
10479 + array_init(track);
10480 + add_assoc_long(track, "total", RFC1867_DATA(content_length));
10481 + add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
10482 + add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
10483 + add_assoc_string(track, "name", RFC1867_DATA(name), 1);
10484 + add_assoc_long(track, "done", 0);
10485 + add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
10486 + _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), track, 3600, 0 TSRMLS_CC);
10487 + zval_ptr_dtor(&track);
10488 + }
10489 + break;
10490 +
10491 + case MULTIPART_EVENT_FILE_DATA:
10492 + if(*RFC1867_DATA(tracking_key)) {
10493 + multipart_event_file_data *data = (multipart_event_file_data *) event_data;
10494 + RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
10495 + if(RFC1867_DATA(bytes_processed) - RFC1867_DATA(prev_bytes_processed) > (uint) RFC1867_DATA(update_freq)) {
10496 + if(!_apc_update(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), update_bytes_processed, &RFC1867_DATA(bytes_processed) TSRMLS_CC)) {
10497 + ALLOC_INIT_ZVAL(track);
10498 + array_init(track);
10499 + add_assoc_long(track, "total", RFC1867_DATA(content_length));
10500 + add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
10501 + add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
10502 + add_assoc_string(track, "name", RFC1867_DATA(name), 1);
10503 + add_assoc_long(track, "done", 0);
10504 + add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
10505 + _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), track, 3600, 0 TSRMLS_CC);
10506 + zval_ptr_dtor(&track);
10507 + }
10508 + RFC1867_DATA(prev_bytes_processed) = RFC1867_DATA(bytes_processed);
10509 + }
10510 + }
10511 + break;
10512 +
10513 + case MULTIPART_EVENT_FILE_END:
10514 + if(*RFC1867_DATA(tracking_key)) {
10515 + multipart_event_file_end *data = (multipart_event_file_end *) event_data;
10516 + RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
10517 + RFC1867_DATA(cancel_upload) = data->cancel_upload;
10518 + RFC1867_DATA(temp_filename) = data->temp_filename;
10519 + ALLOC_INIT_ZVAL(track);
10520 + array_init(track);
10521 + add_assoc_long(track, "total", RFC1867_DATA(content_length));
10522 + add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
10523 + add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
10524 + add_assoc_string(track, "name", RFC1867_DATA(name), 1);
10525 + add_assoc_string(track, "temp_filename", RFC1867_DATA(temp_filename), 1);
10526 + add_assoc_long(track, "cancel_upload", RFC1867_DATA(cancel_upload));
10527 + add_assoc_long(track, "done", 0);
10528 + add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
10529 + _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), track, 3600, 0 TSRMLS_CC);
10530 + zval_ptr_dtor(&track);
10531 + }
10532 + break;
10533 +
10534 + case MULTIPART_EVENT_END:
10535 + if(*RFC1867_DATA(tracking_key)) {
10536 + double now = my_time();
10537 + multipart_event_end *data = (multipart_event_end *) event_data;
10538 + RFC1867_DATA(bytes_processed) = data->post_bytes_processed;
10539 + if(now>RFC1867_DATA(start_time)) RFC1867_DATA(rate) = 8.0*RFC1867_DATA(bytes_processed)/(now-RFC1867_DATA(start_time));
10540 + else RFC1867_DATA(rate) = 8.0*RFC1867_DATA(bytes_processed); /* Too quick */
10541 + ALLOC_INIT_ZVAL(track);
10542 + array_init(track);
10543 + add_assoc_long(track, "total", RFC1867_DATA(content_length));
10544 + add_assoc_long(track, "current", RFC1867_DATA(bytes_processed));
10545 + add_assoc_double(track, "rate", RFC1867_DATA(rate));
10546 + add_assoc_string(track, "filename", RFC1867_DATA(filename), 1);
10547 + add_assoc_string(track, "name", RFC1867_DATA(name), 1);
10548 + add_assoc_long(track, "cancel_upload", RFC1867_DATA(cancel_upload));
10549 + add_assoc_long(track, "done", 1);
10550 + add_assoc_double(track, "start_time", RFC1867_DATA(start_time));
10551 + _apc_store(RFC1867_DATA(tracking_key), RFC1867_DATA(key_length), track, APCG(rfc1867_ttl), 0 TSRMLS_CC);
10552 + zval_ptr_dtor(&track);
10553 + }
10554 + break;
10555 + }
10556 +
10557 + return SUCCESS;
10558 +}
10559 +
10560 +#endif
10561 +/*
10562 + * Local variables:
10563 + * tab-width: 4
10564 + * c-basic-offset: 4
10565 + * End:
10566 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10567 + * vim<600: expandtab sw=4 ts=4 sts=4
10568 + */
10569 diff -Naur php-5.3.1.orig/ext/apc/apc_sem.c php-5.3.1/ext/apc/apc_sem.c
10570 --- php-5.3.1.orig/ext/apc/apc_sem.c 1970-01-01 01:00:00.000000000 +0100
10571 +++ php-5.3.1/ext/apc/apc_sem.c 1970-01-01 10:13:08.000000000 +0100
10572 @@ -0,0 +1,201 @@
10573 +/*
10574 + +----------------------------------------------------------------------+
10575 + | APC |
10576 + +----------------------------------------------------------------------+
10577 + | Copyright (c) 2006-2008 The PHP Group |
10578 + +----------------------------------------------------------------------+
10579 + | This source file is subject to version 3.01 of the PHP license, |
10580 + | that is bundled with this package in the file LICENSE, and is |
10581 + | available through the world-wide-web at the following url: |
10582 + | http://www.php.net/license/3_01.txt |
10583 + | If you did not receive a copy of the PHP license and are unable to |
10584 + | obtain it through the world-wide-web, please send a note to |
10585 + | license@php.net so we can mail you a copy immediately. |
10586 + +----------------------------------------------------------------------+
10587 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
10588 + +----------------------------------------------------------------------+
10589 +
10590 + This software was contributed to PHP by Community Connect Inc. in 2002
10591 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
10592 + Future revisions and derivatives of this source code must acknowledge
10593 + Community Connect Inc. as the original contributor of this module by
10594 + leaving this note intact in the source code.
10595 +
10596 + All other licensing and usage conditions are those of the PHP Group.
10597 +
10598 + */
10599 +
10600 +/* $Id: apc_sem.c 268620 2008-11-09 02:30:49Z shire $ */
10601 +
10602 +#include "apc.h"
10603 +
10604 +#ifdef APC_SEM_LOCKS
10605 +
10606 +#include "apc_sem.h"
10607 +#include "php.h"
10608 +#include <sys/types.h>
10609 +#include <sys/ipc.h>
10610 +#include <sys/sem.h>
10611 +#include <sys/stat.h>
10612 +#include <unistd.h>
10613 +
10614 +#if HAVE_SEMUN
10615 +/* we have semun, no need to define */
10616 +#else
10617 +#undef HAVE_SEMUN
10618 +union semun {
10619 + int val; /* value for SETVAL */
10620 + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
10621 + unsigned short *array; /* array for GETALL, SETALL */
10622 + /* Linux specific part: */
10623 + struct seminfo *__buf; /* buffer for IPC_INFO */
10624 +};
10625 +#define HAVE_SEMUN 1
10626 +#endif
10627 +
10628 +#ifndef SEM_R
10629 +# define SEM_R 0444
10630 +#endif
10631 +#ifndef SEM_A
10632 +# define SEM_A 0222
10633 +#endif
10634 +
10635 +/* always use SEM_UNDO, otherwise we risk deadlock */
10636 +#define USE_SEM_UNDO
10637 +
10638 +#ifdef USE_SEM_UNDO
10639 +# define UNDO SEM_UNDO
10640 +#else
10641 +# define UNDO 0
10642 +#endif
10643 +
10644 +int apc_sem_create(const char* pathname, int proj, int initval)
10645 +{
10646 + int semid;
10647 + int perms;
10648 + union semun arg;
10649 + key_t key;
10650 +
10651 + perms = 0777;
10652 +
10653 + key = IPC_PRIVATE;
10654 + if (pathname != NULL) {
10655 + if ((key = ftok(pathname, proj)) < 0) {
10656 + apc_eprint("apc_sem_create: ftok(%s,%d) failed:", pathname, proj);
10657 + }
10658 + }
10659 +
10660 + if ((semid = semget(key, 1, IPC_CREAT | IPC_EXCL | perms)) >= 0) {
10661 + /* sempahore created for the first time, initialize now */
10662 + arg.val = initval;
10663 + if (semctl(semid, 0, SETVAL, arg) < 0) {
10664 + apc_eprint("apc_sem_create: semctl(%d,...) failed:", semid);
10665 + }
10666 + }
10667 + else if (errno == EEXIST) {
10668 + /* sempahore already exists, don't initialize */
10669 + if ((semid = semget(key, 1, perms)) < 0) {
10670 + apc_eprint("apc_sem_create: semget(%u,...) failed:", key);
10671 + }
10672 + /* insert <sleazy way to avoid race condition> here */
10673 + }
10674 + else {
10675 + apc_eprint("apc_sem_create: semget(%u,...) failed:", key);
10676 + }
10677 +
10678 + return semid;
10679 +}
10680 +
10681 +void apc_sem_destroy(int semid)
10682 +{
10683 + /* we expect this call to fail often, so we do not check */
10684 + union semun arg;
10685 + semctl(semid, 0, IPC_RMID, arg);
10686 +}
10687 +
10688 +void apc_sem_lock(int semid)
10689 +{
10690 + struct sembuf op;
10691 +
10692 + op.sem_num = 0;
10693 + op.sem_op = -1;
10694 + op.sem_flg = UNDO;
10695 +
10696 + if (semop(semid, &op, 1) < 0) {
10697 + if (errno != EINTR) {
10698 + apc_eprint("apc_sem_lock: semop(%d) failed:", semid);
10699 + }
10700 + }
10701 +}
10702 +
10703 +int apc_sem_nonblocking_lock(int semid)
10704 +{
10705 + struct sembuf op;
10706 +
10707 + op.sem_num = 0;
10708 + op.sem_op = -1;
10709 + op.sem_flg = UNDO | IPC_NOWAIT;
10710 +
10711 + if (semop(semid, &op, 1) < 0) {
10712 + if (errno == EAGAIN) {
10713 + return 0; /* Lock is already held */
10714 + } else if (errno != EINTR) {
10715 + apc_eprint("apc_sem_lock: semop(%d) failed:", semid);
10716 + }
10717 + }
10718 +
10719 + return 1; /* Lock obtained */
10720 +}
10721 +
10722 +void apc_sem_unlock(int semid)
10723 +{
10724 + struct sembuf op;
10725 +
10726 + op.sem_num = 0;
10727 + op.sem_op = 1;
10728 + op.sem_flg = UNDO;
10729 +
10730 + if (semop(semid, &op, 1) < 0) {
10731 + if (errno != EINTR) {
10732 + apc_eprint("apc_sem_unlock: semop(%d) failed:", semid);
10733 + }
10734 + }
10735 +}
10736 +
10737 +void apc_sem_wait_for_zero(int semid)
10738 +{
10739 + struct sembuf op;
10740 +
10741 + op.sem_num = 0;
10742 + op.sem_op = 0;
10743 + op.sem_flg = UNDO;
10744 +
10745 + if (semop(semid, &op, 1) < 0) {
10746 + if (errno != EINTR) {
10747 + apc_eprint("apc_sem_waitforzero: semop(%d) failed:", semid);
10748 + }
10749 + }
10750 +}
10751 +
10752 +int apc_sem_get_value(int semid)
10753 +{
10754 + union semun arg;
10755 + unsigned short val[1];
10756 +
10757 + arg.array = val;
10758 + if (semctl(semid, 0, GETALL, arg) < 0) {
10759 + apc_eprint("apc_sem_getvalue: semctl(%d,...) failed:", semid);
10760 + }
10761 + return val[0];
10762 +}
10763 +
10764 +#endif /* APC_SEM_LOCKS */
10765 +
10766 +/*
10767 + * Local variables:
10768 + * tab-width: 4
10769 + * c-basic-offset: 4
10770 + * End:
10771 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10772 + * vim<600: expandtab sw=4 ts=4 sts=4
10773 + */
10774 diff -Naur php-5.3.1.orig/ext/apc/apc_sem.h php-5.3.1/ext/apc/apc_sem.h
10775 --- php-5.3.1.orig/ext/apc/apc_sem.h 1970-01-01 01:00:00.000000000 +0100
10776 +++ php-5.3.1/ext/apc/apc_sem.h 1970-01-01 10:13:08.000000000 +0100
10777 @@ -0,0 +1,52 @@
10778 +/*
10779 + +----------------------------------------------------------------------+
10780 + | APC |
10781 + +----------------------------------------------------------------------+
10782 + | Copyright (c) 2006-2008 The PHP Group |
10783 + +----------------------------------------------------------------------+
10784 + | This source file is subject to version 3.01 of the PHP license, |
10785 + | that is bundled with this package in the file LICENSE, and is |
10786 + | available through the world-wide-web at the following url: |
10787 + | http://www.php.net/license/3_01.txt |
10788 + | If you did not receive a copy of the PHP license and are unable to |
10789 + | obtain it through the world-wide-web, please send a note to |
10790 + | license@php.net so we can mail you a copy immediately. |
10791 + +----------------------------------------------------------------------+
10792 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
10793 + +----------------------------------------------------------------------+
10794 +
10795 + This software was contributed to PHP by Community Connect Inc. in 2002
10796 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
10797 + Future revisions and derivatives of this source code must acknowledge
10798 + Community Connect Inc. as the original contributor of this module by
10799 + leaving this note intact in the source code.
10800 +
10801 + All other licensing and usage conditions are those of the PHP Group.
10802 +
10803 + */
10804 +
10805 +/* $Id: apc_sem.h 268620 2008-11-09 02:30:49Z shire $ */
10806 +
10807 +#ifndef APC_SEM_H
10808 +#define APC_SEM_H
10809 +
10810 +/* Wrapper functions for SysV sempahores */
10811 +
10812 +extern int apc_sem_create(const char* pathname, int proj, int initval);
10813 +extern void apc_sem_destroy(int semid);
10814 +extern void apc_sem_lock(int semid);
10815 +extern int apc_sem_nonblocking_lock(int semid);
10816 +extern void apc_sem_unlock(int semid);
10817 +extern void apc_sem_wait_for_zero(int semid);
10818 +extern int apc_sem_get_value(int semid);
10819 +
10820 +#endif
10821 +
10822 +/*
10823 + * Local variables:
10824 + * tab-width: 4
10825 + * c-basic-offset: 4
10826 + * End:
10827 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10828 + * vim<600: expandtab sw=4 ts=4 sts=4
10829 + */
10830 diff -Naur php-5.3.1.orig/ext/apc/apc_shm.c php-5.3.1/ext/apc/apc_shm.c
10831 --- php-5.3.1.orig/ext/apc/apc_shm.c 1970-01-01 01:00:00.000000000 +0100
10832 +++ php-5.3.1/ext/apc/apc_shm.c 1970-01-01 10:13:08.000000000 +0100
10833 @@ -0,0 +1,124 @@
10834 +/*
10835 + +----------------------------------------------------------------------+
10836 + | APC |
10837 + +----------------------------------------------------------------------+
10838 + | Copyright (c) 2006-2008 The PHP Group |
10839 + +----------------------------------------------------------------------+
10840 + | This source file is subject to version 3.01 of the PHP license, |
10841 + | that is bundled with this package in the file LICENSE, and is |
10842 + | available through the world-wide-web at the following url: |
10843 + | http://www.php.net/license/3_01.txt |
10844 + | If you did not receive a copy of the PHP license and are unable to |
10845 + | obtain it through the world-wide-web, please send a note to |
10846 + | license@php.net so we can mail you a copy immediately. |
10847 + +----------------------------------------------------------------------+
10848 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
10849 + | Rasmus Lerdorf <rasmus@php.net> |
10850 + +----------------------------------------------------------------------+
10851 +
10852 + This software was contributed to PHP by Community Connect Inc. in 2002
10853 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
10854 + Future revisions and derivatives of this source code must acknowledge
10855 + Community Connect Inc. as the original contributor of this module by
10856 + leaving this note intact in the source code.
10857 +
10858 + All other licensing and usage conditions are those of the PHP Group.
10859 +
10860 + */
10861 +
10862 +/* $Id: apc_shm.c 273457 2009-01-13 15:16:42Z gopalv $ */
10863 +
10864 +#include "apc_shm.h"
10865 +#include "apc.h"
10866 +#ifdef PHP_WIN32
10867 +/* shm functions are available in TSRM */
10868 +#include <tsrm/tsrm_win32.h>
10869 +#define key_t long
10870 +#else
10871 +#include <sys/ipc.h>
10872 +#include <sys/shm.h>
10873 +#include <sys/stat.h>
10874 +#endif
10875 +
10876 +#ifndef SHM_R
10877 +# define SHM_R 0444 /* read permission */
10878 +#endif
10879 +#ifndef SHM_A
10880 +# define SHM_A 0222 /* write permission */
10881 +#endif
10882 +
10883 +int apc_shm_create(const char* pathname, int proj, size_t size)
10884 +{
10885 + int shmid; /* shared memory id */
10886 + int oflag; /* permissions on shm */
10887 + key_t key; /* shm key returned by ftok */
10888 +
10889 + key = IPC_PRIVATE;
10890 +#ifndef PHP_WIN32
10891 + /* no ftok yet for win32 */
10892 + if (pathname != NULL) {
10893 + if ((key = ftok(pathname, proj)) < 0) {
10894 + apc_eprint("apc_shm_create: ftok failed:");
10895 + }
10896 + }
10897 +#endif
10898 +
10899 + oflag = IPC_CREAT | SHM_R | SHM_A;
10900 + if ((shmid = shmget(key, size, oflag)) < 0) {
10901 + apc_eprint("apc_shm_create: shmget(%d, %d, %d) failed: %s. It is possible that the chosen SHM segment size is higher than the operation system allows. Linux has usually a default limit of 32MB per segment.", key, size, oflag, strerror(errno));
10902 + }
10903 +
10904 + return shmid;
10905 +}
10906 +
10907 +void apc_shm_destroy(int shmid)
10908 +{
10909 + /* we expect this call to fail often, so we do not check */
10910 + shmctl(shmid, IPC_RMID, 0);
10911 +}
10912 +
10913 +apc_segment_t apc_shm_attach(int shmid)
10914 +{
10915 + apc_segment_t segment; /* shm segment */
10916 +
10917 + if ((long)(segment.shmaddr = shmat(shmid, 0, 0)) == -1) {
10918 + apc_eprint("apc_shm_attach: shmat failed:");
10919 + }
10920 +
10921 +#ifdef APC_MEMPROTECT
10922 +
10923 + if ((long)(segment.roaddr = shmat(shmid, 0, SHM_RDONLY)) == -1) {
10924 + segment.roaddr = NULL;
10925 + }
10926 +
10927 +#endif
10928 +
10929 + /*
10930 + * We set the shmid for removal immediately after attaching to it. The
10931 + * segment won't disappear until all processes have detached from it.
10932 + */
10933 + apc_shm_destroy(shmid);
10934 + return segment;
10935 +}
10936 +
10937 +void apc_shm_detach(apc_segment_t* segment)
10938 +{
10939 + if (shmdt(segment->shmaddr) < 0) {
10940 + apc_eprint("apc_shm_detach: shmdt failed:");
10941 + }
10942 +
10943 +#ifdef APC_MEMPROTECT
10944 + if (segment->roaddr && shmdt(segment->roaddr) < 0) {
10945 + apc_eprint("apc_shm_detach: shmdt failed:");
10946 + }
10947 +#endif
10948 +}
10949 +
10950 +/*
10951 + * Local variables:
10952 + * tab-width: 4
10953 + * c-basic-offset: 4
10954 + * End:
10955 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
10956 + * vim<600: expandtab sw=4 ts=4 sts=4
10957 + */
10958 diff -Naur php-5.3.1.orig/ext/apc/apc_shm.h php-5.3.1/ext/apc/apc_shm.h
10959 --- php-5.3.1.orig/ext/apc/apc_shm.h 1970-01-01 01:00:00.000000000 +0100
10960 +++ php-5.3.1/ext/apc/apc_shm.h 1970-01-01 10:13:08.000000000 +0100
10961 @@ -0,0 +1,56 @@
10962 +/*
10963 + +----------------------------------------------------------------------+
10964 + | APC |
10965 + +----------------------------------------------------------------------+
10966 + | Copyright (c) 2006-2008 The PHP Group |
10967 + +----------------------------------------------------------------------+
10968 + | This source file is subject to version 3.01 of the PHP license, |
10969 + | that is bundled with this package in the file LICENSE, and is |
10970 + | available through the world-wide-web at the following url: |
10971 + | http://www.php.net/license/3_01.txt |
10972 + | If you did not receive a copy of the PHP license and are unable to |
10973 + | obtain it through the world-wide-web, please send a note to |
10974 + | license@php.net so we can mail you a copy immediately. |
10975 + +----------------------------------------------------------------------+
10976 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
10977 + +----------------------------------------------------------------------+
10978 +
10979 + This software was contributed to PHP by Community Connect Inc. in 2002
10980 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
10981 + Future revisions and derivatives of this source code must acknowledge
10982 + Community Connect Inc. as the original contributor of this module by
10983 + leaving this note intact in the source code.
10984 +
10985 + All other licensing and usage conditions are those of the PHP Group.
10986 +
10987 + */
10988 +
10989 +/* $Id: apc_shm.h 273456 2009-01-13 14:43:58Z gopalv $ */
10990 +
10991 +#ifndef APC_SHM_H
10992 +#define APC_SHM_H
10993 +
10994 +#include <sys/types.h>
10995 +#ifdef PHP_WIN32
10996 +#include <time.h>
10997 +#endif
10998 +
10999 +#include "apc_sma.h"
11000 +
11001 +/* Wrapper functions for unix shared memory */
11002 +
11003 +extern int apc_shm_create(const char* name, int proj, size_t size);
11004 +extern void apc_shm_destroy(int shmid);
11005 +extern apc_segment_t apc_shm_attach(int shmid);
11006 +extern void apc_shm_detach(apc_segment_t* segment);
11007 +
11008 +#endif
11009 +
11010 +/*
11011 + * Local variables:
11012 + * tab-width: 4
11013 + * c-basic-offset: 4
11014 + * End:
11015 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
11016 + * vim<600: expandtab sw=4 ts=4 sts=4
11017 + */
11018 diff -Naur php-5.3.1.orig/ext/apc/apc_signal.c php-5.3.1/ext/apc/apc_signal.c
11019 --- php-5.3.1.orig/ext/apc/apc_signal.c 1970-01-01 01:00:00.000000000 +0100
11020 +++ php-5.3.1/ext/apc/apc_signal.c 1970-01-01 10:13:08.000000000 +0100
11021 @@ -0,0 +1,195 @@
11022 +/*
11023 + +----------------------------------------------------------------------+
11024 + | APC |
11025 + +----------------------------------------------------------------------+
11026 + | Copyright (c) 2006-2008 The PHP Group |
11027 + +----------------------------------------------------------------------+
11028 + | This source file is subject to version 3.01 of the PHP license, |
11029 + | that is bundled with this package in the file LICENSE, and is |
11030 + | available through the world-wide-web at the following url: |
11031 + | http://www.php.net/license/3_01.txt |
11032 + | If you did not receive a copy of the PHP license and are unable to |
11033 + | obtain it through the world-wide-web, please send a note to |
11034 + | license@php.net so we can mail you a copy immediately. |
11035 + +----------------------------------------------------------------------+
11036 + | Authors: Lucas Nealan <lucas@php.net> |
11037 + +----------------------------------------------------------------------+
11038 +
11039 + This software was contributed to PHP by Facebook Inc. in 2007.
11040 +
11041 + Future revisions and derivatives of this source code must acknowledge
11042 + Facebook Inc. as the original contributor of this module by leaving
11043 + this note intact in the source code.
11044 +
11045 + All other licensing and usage conditions are those of the PHP Group.
11046 + */
11047 +
11048 + /* $Id: apc_signal.c 268255 2008-11-04 05:42:11Z rasmus $ */
11049 +
11050 + /* Allows apc to install signal handlers and maintain signalling
11051 + to already registered handlers. Registers all signals that
11052 + coredump by default and unmaps the shared memory segment
11053 + before the coredump. Note: PHP module init is called before
11054 + signals are set by Apache and thus apc_set_signals should
11055 + be called in request init (RINIT)
11056 + */
11057 +
11058 +#include "apc.h"
11059 +
11060 +#if HAVE_SIGACTION
11061 +#include <signal.h>
11062 +#include "apc_globals.h"
11063 +#include "apc_sma.h"
11064 +#include "apc_signal.h"
11065 +
11066 +static apc_signal_info_t apc_signal_info = {0};
11067 +
11068 +static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*));
11069 +static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context);
11070 +static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context);
11071 +
11072 +/* {{{ apc_core_unmap
11073 + * Coredump signal handler, unmaps shm and calls previously installed handlers
11074 + */
11075 +static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context)
11076 +{
11077 + apc_sma_cleanup();
11078 + apc_rehandle_signal(signo, siginfo, context);
11079 +
11080 +#if !defined(WIN32) && !defined(NETWARE)
11081 + kill(getpid(), signo);
11082 +#else
11083 + raise(signo);
11084 +#endif
11085 +} /* }}} */
11086 +
11087 +/* {{{ apc_rehandle_signal
11088 + * Call the previously registered handler for a signal
11089 + */
11090 +static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context)
11091 +{
11092 + int i;
11093 + apc_signal_entry_t p_sig = {0};
11094 +
11095 + for (i=0; (i < apc_signal_info.installed && p_sig.signo != signo); i++) {
11096 + p_sig = *apc_signal_info.prev[i];
11097 + if (p_sig.signo == signo) {
11098 + if (p_sig.siginfo) {
11099 + (*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context);
11100 + } else {
11101 + (*(void (*)(int))p_sig.handler)(signo);
11102 + }
11103 + }
11104 + }
11105 +
11106 +} /* }}} */
11107 +
11108 +/* {{{ apc_register_signal
11109 + * Set a handler for a previously installed signal and save so we can
11110 + * callback when handled
11111 + */
11112 +static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*))
11113 +{
11114 + struct sigaction sa = {{0}};
11115 + apc_signal_entry_t p_sig = {0};
11116 +
11117 + if (sigaction(signo, NULL, &sa) == 0) {
11118 + if ((void*)sa.sa_handler == (void*)handler) {
11119 + return SUCCESS;
11120 + }
11121 +
11122 + if (sa.sa_handler != SIG_ERR && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) {
11123 + p_sig.signo = signo;
11124 + p_sig.siginfo = ((sa.sa_flags & SA_SIGINFO) == SA_SIGINFO);
11125 + p_sig.handler = (void *)sa.sa_handler;
11126 +
11127 + apc_signal_info.prev = (apc_signal_entry_t **)apc_erealloc(apc_signal_info.prev, (apc_signal_info.installed+1)*sizeof(apc_signal_entry_t *));
11128 + apc_signal_info.prev[apc_signal_info.installed] = (apc_signal_entry_t *)apc_emalloc(sizeof(apc_signal_entry_t));
11129 + *apc_signal_info.prev[apc_signal_info.installed++] = p_sig;
11130 + } else {
11131 + /* inherit flags and mask if already set */
11132 + sigemptyset(&sa.sa_mask);
11133 + sa.sa_flags = 0;
11134 + sa.sa_flags |= SA_SIGINFO; /* we'll use a siginfo handler */
11135 +#if defined(SA_ONESHOT)
11136 + sa.sa_flags = SA_ONESHOT;
11137 +#elif defined(SA_RESETHAND)
11138 + sa.sa_flags = SA_RESETHAND;
11139 +#endif
11140 + }
11141 + sa.sa_handler = (void*)handler;
11142 +
11143 + if (sigaction(signo, &sa, NULL) < 0) {
11144 + apc_wprint("Error installing apc signal handler for %d", signo);
11145 + }
11146 +
11147 + return SUCCESS;
11148 + }
11149 + return FAILURE;
11150 +} /* }}} */
11151 +
11152 +/* {{{ apc_set_signals
11153 + * Install our signal handlers */
11154 +void apc_set_signals(TSRMLS_D)
11155 +{
11156 + if (APCG(coredump_unmap) && apc_signal_info.installed == 0) {
11157 + /* ISO C standard signals that coredump */
11158 + apc_register_signal(SIGSEGV, apc_core_unmap);
11159 + apc_register_signal(SIGABRT, apc_core_unmap);
11160 + apc_register_signal(SIGFPE, apc_core_unmap);
11161 + apc_register_signal(SIGILL, apc_core_unmap);
11162 + /* extended signals that coredump */
11163 +#ifdef SIGBUS
11164 + apc_register_signal(SIGBUS, apc_core_unmap);
11165 +#endif
11166 +#ifdef SIGABORT
11167 + apc_register_signal(SIGABORT, apc_core_unmap);
11168 +#endif
11169 +#ifdef SIGEMT
11170 + apc_register_signal(SIGEMT, apc_core_unmap);
11171 +#endif
11172 +#ifdef SIGIOT
11173 + apc_register_signal(SIGIOT, apc_core_unmap);
11174 +#endif
11175 +#ifdef SIGQUIT
11176 + apc_register_signal(SIGQUIT, apc_core_unmap);
11177 +#endif
11178 +#ifdef SIGSYS
11179 + apc_register_signal(SIGSYS, apc_core_unmap);
11180 +#endif
11181 +#ifdef SIGTRAP
11182 + apc_register_signal(SIGTRAP, apc_core_unmap);
11183 +#endif
11184 +#ifdef SIGXCPU
11185 + apc_register_signal(SIGXCPU, apc_core_unmap);
11186 +#endif
11187 +#ifdef SIGXFSZ
11188 + apc_register_signal(SIGXFSZ, apc_core_unmap);
11189 +#endif
11190 + }
11191 +} /* }}} */
11192 +
11193 +/* {{{ apc_set_signals
11194 + * cleanup signals for shutdown */
11195 +void apc_shutdown_signals()
11196 +{
11197 + int i=0;
11198 + if (apc_signal_info.installed > 0) {
11199 + for (i=0; (i < apc_signal_info.installed); i++) {
11200 + apc_efree(apc_signal_info.prev[i]);
11201 + }
11202 + apc_efree(apc_signal_info.prev);
11203 + apc_signal_info.installed = 0; /* just in case */
11204 + }
11205 +}
11206 +
11207 +#endif /* HAVE_SIGACTION */
11208 +
11209 +/*
11210 + * Local variables:
11211 + * tab-width: 4
11212 + * c-basic-offset: 4
11213 + * End:
11214 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
11215 + * vim<600: expandtab sw=4 ts=4 sts=4
11216 + */
11217 diff -Naur php-5.3.1.orig/ext/apc/apc_signal.h php-5.3.1/ext/apc/apc_signal.h
11218 --- php-5.3.1.orig/ext/apc/apc_signal.h 1970-01-01 01:00:00.000000000 +0100
11219 +++ php-5.3.1/ext/apc/apc_signal.h 1970-01-01 10:13:08.000000000 +0100
11220 @@ -0,0 +1,51 @@
11221 +/*
11222 + +----------------------------------------------------------------------+
11223 + | APC |
11224 + +----------------------------------------------------------------------+
11225 + | Copyright (c) 2006-2008 The PHP Group |
11226 + +----------------------------------------------------------------------+
11227 + | This source file is subject to version 3.01 of the PHP license, |
11228 + | that is bundled with this package in the file LICENSE, and is |
11229 + | available through the world-wide-web at the following url: |
11230 + | http://www.php.net/license/3_01.txt |
11231 + | If you did not receive a copy of the PHP license and are unable to |
11232 + | obtain it through the world-wide-web, please send a note to |
11233 + | license@php.net so we can mail you a copy immediately. |
11234 + +----------------------------------------------------------------------+
11235 + | Authors: Lucas Nealan <lucas@php.net> |
11236 + +----------------------------------------------------------------------+
11237 +
11238 + */
11239 +
11240 +/* $Id: apc_signal.h 268255 2008-11-04 05:42:11Z rasmus $ */
11241 +
11242 +#ifndef APC_SIGNAL_H
11243 +#define APC_SIGNAL_H
11244 +
11245 +#include "apc.h"
11246 +#include "apc_php.h"
11247 +
11248 +typedef struct apc_signal_entry_t {
11249 + int signo; /* signal number */
11250 + int siginfo; /* siginfo style handler calling */
11251 + void* handler; /* signal handler */
11252 +} apc_signal_entry_t;
11253 +
11254 +typedef struct apc_signal_info_t {
11255 + int installed; /* How many signals we've installed handles for */
11256 + apc_signal_entry_t **prev; /* Previous signal handlers */
11257 +} apc_signal_info_t;
11258 +
11259 +void apc_set_signals(TSRMLS_D);
11260 +void apc_shutdown_signals();
11261 +
11262 +#endif
11263 +
11264 +/*
11265 + * Local variables:
11266 + * tab-width: 4
11267 + * c-basic-offset: 4
11268 + * End:
11269 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
11270 + * vim<600: expandtab sw=4 ts=4 sts=4
11271 + */
11272 diff -Naur php-5.3.1.orig/ext/apc/apc_sma.c php-5.3.1/ext/apc/apc_sma.c
11273 --- php-5.3.1.orig/ext/apc/apc_sma.c 1970-01-01 01:00:00.000000000 +0100
11274 +++ php-5.3.1/ext/apc/apc_sma.c 1970-01-01 10:13:08.000000000 +0100
11275 @@ -0,0 +1,738 @@
11276 +/*
11277 + +----------------------------------------------------------------------+
11278 + | APC |
11279 + +----------------------------------------------------------------------+
11280 + | Copyright (c) 2006-2008 The PHP Group |
11281 + +----------------------------------------------------------------------+
11282 + | This source file is subject to version 3.01 of the PHP license, |
11283 + | that is bundled with this package in the file LICENSE, and is |
11284 + | available through the world-wide-web at the following url: |
11285 + | http://www.php.net/license/3_01.txt |
11286 + | If you did not receive a copy of the PHP license and are unable to |
11287 + | obtain it through the world-wide-web, please send a note to |
11288 + | license@php.net so we can mail you a copy immediately. |
11289 + +----------------------------------------------------------------------+
11290 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
11291 + | Rasmus Lerdorf <rasmus@php.net> |
11292 + +----------------------------------------------------------------------+
11293 +
11294 + This software was contributed to PHP by Community Connect Inc. in 2002
11295 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
11296 + Future revisions and derivatives of this source code must acknowledge
11297 + Community Connect Inc. as the original contributor of this module by
11298 + leaving this note intact in the source code.
11299 +
11300 + All other licensing and usage conditions are those of the PHP Group.
11301 +
11302 + */
11303 +
11304 +/* $Id: apc_sma.c 284580 2009-07-22 06:05:31Z kalle $ */
11305 +
11306 +#include "apc_sma.h"
11307 +#include "apc.h"
11308 +#include "apc_globals.h"
11309 +#include "apc_lock.h"
11310 +#include "apc_shm.h"
11311 +#include "apc_cache.h"
11312 +
11313 +#include <limits.h>
11314 +#include "apc_mmap.h"
11315 +
11316 +#ifdef HAVE_VALGRIND_MEMCHECK_H
11317 +#include <valgrind/memcheck.h>
11318 +#endif
11319 +
11320 +enum { DEFAULT_NUMSEG=1, DEFAULT_SEGSIZE=30*1024*1024 };
11321 +
11322 +static int sma_initialized = 0; /* true if the sma has been initialized */
11323 +static uint sma_numseg; /* number of shm segments to allow */
11324 +static size_t sma_segsize; /* size of each shm segment */
11325 +static apc_segment_t* sma_segments; /* array of shm segments */
11326 +static int sma_lastseg = 0; /* index of MRU segment */
11327 +
11328 +typedef struct sma_header_t sma_header_t;
11329 +struct sma_header_t {
11330 + apc_lck_t sma_lock; /* segment lock, MUST BE ALIGNED for futex locks */
11331 + size_t segsize; /* size of entire segment */
11332 + size_t avail; /* bytes available (not necessarily contiguous) */
11333 +#if ALLOC_DISTRIBUTION
11334 + size_t adist[30];
11335 +#endif
11336 +};
11337 +
11338 +#define SMA_HDR(i) ((sma_header_t*)((sma_segments[i]).shmaddr))
11339 +#define SMA_ADDR(i) ((char*)(SMA_HDR(i)))
11340 +#define SMA_RO(i) ((char*)(sma_segments[i]).roaddr)
11341 +#define SMA_LCK(i) ((SMA_HDR(i))->sma_lock)
11342 +
11343 +
11344 +/* do not enable for threaded http servers */
11345 +/* #define __APC_SMA_DEBUG__ 1 */
11346 +
11347 +#ifdef __APC_SMA_DEBUG__
11348 +/* global counter for identifying blocks
11349 + * Technically it is possible to do the same
11350 + * using offsets, but double allocations of the
11351 + * same offset can happen. */
11352 +static volatile size_t block_id = 0;
11353 +#endif
11354 +
11355 +#define APC_SMA_CANARIES 1
11356 +
11357 +typedef struct block_t block_t;
11358 +struct block_t {
11359 + size_t size; /* size of this block */
11360 + size_t prev_size; /* size of sequentially previous block, 0 if prev is allocated */
11361 + size_t fnext; /* offset in segment of next free block */
11362 + size_t fprev; /* offset in segment of prev free block */
11363 +#ifdef APC_SMA_CANARIES
11364 + size_t canary; /* canary to check for memory overwrites */
11365 +#endif
11366 +#ifdef __APC_SMA_DEBUG__
11367 + size_t id; /* identifier for the memory block */
11368 +#endif
11369 +};
11370 +
11371 +/* The macros BLOCKAT and OFFSET are used for convenience throughout this
11372 + * module. Both assume the presence of a variable shmaddr that points to the
11373 + * beginning of the shared memory segment in question. */
11374 +
11375 +#define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset))
11376 +#define OFFSET(block) ((size_t)(((char*)block) - (char*)shmaddr))
11377 +
11378 +/* macros for getting the next or previous sequential block */
11379 +#define NEXT_SBLOCK(block) ((block_t*)((char*)block + block->size))
11380 +#define PREV_SBLOCK(block) (block->prev_size ? ((block_t*)((char*)block - block->prev_size)) : NULL)
11381 +
11382 +/* Canary macros for setting, checking and resetting memory canaries */
11383 +#ifdef APC_SMA_CANARIES
11384 + #define SET_CANARY(v) (v)->canary = 0x42424242
11385 + #define CHECK_CANARY(v) assert((v)->canary == 0x42424242)
11386 + #define RESET_CANARY(v) (v)->canary = -42
11387 +#else
11388 + #define SET_CANARY(v)
11389 + #define CHECK_CANARY(v)
11390 + #define RESET_CANARY(v)
11391 +#endif
11392 +
11393 +
11394 +/* {{{ MINBLOCKSIZE */
11395 +#define MINBLOCKSIZE (ALIGNWORD(1) + ALIGNWORD(sizeof(block_t)))
11396 +/* }}} */
11397 +
11398 +#if 0
11399 +/* {{{ sma_debug_state(apc_sma_segment_t *segment, int canary_check, int verbose)
11400 + * useful for debuging state of memory blocks and free list, and sanity checking
11401 + */
11402 +static void sma_debug_state(void* shmaddr, int canary_check, int verbose) {
11403 + sma_header_t *header = (sma_header_t*)shmaddr;
11404 + block_t *cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11405 + block_t *prv = NULL;
11406 + size_t avail;
11407 +
11408 + /* Verify free list */
11409 + if (verbose) apc_wprint("Free List: ");
11410 + while(1) {
11411 + if (verbose) apc_wprint(" 0x%x[%d] (s%d)", cur, OFFSET(cur), cur->size);
11412 + if (canary_check) CHECK_CANARY(cur);
11413 + if (!cur->fnext) break;
11414 + cur = BLOCKAT(cur->fnext);
11415 + avail += cur->size;
11416 + if (prv == cur) {
11417 + apc_wprint("Circular list detected!");
11418 + assert(0);
11419 + }
11420 + if (prv && cur->fprev != OFFSET(prv)) {
11421 + apc_wprint("Previous pointer does not point to previous!");
11422 + assert(0);
11423 + }
11424 + prv = cur;
11425 + }
11426 + assert(avail == header->avail);
11427 +
11428 + /* Verify each block */
11429 + if (verbose) apc_wprint("Block List: ");
11430 + cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11431 + while(1) {
11432 + if(!cur->fnext) {
11433 + if (verbose) apc_wprint(" 0x%x[%d] (s%d) (u)", cur, OFFSET(cur), cur->size);
11434 + } else {
11435 + if (verbose) apc_wprint(" 0x%x[%d] (s%d) (f)", cur, OFFSET(cur), cur->size);
11436 + }
11437 + if (canary_check) CHECK_CANARY(cur);
11438 + if (!cur->size && !cur->fnext) break;
11439 + if (!cur->size) {
11440 + cur = BLOCKAT(OFFSET(cur) + ALIGNWORD(sizeof(block_t)));
11441 + } else {
11442 + cur = NEXT_SBLOCK(cur);
11443 + }
11444 + if (prv == cur) {
11445 + apc_wprint("Circular list detected!");
11446 + assert(0);
11447 + }
11448 + prv = cur;
11449 + }
11450 +}
11451 +/* }}} */
11452 +#endif
11453 +
11454 +/* {{{ sma_allocate: tries to allocate at least size bytes in a segment */
11455 +static size_t sma_allocate(sma_header_t* header, size_t size, size_t fragment, size_t *allocated)
11456 +{
11457 + void* shmaddr; /* header of shared memory segment */
11458 + block_t* prv; /* block prior to working block */
11459 + block_t* cur; /* working block in list */
11460 + block_t* prvnextfit; /* block before next fit */
11461 + size_t realsize; /* actual size of block needed, including header */
11462 + const size_t block_size = ALIGNWORD(sizeof(struct block_t));
11463 +
11464 + realsize = ALIGNWORD(size + block_size);
11465 +
11466 + /*
11467 + * First, insure that the segment contains at least realsize free bytes,
11468 + * even if they are not contiguous.
11469 + */
11470 + shmaddr = header;
11471 +
11472 + if (header->avail < realsize) {
11473 + return -1;
11474 + }
11475 +
11476 + prvnextfit = 0; /* initially null (no fit) */
11477 + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11478 + CHECK_CANARY(prv);
11479 +
11480 + while (prv->fnext != 0) {
11481 + cur = BLOCKAT(prv->fnext);
11482 +#ifdef __APC_SMA_DEBUG__
11483 + CHECK_CANARY(cur);
11484 +#endif
11485 + /* If it can fit realsize bytes in cur block, stop searching */
11486 + if (cur->size >= realsize) {
11487 + prvnextfit = prv;
11488 + break;
11489 + }
11490 + prv = cur;
11491 + }
11492 +
11493 + if (prvnextfit == 0) {
11494 + return -1;
11495 + }
11496 +
11497 + prv = prvnextfit;
11498 + cur = BLOCKAT(prv->fnext);
11499 +
11500 + CHECK_CANARY(prv);
11501 + CHECK_CANARY(cur);
11502 +
11503 + if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE + fragment)))) {
11504 + /* cur is big enough for realsize, but too small to split - unlink it */
11505 + *(allocated) = cur->size - block_size;
11506 + prv->fnext = cur->fnext;
11507 + BLOCKAT(cur->fnext)->fprev = OFFSET(prv);
11508 + NEXT_SBLOCK(cur)->prev_size = 0; /* block is alloc'd */
11509 + } else {
11510 + /* nextfit is too big; split it into two smaller blocks */
11511 + block_t* nxt; /* the new block (chopped part of cur) */
11512 + size_t oldsize; /* size of cur before split */
11513 +
11514 + oldsize = cur->size;
11515 + cur->size = realsize;
11516 + *(allocated) = cur->size - block_size;
11517 + nxt = NEXT_SBLOCK(cur);
11518 + nxt->prev_size = 0; /* block is alloc'd */
11519 + nxt->size = oldsize - realsize; /* and fix the size */
11520 + NEXT_SBLOCK(nxt)->prev_size = nxt->size; /* adjust size */
11521 + SET_CANARY(nxt);
11522 +
11523 + /* replace cur with next in free list */
11524 + nxt->fnext = cur->fnext;
11525 + nxt->fprev = cur->fprev;
11526 + BLOCKAT(nxt->fnext)->fprev = OFFSET(nxt);
11527 + BLOCKAT(nxt->fprev)->fnext = OFFSET(nxt);
11528 +#ifdef __APC_SMA_DEBUG__
11529 + nxt->id = -1;
11530 +#endif
11531 + }
11532 +
11533 + cur->fnext = 0;
11534 +
11535 + /* update the block header */
11536 + header->avail -= cur->size;
11537 +#if ALLOC_DISTRIBUTION
11538 + header->adist[(int)(log(size)/log(2))]++;
11539 +#endif
11540 +
11541 + SET_CANARY(cur);
11542 +#ifdef __APC_SMA_DEBUG__
11543 + cur->id = ++block_id;
11544 + fprintf(stderr, "allocate(realsize=%d,size=%d,id=%d)\n", (int)(size), (int)(cur->size), cur->id);
11545 +#endif
11546 +
11547 + return OFFSET(cur) + block_size;
11548 +}
11549 +/* }}} */
11550 +
11551 +/* {{{ sma_deallocate: deallocates the block at the given offset */
11552 +static size_t sma_deallocate(void* shmaddr, size_t offset)
11553 +{
11554 + sma_header_t* header; /* header of shared memory segment */
11555 + block_t* cur; /* the new block to insert */
11556 + block_t* prv; /* the block before cur */
11557 + block_t* nxt; /* the block after cur */
11558 + size_t size; /* size of deallocated block */
11559 +
11560 + offset -= ALIGNWORD(sizeof(struct block_t));
11561 + assert(offset >= 0);
11562 +
11563 + /* find position of new block in free list */
11564 + cur = BLOCKAT(offset);
11565 +
11566 + /* update the block header */
11567 + header = (sma_header_t*) shmaddr;
11568 + header->avail += cur->size;
11569 + size = cur->size;
11570 +
11571 + if (cur->prev_size != 0) {
11572 + /* remove prv from list */
11573 + prv = PREV_SBLOCK(cur);
11574 + BLOCKAT(prv->fnext)->fprev = prv->fprev;
11575 + BLOCKAT(prv->fprev)->fnext = prv->fnext;
11576 + /* cur and prv share an edge, combine them */
11577 + prv->size +=cur->size;
11578 + RESET_CANARY(cur);
11579 + cur = prv;
11580 + }
11581 +
11582 + nxt = NEXT_SBLOCK(cur);
11583 + if (nxt->fnext != 0) {
11584 + assert(NEXT_SBLOCK(NEXT_SBLOCK(cur))->prev_size == nxt->size);
11585 + /* cur and nxt shared an edge, combine them */
11586 + BLOCKAT(nxt->fnext)->fprev = nxt->fprev;
11587 + BLOCKAT(nxt->fprev)->fnext = nxt->fnext;
11588 + cur->size += nxt->size;
11589 +#ifdef __APC_SMA_DEBUG__
11590 + CHECK_CANARY(nxt);
11591 + nxt->id = -1; /* assert this or set it ? */
11592 +#endif
11593 + RESET_CANARY(nxt);
11594 + }
11595 +
11596 + NEXT_SBLOCK(cur)->prev_size = cur->size;
11597 +
11598 + /* insert new block after prv */
11599 + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11600 + cur->fnext = prv->fnext;
11601 + prv->fnext = OFFSET(cur);
11602 + cur->fprev = OFFSET(prv);
11603 + BLOCKAT(cur->fnext)->fprev = OFFSET(cur);
11604 +
11605 + return size;
11606 +}
11607 +/* }}} */
11608 +
11609 +/* {{{ apc_sma_init */
11610 +
11611 +void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask)
11612 +{
11613 + uint i;
11614 +
11615 + if (sma_initialized) {
11616 + return;
11617 + }
11618 + sma_initialized = 1;
11619 +
11620 +#if APC_MMAP
11621 + /*
11622 + * I don't think multiple anonymous mmaps makes any sense
11623 + * so force sma_numseg to 1 in this case
11624 + */
11625 + if(!mmap_file_mask ||
11626 + (mmap_file_mask && !strlen(mmap_file_mask)) ||
11627 + (mmap_file_mask && !strcmp(mmap_file_mask, "/dev/zero"))) {
11628 + sma_numseg = 1;
11629 + } else {
11630 + sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG;
11631 + }
11632 +#else
11633 + sma_numseg = numseg > 0 ? numseg : DEFAULT_NUMSEG;
11634 +#endif
11635 +
11636 + sma_segsize = segsize > 0 ? segsize : DEFAULT_SEGSIZE;
11637 +
11638 + sma_segments = (apc_segment_t*) apc_emalloc(sma_numseg*sizeof(apc_segment_t));
11639 +
11640 + for (i = 0; i < sma_numseg; i++) {
11641 + sma_header_t* header;
11642 + block_t* block;
11643 + void* shmaddr;
11644 +
11645 +#if APC_MMAP
11646 + sma_segments[i] = apc_mmap(mmap_file_mask, sma_segsize);
11647 + if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6);
11648 +#else
11649 + sma_segments[i] = apc_shm_attach(apc_shm_create(NULL, i, sma_segsize));
11650 +#endif
11651 +
11652 + sma_segments[i].size = sma_segsize;
11653 +
11654 + shmaddr = sma_segments[i].shmaddr;
11655 +
11656 + header = (sma_header_t*) shmaddr;
11657 + apc_lck_create(NULL, 0, 1, header->sma_lock);
11658 + header->segsize = sma_segsize;
11659 + header->avail = sma_segsize - ALIGNWORD(sizeof(sma_header_t)) - ALIGNWORD(sizeof(block_t)) - ALIGNWORD(sizeof(block_t));
11660 +#if ALLOC_DISTRIBUTION
11661 + {
11662 + int j;
11663 + for(j=0; j<30; j++) header->adist[j] = 0;
11664 + }
11665 +#endif
11666 + block = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11667 + block->size = 0;
11668 + block->fnext = ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t));
11669 + block->fprev = 0;
11670 + block->prev_size = 0;
11671 + SET_CANARY(block);
11672 +#ifdef __APC_SMA_DEBUG__
11673 + block->id = -1;
11674 +#endif
11675 + block = BLOCKAT(block->fnext);
11676 + block->size = header->avail - ALIGNWORD(sizeof(block_t));
11677 + block->fnext = OFFSET(block) + block->size;
11678 + block->fprev = ALIGNWORD(sizeof(sma_header_t));
11679 + block->prev_size = 0;
11680 + SET_CANARY(block);
11681 +#ifdef __APC_SMA_DEBUG__
11682 + block->id = -1;
11683 +#endif
11684 + block = BLOCKAT(block->fnext);
11685 + block->size = 0;
11686 + block->fnext = 0;
11687 + block->fprev = ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t));
11688 + block->prev_size = header->avail - ALIGNWORD(sizeof(block_t));
11689 + SET_CANARY(block);
11690 +#ifdef __APC_SMA_DEBUG__
11691 + block->id = -1;
11692 +#endif
11693 + }
11694 +}
11695 +/* }}} */
11696 +
11697 +/* {{{ apc_sma_cleanup */
11698 +void apc_sma_cleanup()
11699 +{
11700 + uint i;
11701 +
11702 + assert(sma_initialized);
11703 +
11704 + for (i = 0; i < sma_numseg; i++) {
11705 + apc_lck_destroy(SMA_LCK(i));
11706 +#if APC_MMAP
11707 + apc_unmap(&sma_segments[i]);
11708 +#else
11709 + apc_shm_detach(&sma_segments[i]);
11710 +#endif
11711 + }
11712 + sma_initialized = 0;
11713 + apc_efree(sma_segments);
11714 +}
11715 +/* }}} */
11716 +
11717 +/* {{{ apc_sma_malloc_ex */
11718 +void* apc_sma_malloc_ex(size_t n, size_t fragment, size_t* allocated)
11719 +{
11720 + size_t off;
11721 + uint i;
11722 +
11723 + TSRMLS_FETCH();
11724 + assert(sma_initialized);
11725 + LOCK(SMA_LCK(sma_lastseg));
11726 +
11727 + off = sma_allocate(SMA_HDR(sma_lastseg), n, fragment, allocated);
11728 +
11729 + if(off == -1 && APCG(current_cache)) {
11730 + /* retry failed allocation after we expunge */
11731 + UNLOCK(SMA_LCK(sma_lastseg));
11732 + APCG(current_cache)->expunge_cb(APCG(current_cache), n);
11733 + LOCK(SMA_LCK(sma_lastseg));
11734 + off = sma_allocate(SMA_HDR(sma_lastseg), n, fragment, allocated);
11735 + }
11736 +
11737 + if (off != -1) {
11738 + void* p = (void *)(SMA_ADDR(sma_lastseg) + off);
11739 + UNLOCK(SMA_LCK(sma_lastseg));
11740 +#ifdef VALGRIND_MALLOCLIKE_BLOCK
11741 + VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0);
11742 +#endif
11743 + return p;
11744 + }
11745 +
11746 + UNLOCK(SMA_LCK(sma_lastseg));
11747 +
11748 + for (i = 0; i < sma_numseg; i++) {
11749 + if (i == sma_lastseg) {
11750 + continue;
11751 + }
11752 + LOCK(SMA_LCK(i));
11753 + off = sma_allocate(SMA_HDR(i), n, fragment, allocated);
11754 + if(off == -1 && APCG(current_cache)) {
11755 + /* retry failed allocation after we expunge */
11756 + UNLOCK(SMA_LCK(i));
11757 + APCG(current_cache)->expunge_cb(APCG(current_cache), n);
11758 + LOCK(SMA_LCK(i));
11759 + off = sma_allocate(SMA_HDR(i), n, fragment, allocated);
11760 + }
11761 + if (off != -1) {
11762 + void* p = (void *)(SMA_ADDR(i) + off);
11763 + UNLOCK(SMA_LCK(i));
11764 + sma_lastseg = i;
11765 +#ifdef VALGRIND_MALLOCLIKE_BLOCK
11766 + VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0);
11767 +#endif
11768 + return p;
11769 + }
11770 + UNLOCK(SMA_LCK(i));
11771 + }
11772 +
11773 + return NULL;
11774 +}
11775 +/* }}} */
11776 +
11777 +/* {{{ apc_sma_malloc */
11778 +void* apc_sma_malloc(size_t n)
11779 +{
11780 + size_t allocated;
11781 + void *p = apc_sma_malloc_ex(n, MINBLOCKSIZE, &allocated);
11782 +
11783 + return p;
11784 +}
11785 +/* }}} */
11786 +
11787 +/* {{{ apc_sma_realloc */
11788 +void* apc_sma_realloc(void *p, size_t n)
11789 +{
11790 + apc_sma_free(p);
11791 + return apc_sma_malloc(n);
11792 +}
11793 +/* }}} */
11794 +
11795 +/* {{{ apc_sma_strdup */
11796 +char* apc_sma_strdup(const char* s)
11797 +{
11798 + void* q;
11799 + int len;
11800 +
11801 + if(!s) return NULL;
11802 +
11803 + len = strlen(s)+1;
11804 + q = apc_sma_malloc(len);
11805 + if(!q) return NULL;
11806 + memcpy(q, s, len);
11807 + return q;
11808 +}
11809 +/* }}} */
11810 +
11811 +/* {{{ apc_sma_free */
11812 +void apc_sma_free(void* p)
11813 +{
11814 + uint i;
11815 + size_t offset;
11816 + size_t d_size;
11817 +
11818 + if (p == NULL) {
11819 + return;
11820 + }
11821 +
11822 + assert(sma_initialized);
11823 +
11824 +
11825 + for (i = 0; i < sma_numseg; i++) {
11826 + offset = (size_t)((char *)p - SMA_ADDR(i));
11827 + if (p >= (void*)SMA_ADDR(i) && offset < sma_segsize) {
11828 + LOCK(SMA_LCK(i));
11829 + d_size = sma_deallocate(SMA_HDR(i), offset);
11830 + UNLOCK(SMA_LCK(i));
11831 +#ifdef VALGRIND_FREELIKE_BLOCK
11832 + VALGRIND_FREELIKE_BLOCK(p, 0);
11833 +#endif
11834 + return;
11835 + }
11836 + }
11837 +
11838 + apc_eprint("apc_sma_free: could not locate address %p", p);
11839 +}
11840 +/* }}} */
11841 +
11842 +#ifdef APC_MEMPROTECT
11843 +/* {{{ */
11844 +void* apc_sma_protect(void *p)
11845 +{
11846 + int i;
11847 + size_t offset;
11848 +
11849 + if (p == NULL) {
11850 + return NULL;
11851 + }
11852 +
11853 + if(SMA_RO(sma_lastseg) == NULL) return p;
11854 +
11855 + offset = (size_t)((char *)p - SMA_ADDR(sma_lastseg));
11856 +
11857 + if(p >= (void*)SMA_ADDR(sma_lastseg) && offset < sma_segsize) {
11858 + return SMA_RO(sma_lastseg) + offset;
11859 + }
11860 +
11861 + for (i = 0; i < sma_numseg; i++) {
11862 + offset = (size_t)((char *)p - SMA_ADDR(i));
11863 + if (p >= (void*)SMA_ADDR(i) && offset < sma_segsize) {
11864 + return SMA_RO(i) + offset;
11865 + }
11866 + }
11867 +
11868 + return NULL;
11869 +}
11870 +/* }}} */
11871 +
11872 +/* {{{ */
11873 +void* apc_sma_unprotect(void *p)
11874 +{
11875 + int i;
11876 + size_t offset;
11877 +
11878 + if (p == NULL) {
11879 + return NULL;
11880 + }
11881 +
11882 + if(SMA_RO(sma_lastseg) == NULL) return p;
11883 +
11884 + offset = (size_t)((char *)p - SMA_RO(sma_lastseg));
11885 +
11886 + if(p >= (void*)SMA_RO(sma_lastseg) && offset < sma_segsize) {
11887 + return SMA_ADDR(sma_lastseg) + offset;
11888 + }
11889 +
11890 + for (i = 0; i < sma_numseg; i++) {
11891 + offset = (size_t)((char *)p - SMA_RO(i));
11892 + if (p >= (void*)SMA_RO(i) && offset < sma_segsize) {
11893 + return SMA_ADDR(i) + offset;
11894 + }
11895 + }
11896 +
11897 + return NULL;
11898 +}
11899 +/* }}} */
11900 +#else
11901 +/* {{{ */
11902 +void* apc_sma_protect(void *p) { return p; }
11903 +void* apc_sma_unprotect(void *p) { return p; }
11904 +/* }}} */
11905 +#endif
11906 +
11907 +/* {{{ apc_sma_info */
11908 +apc_sma_info_t* apc_sma_info(zend_bool limited)
11909 +{
11910 + apc_sma_info_t* info;
11911 + apc_sma_link_t** link;
11912 + uint i;
11913 + char* shmaddr;
11914 + block_t* prv;
11915 +
11916 + if (!sma_initialized) {
11917 + return NULL;
11918 + }
11919 +
11920 + info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t));
11921 + info->num_seg = sma_numseg;
11922 + info->seg_size = sma_segsize - (ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)) + ALIGNWORD(sizeof(block_t)));
11923 +
11924 + info->list = apc_emalloc(info->num_seg * sizeof(apc_sma_link_t*));
11925 + for (i = 0; i < sma_numseg; i++) {
11926 + info->list[i] = NULL;
11927 + }
11928 +
11929 + if(limited) return info;
11930 +
11931 + /* For each segment */
11932 + for (i = 0; i < sma_numseg; i++) {
11933 + RDLOCK(SMA_LCK(i));
11934 + shmaddr = SMA_ADDR(i);
11935 + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
11936 +
11937 + link = &info->list[i];
11938 +
11939 + /* For each block in this segment */
11940 + while (BLOCKAT(prv->fnext)->fnext != 0) {
11941 + block_t* cur = BLOCKAT(prv->fnext);
11942 +#ifdef __APC_SMA_DEBUG__
11943 + CHECK_CANARY(cur);
11944 +#endif
11945 +
11946 + *link = apc_emalloc(sizeof(apc_sma_link_t));
11947 + (*link)->size = cur->size;
11948 + (*link)->offset = prv->fnext;
11949 + (*link)->next = NULL;
11950 + link = &(*link)->next;
11951 +
11952 + prv = cur;
11953 +
11954 +#if ALLOC_DISTRIBUTION
11955 + sma_header_t* header = (sma_header_t*) segment->shmaddr;
11956 + memcpy(info->seginfo[i].adist, header->adist, sizeof(size_t) * 30);
11957 +#endif
11958 +
11959 + }
11960 + UNLOCK(SMA_LCK(i));
11961 + }
11962 +
11963 + return info;
11964 +}
11965 +/* }}} */
11966 +
11967 +/* {{{ apc_sma_free_info */
11968 +void apc_sma_free_info(apc_sma_info_t* info)
11969 +{
11970 + int i;
11971 +
11972 + for (i = 0; i < info->num_seg; i++) {
11973 + apc_sma_link_t* p = info->list[i];
11974 + while (p) {
11975 + apc_sma_link_t* q = p;
11976 + p = p->next;
11977 + apc_efree(q);
11978 + }
11979 + }
11980 + apc_efree(info->list);
11981 + apc_efree(info);
11982 +}
11983 +/* }}} */
11984 +
11985 +/* {{{ apc_sma_get_avail_mem */
11986 +size_t apc_sma_get_avail_mem()
11987 +{
11988 + size_t avail_mem = 0;
11989 + uint i;
11990 +
11991 + for (i = 0; i < sma_numseg; i++) {
11992 + sma_header_t* header = SMA_HDR(i);
11993 + avail_mem += header->avail;
11994 + }
11995 + return avail_mem;
11996 +}
11997 +/* }}} */
11998 +
11999 +#if ALLOC_DISTRIBUTION
12000 +size_t *apc_sma_get_alloc_distribution(void) {
12001 + sma_header_t* header = (sma_header_t*) segment->sma_shmaddr;
12002 + return header->adist;
12003 +}
12004 +#endif
12005 +
12006 +/*
12007 + * Local variables:
12008 + * tab-width: 4
12009 + * c-basic-offset: 4
12010 + * End:
12011 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12012 + * vim<600: expandtab sw=4 ts=4 sts=4
12013 + */
12014 diff -Naur php-5.3.1.orig/ext/apc/apc_sma.h php-5.3.1/ext/apc/apc_sma.h
12015 --- php-5.3.1.orig/ext/apc/apc_sma.h 1970-01-01 01:00:00.000000000 +0100
12016 +++ php-5.3.1/ext/apc/apc_sma.h 1970-01-01 10:13:08.000000000 +0100
12017 @@ -0,0 +1,102 @@
12018 +/*
12019 + +----------------------------------------------------------------------+
12020 + | APC |
12021 + +----------------------------------------------------------------------+
12022 + | Copyright (c) 2006-2008 The PHP Group |
12023 + +----------------------------------------------------------------------+
12024 + | This source file is subject to version 3.01 of the PHP license, |
12025 + | that is bundled with this package in the file LICENSE, and is |
12026 + | available through the world-wide-web at the following url: |
12027 + | http://www.php.net/license/3_01.txt |
12028 + | If you did not receive a copy of the PHP license and are unable to |
12029 + | obtain it through the world-wide-web, please send a note to |
12030 + | license@php.net so we can mail you a copy immediately. |
12031 + +----------------------------------------------------------------------+
12032 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
12033 + +----------------------------------------------------------------------+
12034 +
12035 + This software was contributed to PHP by Community Connect Inc. in 2002
12036 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
12037 + Future revisions and derivatives of this source code must acknowledge
12038 + Community Connect Inc. as the original contributor of this module by
12039 + leaving this note intact in the source code.
12040 +
12041 + All other licensing and usage conditions are those of the PHP Group.
12042 +
12043 + */
12044 +
12045 +/* $Id: apc_sma.h 277617 2009-03-23 02:16:24Z shire $ */
12046 +
12047 +#ifndef APC_SMA_H
12048 +#define APC_SMA_H
12049 +
12050 +#define ALLOC_DISTRIBUTION 0
12051 +
12052 +#include "apc.h"
12053 +
12054 +/* Simple shared memory allocator */
12055 +
12056 +typedef struct _apc_segment_t apc_segment_t;
12057 +
12058 +struct _apc_segment_t {
12059 + size_t size;
12060 + void* shmaddr;
12061 +#ifdef APC_MEMPROTECT
12062 + void* roaddr;
12063 +#endif
12064 +};
12065 +
12066 +extern void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask);
12067 +extern void apc_sma_cleanup();
12068 +extern void* apc_sma_malloc(size_t size);
12069 +extern void* apc_sma_malloc_ex(size_t size, size_t fragment, size_t* allocated);
12070 +extern void* apc_sma_realloc(void* p, size_t size);
12071 +extern char* apc_sma_strdup(const char *s);
12072 +extern void apc_sma_free(void* p);
12073 +#if ALLOC_DISTRIBUTION
12074 +extern size_t *apc_sma_get_alloc_distribution();
12075 +#endif
12076 +
12077 +extern void* apc_sma_protect(void *p);
12078 +extern void* apc_sma_unprotect(void *p);
12079 +
12080 +/* {{{ struct definition: apc_sma_link_t */
12081 +typedef struct apc_sma_link_t apc_sma_link_t;
12082 +struct apc_sma_link_t {
12083 + long size; /* size of this free block */
12084 + long offset; /* offset in segment of this block */
12085 + apc_sma_link_t* next; /* link to next free block */
12086 +};
12087 +/* }}} */
12088 +
12089 +/* {{{ struct definition: apc_sma_info_t */
12090 +typedef struct apc_sma_info_t apc_sma_info_t;
12091 +struct apc_sma_info_t {
12092 + int num_seg; /* number of shared memory segments */
12093 + size_t seg_size; /* size of each shared memory segment */
12094 + apc_sma_link_t** list; /* there is one list per segment */
12095 +};
12096 +/* }}} */
12097 +
12098 +extern apc_sma_info_t* apc_sma_info(zend_bool limited);
12099 +extern void apc_sma_free_info(apc_sma_info_t* info);
12100 +
12101 +extern size_t apc_sma_get_avail_mem();
12102 +extern void apc_sma_check_integrity();
12103 +
12104 +/* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */
12105 +typedef union { void* p; int i; long l; double d; void (*f)(); } apc_word_t;
12106 +#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size))))
12107 +#define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t))
12108 +/* }}} */
12109 +
12110 +#endif
12111 +
12112 +/*
12113 + * Local variables:
12114 + * tab-width: 4
12115 + * c-basic-offset: 4
12116 + * End:
12117 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12118 + * vim<600: expandtab sw=4 ts=4 sts=4
12119 + */
12120 diff -Naur php-5.3.1.orig/ext/apc/apc_spin.c php-5.3.1/ext/apc/apc_spin.c
12121 --- php-5.3.1.orig/ext/apc/apc_spin.c 1970-01-01 01:00:00.000000000 +0100
12122 +++ php-5.3.1/ext/apc/apc_spin.c 1970-01-01 10:13:08.000000000 +0100
12123 @@ -0,0 +1,66 @@
12124 +/*
12125 + +----------------------------------------------------------------------+
12126 + | APC |
12127 + +----------------------------------------------------------------------+
12128 + | Copyright (c) 2007-2008 The PHP Group |
12129 + +----------------------------------------------------------------------+
12130 + | This source file is subject to version 3.01 of the PHP license, |
12131 + | that is bundled with this package in the file LICENSE, and is |
12132 + | available through the world-wide-web at the following url: |
12133 + | http://www.php.net/license/3_01.txt |
12134 + | If you did not receive a copy of the PHP license and are unable to |
12135 + | obtain it through the world-wide-web, please send a note to |
12136 + | license@php.net so we can mail you a copy immediately. |
12137 + +----------------------------------------------------------------------+
12138 + | Authors: Brian Shire <shire@php.net> |
12139 + +----------------------------------------------------------------------+
12140 +
12141 + */
12142 +
12143 +/* $Id: apc_spin.c 268255 2008-11-04 05:42:11Z rasmus $ */
12144 +
12145 +#include "apc_spin.h"
12146 +
12147 +#ifdef APC_SPIN_LOCKS
12148 +
12149 +slock_t *apc_slock_create(slock_t *lock)
12150 +{
12151 + S_INIT_LOCK(lock);
12152 + return lock;
12153 +}
12154 +
12155 +void apc_slock_destroy(slock_t *lock)
12156 +{
12157 + return;
12158 +}
12159 +
12160 +void apc_slock_lock(slock_t *lock)
12161 +{
12162 + S_LOCK(lock);
12163 +}
12164 +
12165 +void apc_slock_unlock(slock_t *lock)
12166 +{
12167 + S_UNLOCK(lock);
12168 +}
12169 +
12170 +zend_bool apc_slock_nonblocking_lock(slock_t *lock)
12171 +{
12172 + /* Technically we aren't supposed to call this directly, but the original
12173 + * code provides no method for absolute non-blocking locks, so we'll call into
12174 + * the TAS (test and set) functionality directly
12175 + */
12176 + return !(TAS(lock)); /* if TAS returns 0 we obtained the lock, otherwise we failed */
12177 +}
12178 +
12179 +
12180 +#endif
12181 +
12182 +/*
12183 + * Local variables:
12184 + * tab-width: 4
12185 + * c-basic-offset: 4
12186 + * End:
12187 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12188 + * vim<600: expandtab sw=4 ts=4 sts=4
12189 + */
12190 diff -Naur php-5.3.1.orig/ext/apc/apc_spin.h php-5.3.1/ext/apc/apc_spin.h
12191 --- php-5.3.1.orig/ext/apc/apc_spin.h 1970-01-01 01:00:00.000000000 +0100
12192 +++ php-5.3.1/ext/apc/apc_spin.h 1970-01-01 10:13:08.000000000 +0100
12193 @@ -0,0 +1,49 @@
12194 +/*
12195 + +----------------------------------------------------------------------+
12196 + | APC |
12197 + +----------------------------------------------------------------------+
12198 + | Copyright (c) 2007-2008 The PHP Group |
12199 + +----------------------------------------------------------------------+
12200 + | This source file is subject to version 3.01 of the PHP license, |
12201 + | that is bundled with this package in the file LICENSE, and is |
12202 + | available through the world-wide-web at the following url: |
12203 + | http://www.php.net/license/3_01.txt |
12204 + | If you did not receive a copy of the PHP license and are unable to |
12205 + | obtain it through the world-wide-web, please send a note to |
12206 + | license@php.net so we can mail you a copy immediately. |
12207 + +----------------------------------------------------------------------+
12208 + | Authors: Brian Shire <shire@php.net> |
12209 + +----------------------------------------------------------------------+
12210 +
12211 + */
12212 +
12213 +/* $Id: apc_spin.h 268255 2008-11-04 05:42:11Z rasmus $ */
12214 +
12215 +#ifndef APC_SPIN_H
12216 +#define APC_SPIN_H
12217 +
12218 +#include "apc.h"
12219 +
12220 +#ifdef APC_SPIN_LOCKS
12221 +
12222 +#include "pgsql_s_lock.h"
12223 +
12224 +slock_t *apc_slock_create(slock_t *lock);
12225 +void apc_slock_destroy(slock_t *lock);
12226 +void apc_slock_lock(slock_t *lock);
12227 +zend_bool apc_slock_nonblocking_lock(slock_t *lock);
12228 +void apc_slock_lock(slock_t *lock);
12229 +void apc_slock_unlock(slock_t *lock);
12230 +
12231 +#endif
12232 +
12233 +#endif
12234 +
12235 +/*
12236 + * Local variables:
12237 + * tab-width: 4
12238 + * c-basic-offset: 4
12239 + * End:
12240 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12241 + * vim<600: expandtab sw=4 ts=4 sts=4
12242 + */
12243 diff -Naur php-5.3.1.orig/ext/apc/apc_stack.c php-5.3.1/ext/apc/apc_stack.c
12244 --- php-5.3.1.orig/ext/apc/apc_stack.c 1970-01-01 01:00:00.000000000 +0100
12245 +++ php-5.3.1/ext/apc/apc_stack.c 1970-01-01 10:13:08.000000000 +0100
12246 @@ -0,0 +1,106 @@
12247 +/*
12248 + +----------------------------------------------------------------------+
12249 + | APC |
12250 + +----------------------------------------------------------------------+
12251 + | Copyright (c) 2006-2008 The PHP Group |
12252 + +----------------------------------------------------------------------+
12253 + | This source file is subject to version 3.01 of the PHP license, |
12254 + | that is bundled with this package in the file LICENSE, and is |
12255 + | available through the world-wide-web at the following url: |
12256 + | http://www.php.net/license/3_01.txt |
12257 + | If you did not receive a copy of the PHP license and are unable to |
12258 + | obtain it through the world-wide-web, please send a note to |
12259 + | license@php.net so we can mail you a copy immediately. |
12260 + +----------------------------------------------------------------------+
12261 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
12262 + +----------------------------------------------------------------------+
12263 +
12264 + This software was contributed to PHP by Community Connect Inc. in 2002
12265 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
12266 + Future revisions and derivatives of this source code must acknowledge
12267 + Community Connect Inc. as the original contributor of this module by
12268 + leaving this note intact in the source code.
12269 +
12270 + All other licensing and usage conditions are those of the PHP Group.
12271 +
12272 + */
12273 +
12274 +/* $Id: apc_stack.c 268255 2008-11-04 05:42:11Z rasmus $ */
12275 +
12276 +#include "apc_stack.h"
12277 +#include "apc.h"
12278 +
12279 +struct apc_stack_t {
12280 + void** data;
12281 + int capacity;
12282 + int size;
12283 +};
12284 +
12285 +apc_stack_t* apc_stack_create(int size_hint)
12286 +{
12287 + apc_stack_t* stack = (apc_stack_t*) apc_emalloc(sizeof(apc_stack_t));
12288 +
12289 + stack->capacity = (size_hint > 0) ? size_hint : 10;
12290 + stack->size = 0;
12291 + stack->data = (void**) apc_emalloc(sizeof(void*) * stack->capacity);
12292 +
12293 + return stack;
12294 +}
12295 +
12296 +void apc_stack_destroy(apc_stack_t* stack)
12297 +{
12298 + if (stack != NULL) {
12299 + apc_efree(stack->data);
12300 + apc_efree(stack);
12301 + }
12302 +}
12303 +
12304 +void apc_stack_clear(apc_stack_t* stack)
12305 +{
12306 + assert(stack != NULL);
12307 + stack->size = 0;
12308 +}
12309 +
12310 +void apc_stack_push(apc_stack_t* stack, void* item)
12311 +{
12312 + assert(stack != NULL);
12313 + if (stack->size == stack->capacity) {
12314 + stack->capacity *= 2;
12315 + stack->data = apc_erealloc(stack->data, sizeof(void*)*stack->capacity);
12316 + }
12317 + stack->data[stack->size++] = item;
12318 +}
12319 +
12320 +void* apc_stack_pop(apc_stack_t* stack)
12321 +{
12322 + assert(stack != NULL && stack->size > 0);
12323 + return stack->data[--stack->size];
12324 +}
12325 +
12326 +void* apc_stack_top(apc_stack_t* stack)
12327 +{
12328 + assert(stack != NULL && stack->size > 0);
12329 + return stack->data[stack->size-1];
12330 +}
12331 +
12332 +void* apc_stack_get(apc_stack_t* stack, int n)
12333 +{
12334 + assert(stack != NULL && stack->size > n);
12335 + return stack->data[n];
12336 +}
12337 +
12338 +int apc_stack_size(apc_stack_t* stack)
12339 +{
12340 + assert(stack != NULL);
12341 + return stack->size;
12342 +}
12343 +
12344 +
12345 +/*
12346 + * Local variables:
12347 + * tab-width: 4
12348 + * c-basic-offset: 4
12349 + * End:
12350 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12351 + * vim<600: expandtab sw=4 ts=4 sts=4
12352 + */
12353 diff -Naur php-5.3.1.orig/ext/apc/apc_stack.h php-5.3.1/ext/apc/apc_stack.h
12354 --- php-5.3.1.orig/ext/apc/apc_stack.h 1970-01-01 01:00:00.000000000 +0100
12355 +++ php-5.3.1/ext/apc/apc_stack.h 1970-01-01 10:13:08.000000000 +0100
12356 @@ -0,0 +1,58 @@
12357 +/*
12358 + +----------------------------------------------------------------------+
12359 + | APC |
12360 + +----------------------------------------------------------------------+
12361 + | Copyright (c) 2006-2008 The PHP Group |
12362 + +----------------------------------------------------------------------+
12363 + | This source file is subject to version 3.01 of the PHP license, |
12364 + | that is bundled with this package in the file LICENSE, and is |
12365 + | available through the world-wide-web at the following url: |
12366 + | http://www.php.net/license/3_01.txt |
12367 + | If you did not receive a copy of the PHP license and are unable to |
12368 + | obtain it through the world-wide-web, please send a note to |
12369 + | license@php.net so we can mail you a copy immediately. |
12370 + +----------------------------------------------------------------------+
12371 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
12372 + | George Schlossnagle <george@omniti.com> |
12373 + +----------------------------------------------------------------------+
12374 +
12375 + This software was contributed to PHP by Community Connect Inc. in 2002
12376 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
12377 + Future revisions and derivatives of this source code must acknowledge
12378 + Community Connect Inc. as the original contributor of this module by
12379 + leaving this note intact in the source code.
12380 +
12381 + All other licensing and usage conditions are those of the PHP Group.
12382 +
12383 + */
12384 +
12385 +/* $Id: apc_stack.h 268255 2008-11-04 05:42:11Z rasmus $ */
12386 +
12387 +#ifndef APC_STACK_H
12388 +#define APC_STACK_H
12389 +
12390 +/* Basic stack datatype */
12391 +
12392 +#define T apc_stack_t*
12393 +typedef struct apc_stack_t apc_stack_t; /* opaque stack type */
12394 +
12395 +extern T apc_stack_create(int size_hint);
12396 +extern void apc_stack_destroy(T stack);
12397 +extern void apc_stack_clear(T stack);
12398 +extern void apc_stack_push(T stack, void* item);
12399 +extern void* apc_stack_pop(T stack);
12400 +extern void* apc_stack_top(T stack);
12401 +extern void* apc_stack_get(T stack, int n);
12402 +extern int apc_stack_size(T stack);
12403 +
12404 +#undef T
12405 +#endif
12406 +
12407 +/*
12408 + * Local variables:
12409 + * tab-width: 4
12410 + * c-basic-offset: 4
12411 + * End:
12412 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12413 + * vim<600: expandtab sw=4 ts=4 sts=4
12414 + */
12415 diff -Naur php-5.3.1.orig/ext/apc/apc_zend.c php-5.3.1/ext/apc/apc_zend.c
12416 --- php-5.3.1.orig/ext/apc/apc_zend.c 1970-01-01 01:00:00.000000000 +0100
12417 +++ php-5.3.1/ext/apc/apc_zend.c 1970-01-01 10:13:08.000000000 +0100
12418 @@ -0,0 +1,213 @@
12419 +/*
12420 + +----------------------------------------------------------------------+
12421 + | APC |
12422 + +----------------------------------------------------------------------+
12423 + | Copyright (c) 2006-2008 The PHP Group |
12424 + +----------------------------------------------------------------------+
12425 + | This source file is subject to version 3.01 of the PHP license, |
12426 + | that is bundled with this package in the file LICENSE, and is |
12427 + | available through the world-wide-web at the following url: |
12428 + | http://www.php.net/license/3_01.txt |
12429 + | If you did not receive a copy of the PHP license and are unable to |
12430 + | obtain it through the world-wide-web, please send a note to |
12431 + | license@php.net so we can mail you a copy immediately. |
12432 + +----------------------------------------------------------------------+
12433 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
12434 + +----------------------------------------------------------------------+
12435 +
12436 + This software was contributed to PHP by Community Connect Inc. in 2002
12437 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
12438 + Future revisions and derivatives of this source code must acknowledge
12439 + Community Connect Inc. as the original contributor of this module by
12440 + leaving this note intact in the source code.
12441 +
12442 + All other licensing and usage conditions are those of the PHP Group.
12443 +
12444 + */
12445 +
12446 +/* $Id: apc_zend.c 276053 2009-02-18 08:59:00Z gopalv $ */
12447 +
12448 +#include "apc_zend.h"
12449 +#include "apc_globals.h"
12450 +
12451 +/* true global */
12452 +int apc_reserved_offset;
12453 +
12454 +void* apc_php_malloc(size_t n)
12455 +{
12456 + return emalloc(n);
12457 +}
12458 +
12459 +void apc_php_free(void* p)
12460 +{
12461 + efree(p);
12462 +}
12463 +
12464 +#ifdef APC_OPCODE_OVERRIDE
12465 +
12466 +static opcode_handler_t *apc_original_opcode_handlers;
12467 +static opcode_handler_t apc_opcode_handlers[APC_OPCODE_HANDLER_COUNT];
12468 +
12469 +#define APC_EX_T(offset) (*(temp_variable *)((char*)execute_data->Ts + offset))
12470 +
12471 +static zval *apc_get_zval_ptr(znode *node, zval **freeval, zend_execute_data *execute_data TSRMLS_DC)
12472 +{
12473 + *freeval = NULL;
12474 +
12475 + switch (node->op_type) {
12476 + case IS_CONST:
12477 + return &(node->u.constant);
12478 + case IS_VAR:
12479 + return APC_EX_T(node->u.var).var.ptr;
12480 + case IS_TMP_VAR:
12481 + return (*freeval = &APC_EX_T(node->u.var).tmp_var);
12482 +#ifdef ZEND_ENGINE_2_1
12483 + case IS_CV:
12484 + {
12485 + zval ***ret = &execute_data->CVs[node->u.var];
12486 +
12487 + if (!*ret) {
12488 + zend_compiled_variable *cv = &EG(active_op_array)->vars[node->u.var];
12489 +
12490 + if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void**)ret)==FAILURE) {
12491 + apc_nprint("Undefined variable: %s", cv->name);
12492 + return &EG(uninitialized_zval);
12493 + }
12494 + }
12495 + return **ret;
12496 + }
12497 +#endif
12498 + case IS_UNUSED:
12499 + default:
12500 + return NULL;
12501 + }
12502 +}
12503 +
12504 +static int ZEND_FASTCALL apc_op_ZEND_INCLUDE_OR_EVAL(ZEND_OPCODE_HANDLER_ARGS)
12505 +{
12506 + APC_ZEND_OPLINE
12507 + zval *freeop1 = NULL;
12508 + zval *inc_filename = NULL, tmp_inc_filename;
12509 + char realpath[MAXPATHLEN];
12510 + php_stream_wrapper *wrapper;
12511 + char *path_for_open;
12512 + int ret = 0;
12513 + apc_opflags_t* flags = NULL;
12514 +
12515 + if (Z_LVAL(opline->op2.u.constant) != ZEND_INCLUDE_ONCE &&
12516 + Z_LVAL(opline->op2.u.constant) != ZEND_REQUIRE_ONCE) {
12517 + return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
12518 + }
12519 +
12520 + inc_filename = apc_get_zval_ptr(&opline->op1, &freeop1, execute_data TSRMLS_CC);
12521 + if (Z_TYPE_P(inc_filename) != IS_STRING) {
12522 + tmp_inc_filename = *inc_filename;
12523 + zval_copy_ctor(&tmp_inc_filename);
12524 + convert_to_string(&tmp_inc_filename);
12525 + inc_filename = &tmp_inc_filename;
12526 + }
12527 +
12528 + wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(inc_filename), &path_for_open, 0 TSRMLS_CC);
12529 +
12530 + if (wrapper != &php_plain_files_wrapper ||
12531 + !(IS_ABSOLUTE_PATH(path_for_open, strlen(path_for_open)) ||
12532 + expand_filepath(path_for_open, realpath TSRMLS_CC))) {
12533 + /* Fallback to original handler */
12534 + if (inc_filename == &tmp_inc_filename) {
12535 + zval_dtor(&tmp_inc_filename);
12536 + }
12537 + return apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
12538 + }
12539 +
12540 + if (zend_hash_exists(&EG(included_files), realpath, strlen(realpath) + 1)) {
12541 + if (!(opline->result.u.EA.type & EXT_TYPE_UNUSED)) {
12542 + ALLOC_INIT_ZVAL(APC_EX_T(opline->result.u.var).var.ptr);
12543 + ZVAL_TRUE(APC_EX_T(opline->result.u.var).var.ptr);
12544 + }
12545 + if (inc_filename == &tmp_inc_filename) {
12546 + zval_dtor(&tmp_inc_filename);
12547 + }
12548 + if (freeop1) {
12549 + zval_dtor(freeop1);
12550 + }
12551 + execute_data->opline++;
12552 + return 0;
12553 + }
12554 +
12555 + if (inc_filename == &tmp_inc_filename) {
12556 + zval_dtor(&tmp_inc_filename);
12557 + }
12558 +
12559 + if(apc_reserved_offset != -1) {
12560 + /* Insanity alert: look into apc_compile.c for why a void** is cast to a apc_opflags_t* */
12561 + flags = (apc_opflags_t*) & (execute_data->op_array->reserved[apc_reserved_offset]);
12562 + }
12563 +
12564 + if(flags && flags->deep_copy == 1) {
12565 + /* Since the op array is a local copy, we can cheat our way through the file inclusion by temporarily
12566 + * changing the op to a plain require/include, calling its handler and finally restoring the opcode.
12567 + */
12568 + Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE_ONCE) ? ZEND_INCLUDE : ZEND_REQUIRE;
12569 + ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
12570 + Z_LVAL(opline->op2.u.constant) = (Z_LVAL(opline->op2.u.constant) == ZEND_INCLUDE) ? ZEND_INCLUDE_ONCE : ZEND_REQUIRE_ONCE;
12571 + } else {
12572 + ret = apc_original_opcode_handlers[APC_OPCODE_HANDLER_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
12573 + }
12574 +
12575 + return ret;
12576 +}
12577 +
12578 +void apc_zend_init(TSRMLS_D)
12579 +{
12580 + zend_extension dummy_ext;
12581 + apc_reserved_offset = zend_get_resource_handle(&dummy_ext);
12582 + assert(apc_reserved_offset == dummy_ext.resource_number);
12583 + assert(apc_reserved_offset != -1);
12584 + assert(sizeof(apc_opflags_t) <= sizeof(void*));
12585 + if (!APCG(include_once)) {
12586 + /* If we're not overriding the INCLUDE_OR_EVAL handler, then just skip this malarkey */
12587 + return;
12588 + }
12589 +
12590 + memcpy(apc_opcode_handlers, zend_opcode_handlers, sizeof(apc_opcode_handlers));
12591 +
12592 + /* 5.0 exposes zend_opcode_handlers differently than 5.1 and later */
12593 +#ifdef ZEND_ENGINE_2_1
12594 + apc_original_opcode_handlers = zend_opcode_handlers;
12595 + zend_opcode_handlers = apc_opcode_handlers;
12596 +#else
12597 + apc_original_opcode_handlers = apc_opcode_handlers;
12598 +#endif
12599 +
12600 + APC_REPLACE_OPCODE(ZEND_INCLUDE_OR_EVAL);
12601 +}
12602 +
12603 +void apc_zend_shutdown(TSRMLS_D)
12604 +{
12605 + if (!APCG(include_once)) {
12606 + /* Nothing changed, nothing to restore */
12607 + return;
12608 + }
12609 +
12610 +#ifdef ZEND_ENGINE_2_1
12611 + zend_opcode_handlers = apc_original_opcode_handlers;
12612 +#else
12613 + memcpy(zend_opcode_handlers, apc_original_opcode_handlers, sizeof(apc_opcode_handlers));
12614 +#endif
12615 +}
12616 +
12617 +#else /* Opcode Overrides unavailable */
12618 +
12619 +void apc_zend_init(TSRMLS_D) { }
12620 +void apc_zend_shutdown(TSRMLS_D) { }
12621 +
12622 +#endif /* APC_OPCODE_OVERRIDE */
12623 +
12624 +/*
12625 + * Local variables:
12626 + * tab-width: 4
12627 + * c-basic-offset: 4
12628 + * End:
12629 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12630 + * vim<600: expandtab sw=4 ts=4 sts=4
12631 + */
12632 diff -Naur php-5.3.1.orig/ext/apc/apc_zend.h php-5.3.1/ext/apc/apc_zend.h
12633 --- php-5.3.1.orig/ext/apc/apc_zend.h 1970-01-01 01:00:00.000000000 +0100
12634 +++ php-5.3.1/ext/apc/apc_zend.h 1970-01-01 10:13:08.000000000 +0100
12635 @@ -0,0 +1,169 @@
12636 +/*
12637 + +----------------------------------------------------------------------+
12638 + | APC |
12639 + +----------------------------------------------------------------------+
12640 + | Copyright (c) 2006-2008 The PHP Group |
12641 + +----------------------------------------------------------------------+
12642 + | This source file is subject to version 3.01 of the PHP license, |
12643 + | that is bundled with this package in the file LICENSE, and is |
12644 + | available through the world-wide-web at the following url: |
12645 + | http://www.php.net/license/3_01.txt |
12646 + | If you did not receive a copy of the PHP license and are unable to |
12647 + | obtain it through the world-wide-web, please send a note to |
12648 + | license@php.net so we can mail you a copy immediately. |
12649 + +----------------------------------------------------------------------+
12650 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
12651 + +----------------------------------------------------------------------+
12652 +
12653 + This software was contributed to PHP by Community Connect Inc. in 2002
12654 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
12655 + Future revisions and derivatives of this source code must acknowledge
12656 + Community Connect Inc. as the original contributor of this module by
12657 + leaving this note intact in the source code.
12658 +
12659 + All other licensing and usage conditions are those of the PHP Group.
12660 +
12661 + */
12662 +
12663 +/* $Id: apc_zend.h 286799 2009-08-04 11:27:29Z gopalv $ */
12664 +
12665 +#ifndef APC_ZEND_H
12666 +#define APC_ZEND_H
12667 +
12668 +/* Utilities for interfacing with the zend engine */
12669 +
12670 +#include "apc.h"
12671 +#include "apc_php.h"
12672 +
12673 +#ifndef Z_REFCOUNT_P
12674 +#define Z_REFCOUNT_P(pz) (pz)->refcount
12675 +#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))
12676 +#endif
12677 +
12678 +#ifndef Z_SET_REFCOUNT_P
12679 +#define Z_SET_REFCOUNT_P(pz, rc) (pz)->refcount = rc
12680 +#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc)
12681 +#endif
12682 +
12683 +#ifndef Z_ADDREF_P
12684 +#define Z_ADDREF_P(pz) (pz)->refcount++
12685 +#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz))
12686 +#endif
12687 +
12688 +#ifndef Z_DELREF_P
12689 +#define Z_DELREF_P(pz) (pz)->refcount--
12690 +#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
12691 +#endif
12692 +
12693 +#ifndef Z_ISREF_P
12694 +#define Z_ISREF_P(pz) (pz)->is_ref
12695 +#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz))
12696 +#endif
12697 +
12698 +#ifndef Z_SET_ISREF_P
12699 +#define Z_SET_ISREF_P(pz) (pz)->is_ref = 1
12700 +#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz))
12701 +#endif
12702 +
12703 +#ifndef Z_UNSET_ISREF_P
12704 +#define Z_UNSET_ISREF_P(pz) (pz)->is_ref = 0
12705 +#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz))
12706 +#endif
12707 +
12708 +#ifndef Z_SET_ISREF_TO_P
12709 +#define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = isref
12710 +#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref)
12711 +#endif
12712 +
12713 +
12714 +extern void* apc_php_malloc(size_t n);
12715 +extern void apc_php_free(void* p);
12716 +
12717 +extern void apc_zend_init(TSRMLS_D);
12718 +extern void apc_zend_shutdown(TSRMLS_D);
12719 +
12720 +
12721 +/* offset for apc info in op_array->reserved */
12722 +extern int apc_reserved_offset;
12723 +
12724 +#ifndef ZEND_VM_KIND_CALL /* Not currently defined by any ZE version */
12725 +# define ZEND_VM_KIND_CALL 1
12726 +#endif
12727 +
12728 +#ifndef ZEND_VM_KIND /* Indicates PHP < 5.1 */
12729 +# define ZEND_VM_KIND ZEND_VM_KIND_CALL
12730 +#endif
12731 +
12732 +#if defined(ZEND_ENGINE_2) && (ZEND_VM_KIND == ZEND_VM_KIND_CALL)
12733 +# define APC_OPCODE_OVERRIDE
12734 +#endif
12735 +
12736 +#ifdef APC_OPCODE_OVERRIDE
12737 +
12738 +#ifdef ZEND_ENGINE_2_1
12739 +/* Taken from Zend/zend_vm_execute.h */
12740 +#define _CONST_CODE 0
12741 +#define _TMP_CODE 1
12742 +#define _VAR_CODE 2
12743 +#define _UNUSED_CODE 3
12744 +#define _CV_CODE 4
12745 +static inline int _apc_opcode_handler_decode(zend_op *opline)
12746 +{
12747 + static const int apc_vm_decode[] = {
12748 + _UNUSED_CODE, /* 0 */
12749 + _CONST_CODE, /* 1 = IS_CONST */
12750 + _TMP_CODE, /* 2 = IS_TMP_VAR */
12751 + _UNUSED_CODE, /* 3 */
12752 + _VAR_CODE, /* 4 = IS_VAR */
12753 + _UNUSED_CODE, /* 5 */
12754 + _UNUSED_CODE, /* 6 */
12755 + _UNUSED_CODE, /* 7 */
12756 + _UNUSED_CODE, /* 8 = IS_UNUSED */
12757 + _UNUSED_CODE, /* 9 */
12758 + _UNUSED_CODE, /* 10 */
12759 + _UNUSED_CODE, /* 11 */
12760 + _UNUSED_CODE, /* 12 */
12761 + _UNUSED_CODE, /* 13 */
12762 + _UNUSED_CODE, /* 14 */
12763 + _UNUSED_CODE, /* 15 */
12764 + _CV_CODE /* 16 = IS_CV */
12765 + };
12766 + return (opline->opcode * 25) + (apc_vm_decode[opline->op1.op_type] * 5) + apc_vm_decode[opline->op2.op_type];
12767 +}
12768 +
12769 +# define APC_ZEND_OPLINE zend_op *opline = execute_data->opline;
12770 +# define APC_OPCODE_HANDLER_DECODE(opline) _apc_opcode_handler_decode(opline)
12771 +# if PHP_MAJOR_VERSION >= 6
12772 +# define APC_OPCODE_HANDLER_COUNT ((25 * 152) + 1)
12773 +# elif PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3
12774 +# define APC_OPCODE_HANDLER_COUNT ((25 * 154) + 1) /* 3 new opcodes in 5.3 - unused, lambda, jmp_set */
12775 +# else
12776 +# define APC_OPCODE_HANDLER_COUNT ((25 * 151) + 1)
12777 +# endif
12778 +# define APC_REPLACE_OPCODE(opname) { int i; for(i = 0; i < 25; i++) if (zend_opcode_handlers[(opname*25) + i]) zend_opcode_handlers[(opname*25) + i] = apc_op_##opname; }
12779 +
12780 +#else /* ZE2.0 */
12781 +# define APC_ZEND_ONLINE
12782 +# define APC_OPCODE_HANDLER_DECODE(opline) (opline->opcode)
12783 +# define APC_OPCODE_HANDLER_COUNT 512
12784 +# define APC_REPLACE_OPCODE(opname) zend_opcode_handlers[opname] = apc_op_##opname;
12785 +#endif
12786 +
12787 +#ifndef ZEND_FASTCALL /* Added in ZE2.3.0 */
12788 +#define ZEND_FASTCALL
12789 +#endif
12790 +
12791 +
12792 +#endif /* APC_OPCODE_OVERRIDE */
12793 +
12794 +
12795 +#endif /* APC_ZEND_H */
12796 +
12797 +/*
12798 + * Local variables:
12799 + * tab-width: 4
12800 + * c-basic-offset: 4
12801 + * End:
12802 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
12803 + * vim<600: expandtab sw=4 ts=4 sts=4
12804 + */
12805 diff -Naur php-5.3.1.orig/ext/apc/CHANGELOG php-5.3.1/ext/apc/CHANGELOG
12806 --- php-5.3.1.orig/ext/apc/CHANGELOG 1970-01-01 01:00:00.000000000 +0100
12807 +++ php-5.3.1/ext/apc/CHANGELOG 1970-01-01 10:13:08.000000000 +0100
12808 @@ -0,0 +1,249 @@
12809 +
12810 +3.1.2 : 2008-12-12
12811 +
12812 +- pecl package.xml/build fixes (bjori)
12813 +
12814 +3.1.1 : 2008-12-12
12815 +
12816 +- PHP4 compatibilty break
12817 +- apc_pool allocator (Gopal)
12818 +- doubly-linked sma allocator (Shire)
12819 +- php 5.3 gc compatibility (Gopal)
12820 +- APCIterator for easy access (Shire)
12821 +- apc_delete_file (Shire)
12822 +- apc_inc/apc_dec/apc_cas functions (Shire)
12823 +- apc.canonicalize (Gopal)
12824 +- apc.preload_path (Gopal)
12825 +- apc.rfc1867_ttl (Shire)
12826 +- apc.file_md5 (Shire)
12827 +- consolidate locking macros (Shire)
12828 +- remove futex/TSRM locks (Shire)
12829 +- non-blocking semaphore locks (Shire)
12830 +- zval* object rework (Gopal)
12831 +
12832 +3.0.19: 2008-05-14
12833 +- Safe-mode and fast-cgi fixes
12834 +- Fix double-free of builtin_functions
12835 +- php 5.3 fixes
12836 +
12837 +3.0.18: 2008-03-29
12838 +- Revert apc_expunge_cb bug-fix
12839 +- Misc memleaks
12840 +
12841 +3.0.17: 2008-03-26
12842 +- Crash fixes
12843 +- Fix apc_add() cache expunge bug (Rasmus)
12844 +- Added parameter to apc_fetch to determine success/failure when fetching booleans (shire)
12845 +- Fix misc. memleaks (shire)
12846 +
12847 +3.0.16: 2007-12-26
12848 +- Fix for longstanding cache-full crash (Christian Seiler)
12849 + http://news.php.net/php.pecl.dev/4951 for the details
12850 +- Added optional shm unmap on a fatal signal feature (Lucas Nealan)
12851 +- Added PTHREAD_MUTEX_ADAPTIVE_NP option pthread locks (Paul Saab)
12852 +- Minor cleanups (Lucas Nealan)
12853 +- Added configure option to enable apc_cache_info('filehits') (Shire)
12854 +
12855 +3.0.15: 2007-10-18
12856 +- Eliminate a per-request time() syscall (Rasmus)
12857 +- Added rfc1867 prefix, name, and freq ini options (Shire)
12858 +- Allow deletion of individual user cache entries via apc.php (Sara)
12859 +- Fix overzealous cleanup during RSHUTDOWN (Gopal)
12860 +- Fix memory alignment and locking issues (Gopal)
12861 +- Make apc_compile insert/replace entries (Shire)
12862 +- Make mixed inheritance recompile & cache afresh (Gopal)
12863 +- Make nostat mode search include_path for canonicalization (Gopal)
12864 +- ZTS & other compile fixes (Gopal, Edin, Shire)
12865 +
12866 +3.0.14: 2007-03-21
12867 +- Build fix (Shire)
12868 +- Don't hook the upload hook if APC is disabled (Rasmus)
12869 +- Local shadow cache support (Gopal)
12870 +- Avoid uneccessary loops over op_arrays for "known" auto-globals (Gopal)
12871 +- Fix apc_add() to overwrite timed out user entries (Rasmus)
12872 +- Fix double inclusion of files with conditional classes in php4 (Gopal)
12873 +- Allocator fixes to reduce fragmentation (Gopal)
12874 +
12875 +3.0.13: 2007-02-24
12876 +- File upload progress (Rasmus)
12877 +- Pthread mutex and spin locks (Shire)
12878 +- Recursive zval support for apc_fetch/_store (Shire, Gopal)
12879 +- apc.stat_ctime flag for ctime checks (Rasmus)
12880 +- Multiple key fetches with apc_fetch (Shire)
12881 +- Canary checks for shm memory deallocation (Gopal)
12882 +- Add hooks for external optimizer (Shire)
12883 +- Obsolete and remove apc optimizer (Gopal)
12884 +- APC info changes - cache insert rate, hit and miss rates (Shire)
12885 +- Fix apc_load_constants (Gopal)
12886 +- Rewrite dump opcode code to use vld (Gopal)
12887 +- Use apc_[ewn]print functions for error reporting (Shire)
12888 +- Auto global fixes and refactoring (Gopal, Shire)
12889 +- Fix memory leaks in object serialization (Ilia)
12890 +- Memory cleanup code for destructor order (Gopal)
12891 +- Win32 build fixes (Ilia, Wez)
12892 +- ZTS and Php 4 build fixes (Bjori)
12893 +- Add apc_add() function (Rasmus)
12894 +- Add optional limited flag to apc_sma_info() (Rasmus)
12895 +
12896 +3.0.12p2: 2006-09-05
12897 +- Package version up
12898 +
12899 +3.0,12p1: 2006-09-05
12900 +- PHP4 build fixes
12901 +
12902 +3.0.12: 2006-09-05
12903 +- PHP 5.2 compatibility (Gopal)
12904 +- TSRM fixes (Gopal)
12905 +- Add extra flags to op_array->reserved to improve op array
12906 + processing code (Gopal)
12907 +- Fix crashes in optimizer and cli mode (Ilia)
12908 +- Optimizer fixes for PHP5 (Ilia, Gopal)
12909 +- Allow multiple inclusions of a file with a dynamic class (Gopal)
12910 +- Php 4 function table and properties fixes (Gopal)
12911 +- Fix memory leaks in apc_cache_info (Gopal)
12912 +
12913 +3.0.11: 2006-08-16
12914 +- Made --enable-apc-mmap the default compile option (for real this time)
12915 +- Add an optional flag to apc_cache_info() and some apc.php tweaks to make it
12916 + only fetch header information to make it useful when you have tens of
12917 + thousands of entries. (Brian Shire)
12918 +- 64-bit fixes (George)
12919 +- Don't mix Full Path and Inode keys (George)
12920 +- Override ZEND_INCLUDE_OR_EVAL opcode (when possible) to speed up use of
12921 + require_once() and include_once() statements. (Sara)
12922 +- Add a non-blocking write_lock for cache inserts. This is a better approach
12923 + to prevent cache slams and deprecates the slam_defense setting. (Rasmus)
12924 +- A bit of work on the optimizer. (Sara)
12925 +- Various memory issues resolved. (Gopal)
12926 +
12927 +3.0.10: 2006-03-11
12928 +- Add apc.stat ini flag which defaults to 1. If set to 0, the main script and any fullpath
12929 + includes will not be stat'ed for any changes. You will have to restart the server if you
12930 + change anything. This mode increases performance quite a bit, especially if you have a
12931 + lot of includes.
12932 +
12933 +- Get rid of the lock safety net hack I added in 3.0.9. It seems to cause more problems
12934 + than it solves. I'll need to revisit locking and signal handling at some point soon.
12935 +
12936 +3.0.9: 2006-03-04
12937 +- Eliminate rand() call when slam_defense is not set (Rasmus)
12938 +- Fix for __isset problem (Gopal)
12939 +- Rewrite allocator from a "best fit" to a "next fit" algorithm (Rasmus)
12940 +- Added a Cache Full counter so we have an idea how many times the segment has filled up causing an expunge (Rasmus)
12941 +- Report back the correct number of available bytes in the segment instead of the allocated bytes. (Rasmus)
12942 +- Add cache busy flag which is set when an expunge is underway (Rasmus)
12943 +- Add automatic serialization of objects in apc_store() (Marcus)
12944 +- 64-bit .ini flag fix (Rasmus)
12945 +- Static members fix (Gopal)
12946 +- sma_cleanup() mem leak fix (Rasmus)
12947 +- Fix for http://pecl.php.net/bugs/5311 (Rasmus)
12948 +- Fix autoglobals JIT bug (Gopal)
12949 +- Fix instance bug (Gopal)
12950 +- Add a lock cleanup safety net to request shutdown (Rasmus)
12951 +- Fix apc.slam_defense edge-case bug (Rasmus)
12952 +- User entry memory usage tracking support (Ilia)
12953 +- Allow keys used in apc_store/apc_fetch/apc_delete to be binary safe and prevent conflicts between keys that are found at the start of other keys. (Ilia)
12954 +
12955 +3.0.8: 2005-08-24
12956 +Fix invalid free in globals destructor introduced in 3.0.7 (Rasmus)
12957 +Cache corruption fix in cache-full cleanup code (Gopal)
12958 +
12959 +3.0.7: 2005-08-16
12960 +- Fix to apc.php to show final segment in frag chart. (Ilia)
12961 +- A couple of win32 fixes. (Frank)
12962 +- Add apc.enable_cli ini directive. (Rasmus)
12963 +- Add test cases. (Marcus)
12964 +- Fix apc_define_constants() bug - http://pecl.php.net/bugs/5084 (Rasmus)
12965 +- Simplify user cache handling by removing the user_cache_stack (Rasmus)
12966 +- Fix apc_fetch() memory corruption (Andrei,Rasmus)
12967 +- Added apc.max_file_size INI setting that allows exclusion of large files from being cached. Default file size limit, 1 megabyte. (Ilia)
12968 +
12969 +3.0.6: 2005-07-30
12970 +- Added apc.php to package.xml file.
12971 +- Track per-entry memory usage. (Val)
12972 +- Various apc.php fixes and enhancements. (Ralf, Ilia, Rasmus)
12973 +- fcntl locking robustness fixes. (Rasmus)
12974 +- Shared read-locks where possible. (Rasmus)
12975 +- Added file_update_protection configuration parameter. (Rasmus)
12976 +- Windows ZTS fixes (Frank)
12977 +
12978 +3.0.5: 2005-07-27
12979 +- Make it easier for sapis that only populate file_handle->filename to use APC. (Rasmus)
12980 +- Support extensions such as bcompiler that need to hook into compile_file. (Val)
12981 +- Ralf Becker's apcgui code has now become the default apc.php status page. (Ralf, Rasmus, Ilia)
12982 +- Segfault in cache cleanup code (Ilia, Rasmus)
12983 +
12984 +3.0.4: 2005-07-18
12985 +- Add win32 support (Edin )
12986 +- Add --with-apxs switch to work around problem when loading APC into Apache binary compiled with LFS switches (Rasmus)
12987 +- A couple of other minor fixes
12988 +
12989 +3.0.3: 2005-07-05
12990 +- Fix compile problem against PHP 5.0.x
12991 +
12992 +3.0.2: 2005-07-05
12993 +- Better shm error message
12994 +
12995 +3.0.1: 2005-07-05
12996 +- PHP4 build fix
12997 +
12998 +3.0: 2005-06-23
12999 +- PHP 5.1 support (Arun, Gopal, Rasmus)
13000 +- Major Inheritance bug fix (Arun, Gopal)
13001 +
13002 +2.0: 2003-02-10
13003 +- ground-up rewrite sharing none of the original source code (djc)
13004 +
13005 +1.0.10:
13006 +- merge mmap / shm code to be in one file, module supports both modes now [mpb 2001-05-15]
13007 +- added apc.mode config parameter [mpb 2001-05-15] NOTE: You'll have to add
13008 + this parameter to your php.ini file to activate apc shm or mmap caching
13009 +- generic source cleanup (missing includes, PATH_MAX usage etc) [mpb
13010 + 2001-05-15]
13011 +- fixed: realpath return result checking in generate_key [mpb 2001-05-15]
13012 +- updated: gui updated (extras/apc_gui-1.0.2.tar.gz)
13013 +- experminental 'fast' cache-retrieval [djc 2001-05-20]
13014 +- fixed regex support [gws 2001-05-16]
13015 +- enhanced reader-writer lock support [rg 2001-05-07]
13016 +
13017 +1.0.9:
13018 +- fixed (?) memory alignment bug on 64 bit archiecures
13019 +- added many cache visibiliy functions
13020 +- added opional fcntl locks under shm version
13021 +- numerous bug fixes
13022 +
13023 +1.0.8:
13024 +- added ability to detect and decompile compiled files placed as 'source'
13025 + [gws,dw 2001-01-30]
13026 +- fixed apc_rstat bug [gws 2001-01-29]
13027 +- added hack to support included urls [gws 2001-01-30]
13028 +- fixed apc_cache_index [mb 2001-01-31]
13029 +- added multiple regex support [gs 2001-02-03]
13030 +- added apc_cache_info [mb,gs 2001-02-03]
13031 +
13032 +1.0.7:
13033 +- partially fixed for Solaris [gws 2001-01-29]
13034 +- fixed mtime support for relative includes [gws 2001-01-29]
13035 +- code cleanup [yg,ta,gws 2001-01-29]
13036 +
13037 +1.0.6:
13038 +- support for mtime in mmap [yg,gws 2001-01-27]
13039 +- fixed indexed-array initialization bug [djc,gws 2001-01-27]
13040 +
13041 +1.0.5:
13042 +- support for relative include paths [djc,gws 2001-01-19]
13043 +- class member array support fixed [djc 2001-01-18]
13044 +- added apc_cache_index [gws 2001-01-18]
13045 +
13046 +1.0.4:
13047 +- support for class hierarchies greater than two levels deep [djc 2001-01-17]
13048 +
13049 +1.0.3:
13050 +- fixed support for class inheritance [djc 2001-01-16]
13051 +
13052 +1.0.2:
13053 +- support for inherited classes [gws 2001-01-15]
13054 +- support for intialization of class variables and objects [gws 2001-01-13]
13055 +
13056 +1.0.1:
13057 +- added optional file modification time check [djc 2001-01-12]
13058 diff -Naur php-5.3.1.orig/ext/apc/config.m4 php-5.3.1/ext/apc/config.m4
13059 --- php-5.3.1.orig/ext/apc/config.m4 1970-01-01 01:00:00.000000000 +0100
13060 +++ php-5.3.1/ext/apc/config.m4 1970-01-01 10:13:08.000000000 +0100
13061 @@ -0,0 +1,232 @@
13062 +dnl
13063 +dnl $Id: config.m4 286829 2009-08-05 10:31:28Z gopalv $
13064 +dnl
13065 +
13066 +PHP_ARG_ENABLE(apc, whether to enable APC support,
13067 +[ --enable-apc Enable APC support])
13068 +
13069 +AC_MSG_CHECKING(whether we should enable cache request file info)
13070 +AC_ARG_ENABLE(apc-filehits,
13071 +[ --enable-apc-filehits Enable per request file info about files used from the APC cache (ie: apc_cache_info('filehits')) ],
13072 +[
13073 + PHP_APC_FILEHITS=$enableval
13074 + AC_MSG_RESULT($enableval)
13075 +],
13076 +[
13077 + PHP_APC_FILEHITS=no
13078 + AC_MSG_RESULT(no)
13079 +])
13080 +
13081 +AC_MSG_CHECKING(whether we should use mmap)
13082 +AC_ARG_ENABLE(apc-mmap,
13083 +[ --disable-apc-mmap
13084 + Disable mmap support and use IPC shm instead],
13085 +[
13086 + PHP_APC_MMAP=$enableval
13087 + AC_MSG_RESULT($enableval)
13088 +], [
13089 + PHP_APC_MMAP=yes
13090 + AC_MSG_RESULT(yes)
13091 +])
13092 +
13093 +AC_MSG_CHECKING(whether we should use semaphore locking instead of fcntl)
13094 +AC_ARG_ENABLE(apc-sem,
13095 +[ --enable-apc-sem
13096 + Enable semaphore locks instead of fcntl],
13097 +[
13098 + PHP_APC_SEM=$enableval
13099 + AC_MSG_RESULT($enableval)
13100 +], [
13101 + PHP_APC_SEM=no
13102 + AC_MSG_RESULT(no)
13103 +])
13104 +
13105 +AC_MSG_CHECKING(whether we should use pthread mutex locking)
13106 +AC_ARG_ENABLE(apc-pthreadmutex,
13107 +[ --disable-apc-pthreadmutex
13108 + Disable pthread mutex locking ],
13109 +[
13110 + PHP_APC_PTHREADMUTEX=$enableval
13111 + AC_MSG_RESULT($enableval)
13112 +],
13113 +[
13114 + PHP_APC_PTHREADMUTEX=yes
13115 + AC_MSG_RESULT(yes)
13116 +])
13117 +
13118 +if test "$PHP_APC_PTHREADMUTEX" != "no"; then
13119 + orig_LIBS="$LIBS"
13120 + LIBS="$LIBS -lpthread"
13121 + AC_TRY_RUN(
13122 + [
13123 + #include <sys/types.h>
13124 + #include <pthread.h>
13125 + main() {
13126 + pthread_mutex_t mutex;
13127 + pthread_mutexattr_t attr;
13128 +
13129 + if(pthread_mutexattr_init(&attr)) {
13130 + puts("Unable to initialize pthread attributes (pthread_mutexattr_init).");
13131 + return -1;
13132 + }
13133 + if(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
13134 + puts("Unable to set PTHREAD_PROCESS_SHARED (pthread_mutexattr_setpshared), your system may not support shared mutex's.");
13135 + return -1;
13136 + }
13137 + if(pthread_mutex_init(&mutex, &attr)) {
13138 + puts("Unable to initialize the mutex (pthread_mutex_init).");
13139 + return -1;
13140 + }
13141 + if(pthread_mutexattr_destroy(&attr)) {
13142 + puts("Unable to destroy mutex attributes (pthread_mutexattr_destroy).");
13143 + return -1;
13144 + }
13145 + if(pthread_mutex_destroy(&mutex)) {
13146 + puts("Unable to destroy mutex (pthread_mutex_destroy).");
13147 + return -1;
13148 + }
13149 +
13150 + puts("pthread mutex's are supported!");
13151 + return 0;
13152 + }
13153 + ],
13154 + [ dnl -Success-
13155 + PHP_ADD_LIBRARY(pthread)
13156 + ],
13157 + [ dnl -Failure-
13158 + AC_MSG_WARN([It doesn't appear that pthread mutex's are supported on your system])
13159 + PHP_APC_PTHREADMUTEX=no
13160 + ],
13161 + [
13162 + PHP_ADD_LIBRARY(pthread)
13163 + ]
13164 + )
13165 + LIBS="$orig_LIBS"
13166 +fi
13167 +
13168 +AC_MSG_CHECKING(whether we should use spin locks)
13169 +AC_ARG_ENABLE(apc-spinlocks,
13170 +[ --enable-apc-spinlocks
13171 + Enable spin locks EXPERIMENTAL ],
13172 +[
13173 + PHP_APC_SPINLOCKS=$enableval
13174 + AC_MSG_RESULT($enableval)
13175 +],
13176 +[
13177 + PHP_APC_SPINLOCKS=no
13178 + AC_MSG_RESULT(no)
13179 +])
13180 +
13181 +AC_MSG_CHECKING(whether we should enable memory protection)
13182 +AC_ARG_ENABLE(memory-protection,
13183 +[ --enable-memory-protection
13184 + Enable mmap/shm memory protection],
13185 +[
13186 + PHP_APC_MEMPROTECT=$enableval
13187 + AC_MSG_RESULT($enableval)
13188 +], [
13189 + PHP_APC_MEMPROTECT=no
13190 + AC_MSG_RESULT(no)
13191 +])
13192 +
13193 +if test "$PHP_APC" != "no"; then
13194 + test "$PHP_APC_MMAP" != "no" && AC_DEFINE(APC_MMAP, 1, [ ])
13195 + test "$PHP_APC_FILEHITS" != "no" && AC_DEFINE(APC_FILEHITS, 1, [ ])
13196 +
13197 + if test "$PHP_APC_SEM" != "no"; then
13198 + AC_DEFINE(APC_SEM_LOCKS, 1, [ ])
13199 + elif test "$PHP_APC_SPINLOCKS" != "no"; then
13200 + AC_DEFINE(APC_SPIN_LOCKS, 1, [ ])
13201 + elif test "$PHP_APC_PTHREADMUTEX" != "no"; then
13202 + AC_DEFINE(APC_PTHREADMUTEX_LOCKS, 1, [ ])
13203 + else
13204 + AC_DEFINE(APC_FCNTL_LOCKS, 1, [ ])
13205 + fi
13206 +
13207 + if test "$PHP_APC_MEMPROTECT" != "no"; then
13208 + AC_DEFINE(APC_MEMPROTECT, 1, [ shm/mmap memory protection ])
13209 + fi
13210 +
13211 + AC_CACHE_CHECK(for zend_set_lookup_function_hook, php_cv_zend_set_lookup_function_hook,
13212 + [
13213 + orig_cflags=$CFLAGS
13214 + CFLAGS="$INCLUDES $EXTRA_INCLUDES"
13215 + AC_TRY_COMPILE([
13216 +#include "main/php.h"
13217 +#include "Zend/zend_API.h"
13218 + ], [#ifndef zend_set_lookup_function_hook
13219 + (void) zend_set_lookup_function_hook;
13220 +#endif], [
13221 + php_cv_zend_set_lookup_function_hook=yes
13222 + ],[
13223 + php_cv_zend_set_lookup_function_hook=no
13224 + ])
13225 + CFLAGS=$orig_cflags
13226 + ])
13227 + if test "$php_cv_zend_set_lookup_function_hook" = "yes"; then
13228 + AC_DEFINE(APC_HAVE_LOOKUP_HOOKS, 1, [ ])
13229 + else
13230 + AC_DEFINE(APC_HAVE_LOOKUP_HOOKS, 0, [ ])
13231 + fi
13232 +
13233 + AC_CHECK_FUNCS(sigaction)
13234 + AC_CACHE_CHECK(for union semun, php_cv_semun,
13235 + [
13236 + AC_TRY_COMPILE([
13237 +#include <sys/types.h>
13238 +#include <sys/ipc.h>
13239 +#include <sys/sem.h>
13240 + ], [union semun x; x.val=1], [
13241 + php_cv_semun=yes
13242 + ],[
13243 + php_cv_semun=no
13244 + ])
13245 + ])
13246 + if test "$php_cv_semun" = "yes"; then
13247 + AC_DEFINE(HAVE_SEMUN, 1, [ ])
13248 + else
13249 + AC_DEFINE(HAVE_SEMUN, 0, [ ])
13250 + fi
13251 +
13252 + AC_MSG_CHECKING(whether we should enable valgrind support)
13253 + AC_ARG_ENABLE(valgrind-checks,
13254 + [ --disable-valgrind-checks
13255 + Disable valgrind based memory checks],
13256 + [
13257 + PHP_APC_VALGRIND=$enableval
13258 + AC_MSG_RESULT($enableval)
13259 + ], [
13260 + PHP_APC_VALGRIND=yes
13261 + AC_MSG_RESULT(yes)
13262 + AC_CHECK_HEADER(valgrind/memcheck.h,
13263 + [AC_DEFINE([HAVE_VALGRIND_MEMCHECK_H],1, [enable valgrind memchecks])])
13264 + ])
13265 +
13266 + apc_sources="apc.c php_apc.c \
13267 + apc_cache.c \
13268 + apc_compile.c \
13269 + apc_debug.c \
13270 + apc_fcntl.c \
13271 + apc_main.c \
13272 + apc_mmap.c \
13273 + apc_sem.c \
13274 + apc_shm.c \
13275 + apc_pthreadmutex.c \
13276 + apc_spin.c \
13277 + pgsql_s_lock.c \
13278 + apc_sma.c \
13279 + apc_stack.c \
13280 + apc_zend.c \
13281 + apc_rfc1867.c \
13282 + apc_signal.c \
13283 + apc_pool.c \
13284 + apc_iterator.c \
13285 + apc_bin.c "
13286 +
13287 + PHP_CHECK_LIBRARY(rt, shm_open, [PHP_ADD_LIBRARY(rt,,APC_SHARED_LIBADD)])
13288 + PHP_NEW_EXTENSION(apc, $apc_sources, $ext_shared,, \\$(APC_CFLAGS))
13289 + PHP_SUBST(APC_SHARED_LIBADD)
13290 + PHP_SUBST(APC_CFLAGS)
13291 + AC_DEFINE(HAVE_APC, 1, [ ])
13292 +fi
13293 +
13294 diff -Naur php-5.3.1.orig/ext/apc/config.w32 php-5.3.1/ext/apc/config.w32
13295 --- php-5.3.1.orig/ext/apc/config.w32 1970-01-01 01:00:00.000000000 +0100
13296 +++ php-5.3.1/ext/apc/config.w32 1970-01-01 10:13:08.000000000 +0100
13297 @@ -0,0 +1,27 @@
13298 +// $Id: config.w32 284592 2009-07-22 10:53:50Z kalle $
13299 +// vim:ft=javascript
13300 +
13301 +ARG_ENABLE("apc", "Alternative PHP Cache", "no");
13302 +
13303 +if (PHP_APC != "no") {
13304 + apc_sources="apc.c php_apc.c \
13305 + apc_cache.c \
13306 + apc_compile.c \
13307 + apc_debug.c \
13308 + apc_fcntl_win32.c \
13309 + apc_iterator.c \
13310 + apc_main.c \
13311 + apc_shm.c \
13312 + apc_sma.c \
13313 + apc_stack.c \
13314 + apc_rfc1867.c \
13315 + apc_zend.c \
13316 + apc_pool.c \
13317 + apc_bin.c \
13318 + apc_spin.c \
13319 + pgsql_s_lock.c";
13320 +
13321 + EXTENSION('apc', apc_sources);
13322 + AC_DEFINE('HAVE_APC', 1);
13323 + ADD_FLAG('CFLAGS_APC', "/DAPC_SPIN_LOCKS=1 /DWIN32_ONLY_COMPILER=1");
13324 +}
13325 diff -Naur php-5.3.1.orig/ext/apc/INSTALL php-5.3.1/ext/apc/INSTALL
13326 --- php-5.3.1.orig/ext/apc/INSTALL 1970-01-01 01:00:00.000000000 +0100
13327 +++ php-5.3.1/ext/apc/INSTALL 1970-01-01 10:13:08.000000000 +0100
13328 @@ -0,0 +1,421 @@
13329 +Installation Instructions for APC
13330 +---------------------------------
13331 +
13332 +This version of APC should work on PHP 4.3.0 - 4.4.x and
13333 +5.1.0 - 5.2.x. Yes, that means PHP 5.0.x is no longer
13334 +supported. Upgrade to PHP 5.1.x or 5.2.x and you will
13335 +notice all sorts of performance increases.
13336 +
13337 +CVS Instructions
13338 +----------------
13339 +Building from CVS can be done like this:
13340 +
13341 + cvs -d :pserver:cvsread@cvs.php.net:/repository login
13342 + Password: phpfi
13343 + cvs -d :pserver:cvsread@cvs.php.net:/repository co pecl/apc
13344 + cd pecl/apc
13345 + phpize
13346 + ./configure --enable-apc-mmap --with-apxs --with-php-config=/usr/local/php/bin/php-config
13347 + make
13348 + make install
13349 +
13350 +Suggested Configuration (in your php.ini file)
13351 +----------------------------------------------
13352 + extension=apc.so
13353 + apc.enabled=1
13354 + apc.shm_segments=1
13355 + apc.shm_size=128
13356 + apc.ttl=7200
13357 + apc.user_ttl=7200
13358 + apc.num_files_hint=1024
13359 + apc.mmap_file_mask=/tmp/apc.XXXXXX
13360 + apc.enable_cli=1
13361 +
13362 +These are fully described at the bottom of this file.
13363 +
13364 +PHP 4 Optimization
13365 +------------------
13366 +If you are trying to get every little bit of speed out of PHP4+APC, you need
13367 +to tell APC where to find your httpd.h file and also add -DAPC_PHP4_STAT to
13368 +your CPPFLAGS. (if you don't have httpd.h, install the apache_dev package
13369 +for your OS) and do:
13370 + export CPPFLAGS="-I/usr/include/apache-1.3 -DAPC_PHP4_STAT" (for bash on Debian)
13371 + setenv CPPFLAGS "-I/usr/include/apache-1.3 -DAPC_PHP4_STAT" (for tsch on Debian)
13372 +and then re-run your configure script.
13373 +
13374 +This optimization saves a stat syscall on the main script file. In PHP5 this
13375 +optimization is automatic and doesn't need any special build flags.
13376 +
13377 +The second thing you are going to want to do to save another syscall is to
13378 +compile using the --with-apxs configure switch. This should work for both
13379 +Apache1 and Apache2. Point it directly at your apxs2 script for Apache2.
13380 +eg. --with-apxs=/usr/local/bin/apxs2
13381 +
13382 ++---------------------+
13383 +| QUICK INSTALL (DSO) |
13384 ++---------------------+
13385 +
13386 +These instructions assume your PHP installation is located in /usr/local/php and you
13387 +want Apache optimizations (--with-apxs).
13388 +
13389 +$ gunzip -c apc_x.y.tar.gz | tar xf -
13390 +$ cd apc_x.y
13391 +$ /usr/local/php/bin/phpize
13392 +$ ./configure --enable-apc --enable-apc-mmap --with-apxs --with-php-config=/usr/local/php/bin/php-config
13393 +$ make
13394 +$ make install
13395 +
13396 +You will probably need to run the final command (make install) as root.
13397 +
13398 +The above sequence of commands will install a .so file in your PHP
13399 +installation extension directory. The output of make install should display
13400 +that path to the screen.
13401 +
13402 +Next you must edit your php.ini file, which is normally located in
13403 +/usr/local/php/lib/php.ini, and add the following line:
13404 +
13405 + extension="apc.so"
13406 +
13407 +Replace "/path/to/php/extensions" with whatever path was displayed when you
13408 +ran make install above.
13409 +
13410 +Then restart your web server and consult the output of phpinfo(). If there is
13411 +an informational section for APC, the installation was successful.
13412 +
13413 ++------------------------+
13414 +| QUICK INSTALL (Static) |
13415 ++------------------------+
13416 +
13417 +APC will not successfully compile on all systems as a DSO. If you run into
13418 +problems using the DSO quick install, you can try to compile it statically
13419 +into PHP. (The DSO install is recommended, though.)
13420 +
13421 +These instructions assume the current directory is the root of the PHP source
13422 +tree, and that you have already configured PHP by running its bundled
13423 +configure script.
13424 +
13425 +$ cd ext
13426 +$ gunzip -c apc_x.y.tar.gz | tar xf -
13427 +$ cd ..
13428 +$ ./buildconf
13429 +$ ./config.nice
13430 +$ make
13431 +$ make install
13432 +
13433 +Once this is complete, simply restart your web server. You do not need to
13434 +modify your php.ini file to enable APC.
13435 +
13436 ++-----------------+
13437 +| VERBOSE INSTALL |
13438 ++-----------------+
13439 +
13440 +These instructions assume your PHP installation is located in /usr/local/php.
13441 +
13442 +1. Unpack your distribution file.
13443 +
13444 + You will have downloaded a file named something like apc_x.y.tar.gz.
13445 + Unzip this file with a command like
13446 +
13447 + gunzip apc_x.y.tar.gz
13448 +
13449 + Next you have to untar it with
13450 +
13451 + tar xvf apc_x.y.tar
13452 +
13453 + This will create an apc_x.y directory. cd into this new directory:
13454 +
13455 + cd apc_x.y
13456 +
13457 +2. Run phpize.
13458 +
13459 + phpize is a script that should have been installed with PHP, and is
13460 + normally located in /usr/local/php/bin assuming you installed PHP in
13461 + /usr/local/php. (If you do not have the phpize script, you must reinstall
13462 + PHP and be sure not to disable PEAR.)
13463 +
13464 + Run the phpize command:
13465 +
13466 + /usr/local/php/bin/phpize
13467 +
13468 + Its output should resemble this:
13469 +
13470 + autoheader: `config.h.in' is created
13471 + You should update your `aclocal.m4' by running aclocal.
13472 + Configuring for:
13473 + PHP Api Version: 20020918
13474 + Zend Module Api No: 20020429
13475 + Zend Extension Api No: 20021010
13476 +
13477 + phpize should create a configure script in the current directory. If you
13478 + get errors instead, you might be missing some required development tools,
13479 + such as autoconf or libtool. You can try downloading the latest versions
13480 + of those tools and running phpize again.
13481 +
13482 +3. Run the configure script.
13483 +
13484 + phpize creates a configure script. The only option you need to specify is
13485 + the location of your php-config script:
13486 +
13487 + ./configure --enable-apc
13488 +
13489 + php-config should be located in the same directory as phpize.
13490 +
13491 + If you prefer to use mmap instead of the default IPC shared memory support,
13492 + add --enable-apc-mmap to your configure line.
13493 +
13494 + If you prefer to use sysv IPC semaphores over the safer fcntl() locks, add
13495 + --enable-sem to your configure line. If you don't have a problem
13496 + with your server segaulting, or any other unnatural accumulation of
13497 + semaphores on your system, the semaphore based locking is slightly faster.
13498 +
13499 +4. Compile and install the files. Simply type: make install
13500 +
13501 + (You may need to be root in order to install)
13502 +
13503 + If you encounter errors from libtool or gcc during this step, please
13504 + contact the project maintainer (dcowgill@php.net).
13505 +
13506 +5. Edit your php.ini
13507 +
13508 + make install should have printed a line resembling the following:
13509 +
13510 + Installing shared extensions: /path/to/extension/
13511 +
13512 + Copy the path /path/to/extension/ and add the following line to your
13513 + php.ini file (normally located in /usr/local/php/lib/php.ini):
13514 +
13515 + extension="apc.so"
13516 +
13517 + If you don't have a php.ini file in that location, you can create it now.
13518 +
13519 +6. Restart the web server and test the installation.
13520 +
13521 + Restart your web server now (for apache, it's apachectl restart) and
13522 + create a small test PHP file in your document root. The file should
13523 + contain just the following line:
13524 +
13525 + <?php phpinfo() ?>
13526 +
13527 + Request that file in a web browser. If there is an entry for APC in the
13528 + list of installed modules, the installation was successful.
13529 +
13530 + If APC is not listed, consult your web server error log. If it contains an
13531 + error message saying that it can't load the APC extension, your system
13532 + might not be able to load shared libraries created with PHP's build
13533 + system. One alternative would be to compile APC statically into PHP. See
13534 + the Quick Install (Static) instructions above.
13535 +
13536 + You should consult your error log anyway to see if APC generated any
13537 + errors. On BSD-based platforms, it is typical for APC to be unable to
13538 + allocate the default-sized shared memory segment. See below for hints on
13539 + raising your system's shared memory limitations.
13540 +
13541 ++-----------------+
13542 +| CONFIGURING APC |
13543 ++-----------------+
13544 +
13545 +Although the default APC settings are fine for many installations, serious
13546 +users should consider tuning the following parameters:
13547 +
13548 + OPTION DESCRIPTION
13549 + ------------------ --------------------------------------------------
13550 + apc.enabled This can be set to 0 to disable APC. This is
13551 + primarily useful when APC is statically compiled
13552 + into PHP, since there is no other way to disable
13553 + it (when compiled as a DSO, the zend_extension
13554 + line can just be commented-out).
13555 + (Default: 1)
13556 +
13557 + apc.shm_segments The number of shared memory segments to allocate
13558 + for the compiler cache. If APC is running out of
13559 + shared memory but you have already set
13560 + apc.shm_size as high as your system allows, you
13561 + can try raising this value. Setting this to a
13562 + value other than 1 has no effect in mmap mode
13563 + since mmap'ed shm segments don't have size limits.
13564 + (Default: 1)
13565 +
13566 + apc.shm_size The size of each shared memory segment in MB.
13567 + By default, some systems (including most BSD
13568 + variants) have very low limits on the size of a
13569 + shared memory segment.
13570 + (Default: 30)
13571 +
13572 + apc.optimization This option has been deprecated.
13573 + (Default: 0)
13574 +
13575 + apc.num_files_hint A "hint" about the number of distinct source files
13576 + that will be included or requested on your web
13577 + server. Set to zero or omit if you're not sure;
13578 + this setting is mainly useful for sites that have
13579 + many thousands of source files.
13580 + (Default: 1000)
13581 +
13582 + apc.user_entries_hint Just like num_files_hint, a "hint" about the number
13583 + of distinct user cache variables to store.
13584 + Set to zero or omit if you're not sure;
13585 + (Default: 4096)
13586 +
13587 + apc.ttl The number of seconds a cache entry is allowed to
13588 + idle in a slot in case this cache entry slot is
13589 + needed by another entry. Leaving this at zero
13590 + means that your cache could potentially fill up
13591 + with stale entries while newer entries won't be
13592 + cached.
13593 + (Default: 0)
13594 +
13595 + apc.user_ttl The number of seconds a user cache entry is allowed
13596 + to idle in a slot in case this cache entry slot is
13597 + needed by another entry. Leaving this at zero
13598 + means that your cache could potentially fill up
13599 + with stale entries while newer entries won't be
13600 + cached.
13601 + (Default: 0)
13602 +
13603 +
13604 + apc.gc_ttl The number of seconds that a cache entry may
13605 + remain on the garbage-collection list. This value
13606 + provides a failsafe in the event that a server
13607 + process dies while executing a cached source file;
13608 + if that source file is modified, the memory
13609 + allocated for the old version will not be
13610 + reclaimed until this TTL reached. Set to zero to
13611 + disable this feature.
13612 + (Default: 3600)
13613 +
13614 + apc.cache_by_default On by default, but can be set to off and used in
13615 + conjunction with positive apc.filters so that files
13616 + are only cached if matched by a positive filter.
13617 + (Default: On)
13618 +
13619 + apc.filters A comma-separated list of POSIX extended regular
13620 + expressions. If any pattern matches the source
13621 + filename, the file will not be cached. Note that
13622 + the filename used for matching is the one passed
13623 + to include/require, not the absolute path. If the
13624 + first character of the expression is a + then the
13625 + expression will be additive in the sense that any
13626 + files matched by the expression will be cached, and
13627 + if the first character is a - then anything matched
13628 + will not be cached. The - case is the default, so
13629 + it can be left off.
13630 + (Default: "")
13631 +
13632 + apc.mmap_file_mask If compiled with MMAP support by using --enable-mmap
13633 + this is the mktemp-style file_mask to pass to the
13634 + mmap module for determing whether your mmap'ed memory
13635 + region is going to be file-backed or shared memory
13636 + backed. For straight file-backed mmap, set it to
13637 + something like /tmp/apc.XXXXXX (exactly 6 X's).
13638 + To use POSIX-style shm_open/mmap put a ".shm"
13639 + somewhere in your mask. eg. "/apc.shm.XXXXXX"
13640 + You can also set it to "/dev/zero" to use your
13641 + kernel's /dev/zero interface to anonymous mmap'ed
13642 + memory. Leaving it undefined will force an
13643 + anonymous mmap.
13644 + (Default: "")
13645 +
13646 + apc.slam_defense ** DEPRECATED - Use apc.write_lock instead **
13647 + On very busy servers whenever you start the server or
13648 + modify files you can create a race of many processes
13649 + all trying to cache the same file at the same time.
13650 + This option sets the percentage of processes that will
13651 + skip trying to cache an uncached file. Or think of it
13652 + as the probability of a single process to skip caching.
13653 + For example, setting this to 75 would mean that there is
13654 + a 75% chance that the process will not cache an uncached
13655 + file. So the higher the setting the greater the defense
13656 + against cache slams. Setting this to 0 disables this
13657 + feature.
13658 + (Default: 0)
13659 +
13660 + apc.file_update_protection
13661 + When you modify a file on a live web server you really
13662 + should do so in an atomic manner. That is, write to a
13663 + temporary file and rename (mv) the file into its permanent
13664 + position when it is ready. Many text editors, cp, tar and
13665 + other such programs don't do this. This means that there
13666 + is a chance that a file is accessed (and cached) while it
13667 + is still being written to. This file_update_protection
13668 + setting puts a delay on caching brand new files. The
13669 + default is 2 seconds which means that if the modification
13670 + timestamp (mtime) on a file shows that it is less than 2
13671 + seconds old when it is accessed, it will not be cached.
13672 + The unfortunate person who accessed this half-written file
13673 + will still see weirdness, but at least it won't persist.
13674 + If you are certain you always atomically update your files
13675 + by using something like rsync which does this correctly, you
13676 + can turn this protection off by setting it to 0. If you
13677 + have a system that is flooded with io causing some update
13678 + procedure to take longer than 2 seconds, you may want to
13679 + increase this a bit.
13680 + (Default: 2)
13681 +
13682 + apc.enable_cli Mostly for testing and debugging. Setting this enables APC
13683 + for the CLI version of PHP. Normally you wouldn't want to
13684 + create, populate and tear down the APC cache on every CLI
13685 + request, but for various test scenarios it is handy to be
13686 + able to enable APC for the CLI version of APC easily.
13687 + (Default: 0)
13688 +
13689 + apc.max_file_size Prevents large files from being cached.
13690 + (Default: 1M)
13691 +
13692 + apc.stat Whether to stat the main script file and the fullpath
13693 + includes. If you turn this off you will need to restart
13694 + your server in order to update scripts.
13695 + (Default: 1)
13696 +
13697 + apc.canonicalize Whether to canonicalize paths in stat=0 mode or
13698 + fall back to stat behaviour if set to 0
13699 + (Default: 0)
13700 +
13701 + apc.write_lock On busy servers when you first start up the server, or when
13702 + many files are modified, you can end up with all your processes
13703 + trying to compile and cache the same files. With write_lock
13704 + enabled, only one process at a time will try to compile an
13705 + uncached script while the other processes will run uncached
13706 + instead of sitting around waiting on a lock.
13707 + (Default: 1)
13708 +
13709 + apc.report_autofilter Logs any scripts that were automatically excluded from being
13710 + cached due to early/late binding issues.
13711 + (Default: 0)
13712 +
13713 + apc.rfc1867 RFC1867 File Upload Progress hook handler is only available
13714 + if you compiled APC against PHP 5.2.0 or later. When enabled
13715 + any file uploads which includes a field called
13716 + APC_UPLOAD_PROGRESS before the file field in an upload form
13717 + will cause APC to automatically create an upload_<key>
13718 + user cache entry where <key> is the value of the
13719 + APC_UPLOAD_PROGRESS form entry.
13720 +
13721 + Note that the file upload tracking is not threadsafe at this
13722 + point, so new uploads that happen while a previous one is
13723 + still going will disable the tracking for the previous.
13724 + (Default: 0)
13725 +
13726 + apc.rfc1867_prefix Key prefix to use for the user cache entry generated by
13727 + rfc1867 upload progress functionality.
13728 + (Default: "upload_")
13729 +
13730 + apc.rfc1867_name Specify the hidden form entry name that activates APC upload
13731 + progress and specifies the user cache key suffix.
13732 + (Default: "APC_UPLOAD_PROGRESS")
13733 +
13734 + apc.rfc1867_freq The frequency that updates should be made to the user cache
13735 + entry for upload progress. This can take the form of a
13736 + percentage of the total file size or a size in bytes
13737 + optionally suffixed with 'k', 'm', or 'g' for kilobytes,
13738 + megabytes, or gigabytes respectively (case insensitive).
13739 + A setting of 0 updates as often as possible, which may cause
13740 + slower uploads.
13741 + (Default: 0)
13742 +
13743 + apc.localcache ** REMOVED
13744 + apc.localcache.size ** REMOVED
13745 +
13746 + apc.include_once_override
13747 + Optimize include_once and require_once calls and avoid the
13748 + expensive system calls used.
13749 + (Default: 0)
13750 diff -Naur php-5.3.1.orig/ext/apc/LICENSE php-5.3.1/ext/apc/LICENSE
13751 --- php-5.3.1.orig/ext/apc/LICENSE 1970-01-01 01:00:00.000000000 +0100
13752 +++ php-5.3.1/ext/apc/LICENSE 1970-01-01 10:13:08.000000000 +0100
13753 @@ -0,0 +1,68 @@
13754 +--------------------------------------------------------------------
13755 + The PHP License, version 3.01
13756 +Copyright (c) 1999 - 2006 The PHP Group. All rights reserved.
13757 +--------------------------------------------------------------------
13758 +
13759 +Redistribution and use in source and binary forms, with or without
13760 +modification, is permitted provided that the following conditions
13761 +are met:
13762 +
13763 + 1. Redistributions of source code must retain the above copyright
13764 + notice, this list of conditions and the following disclaimer.
13765 +
13766 + 2. Redistributions in binary form must reproduce the above copyright
13767 + notice, this list of conditions and the following disclaimer in
13768 + the documentation and/or other materials provided with the
13769 + distribution.
13770 +
13771 + 3. The name "PHP" must not be used to endorse or promote products
13772 + derived from this software without prior written permission. For
13773 + written permission, please contact group@php.net.
13774 +
13775 + 4. Products derived from this software may not be called "PHP", nor
13776 + may "PHP" appear in their name, without prior written permission
13777 + from group@php.net. You may indicate that your software works in
13778 + conjunction with PHP by saying "Foo for PHP" instead of calling
13779 + it "PHP Foo" or "phpfoo"
13780 +
13781 + 5. The PHP Group may publish revised and/or new versions of the
13782 + license from time to time. Each version will be given a
13783 + distinguishing version number.
13784 + Once covered code has been published under a particular version
13785 + of the license, you may always continue to use it under the terms
13786 + of that version. You may also choose to use such covered code
13787 + under the terms of any subsequent version of the license
13788 + published by the PHP Group. No one other than the PHP Group has
13789 + the right to modify the terms applicable to covered code created
13790 + under this License.
13791 +
13792 + 6. Redistributions of any form whatsoever must retain the following
13793 + acknowledgment:
13794 + "This product includes PHP software, freely available from
13795 + <http://www.php.net/software/>".
13796 +
13797 +THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
13798 +ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
13799 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
13800 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
13801 +DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
13802 +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13803 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
13804 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13805 +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
13806 +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
13807 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
13808 +OF THE POSSIBILITY OF SUCH DAMAGE.
13809 +
13810 +--------------------------------------------------------------------
13811 +
13812 +This software consists of voluntary contributions made by many
13813 +individuals on behalf of the PHP Group.
13814 +
13815 +The PHP Group can be contacted via Email at group@php.net.
13816 +
13817 +For more information on the PHP Group and the PHP project,
13818 +please see <http://www.php.net>.
13819 +
13820 +PHP includes the Zend Engine, freely available at
13821 +<http://www.zend.com>.
13822 diff -Naur php-5.3.1.orig/ext/apc/NOTICE php-5.3.1/ext/apc/NOTICE
13823 --- php-5.3.1.orig/ext/apc/NOTICE 1970-01-01 01:00:00.000000000 +0100
13824 +++ php-5.3.1/ext/apc/NOTICE 1970-01-01 10:13:08.000000000 +0100
13825 @@ -0,0 +1,43 @@
13826 +This is the NOTICE file that holds acknowledgements and stuff.
13827 +
13828 +The Alternative PHP Cache (APC) is a free and open opcode cache for PHP.
13829 +This extension is being released under the PHP License for complete compliance
13830 +with PHP and to encourage wide-spread use. It is our intention that this
13831 +project be kept open source and that all commercial spin-offs contribute their
13832 +modifications back into the public source-tree.
13833 +
13834 +Creators:
13835 + Daniel Cowgill
13836 + George Schlossnagle
13837 +
13838 +PHP5 support and major features by:
13839 + Arun C. Murthy
13840 + Gopal Vijayaraghavan
13841 + Rasmus Lerdorf
13842 +
13843 +This software was contributed to PHP by Community Connect Inc. in 2002
13844 +and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
13845 +Future revisions and derivatives of this source code must acknowledge
13846 +Community Connect Inc. as the original contributor of this module by
13847 +leaving this note intact in the source code.
13848 +
13849 +All other licensing and usage conditions are those of the PHP Group.
13850 +
13851 +We would like to thank Community Connect Inc. and Yahoo! Inc. for supporting
13852 +this project and providing a challenging and stimulating environment in
13853 +which exciting projects can happen.
13854 +
13855 +Contributors:
13856 + Mike Bretz bug fixes, GUI, and lots of work
13857 + Ricardo Galli changed read-write locks to prefer readers
13858 + Yann Grossel bug fixes
13859 + Thies Arntzen bug fixes
13860 + Sara Golemon optimizer work
13861 +
13862 +Special Thanks:
13863 + Florian Baumert help debugging phplib problems
13864 + Thomas Duffey help debugging inheritance issues
13865 + Vibol Hou help debugging phplib problems
13866 + Angel Li diffs for ANSI comment compliance
13867 + Christian Rishøj help debugging phplib problems
13868 + Sascha Schumann memory error bug fix
13869 diff -Naur php-5.3.1.orig/ext/apc/package.xml php-5.3.1/ext/apc/package.xml
13870 --- php-5.3.1.orig/ext/apc/package.xml 1970-01-01 01:00:00.000000000 +0100
13871 +++ php-5.3.1/ext/apc/package.xml 1970-01-01 10:13:08.000000000 +0100
13872 @@ -0,0 +1,736 @@
13873 +<?xml version="1.0" encoding="UTF-8"?>
13874 +<package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
13875 + <name>APC</name>
13876 + <channel>pecl.php.net</channel>
13877 + <summary>Alternative PHP Cache</summary>
13878 + <description>APC is a free, open, and robust framework for caching and optimizing PHP intermediate code.</description>
13879 + <lead>
13880 + <name>Daniel Cowgill</name>
13881 + <user>dcowgill</user>
13882 + <email>dan@mail.communityconnect.com</email>
13883 + <active>no</active>
13884 + </lead>
13885 + <lead>
13886 + <name>George Schlossnagle</name>
13887 + <user>gschlossnagle</user>
13888 + <email>george@omniti.com</email>
13889 + <active>no</active>
13890 + </lead>
13891 + <lead>
13892 + <name>Rasmus Lerdorf</name>
13893 + <user>rasmus</user>
13894 + <email>rasmus@php.net</email>
13895 + <active>yes</active>
13896 + </lead>
13897 + <lead>
13898 + <name>Gopal Vijayaraghavan</name>
13899 + <user>gopalv</user>
13900 + <email>gopalv@php.net</email>
13901 + <active>yes</active>
13902 + </lead>
13903 + <developer>
13904 + <name>Edin Kadribasic</name>
13905 + <user>edink</user>
13906 + <email>edink@emini.dk</email>
13907 + <active>yes</active>
13908 + </developer>
13909 + <developer>
13910 + <name>Ilia Alshanetsky</name>
13911 + <user>iliaa</user>
13912 + <email>ilia@prohost.org</email>
13913 + <active>yes</active>
13914 + </developer>
13915 + <developer>
13916 + <name>Marcus Börger</name>
13917 + <user>helly</user>
13918 + <email>helly@php.net</email>
13919 + <active>yes</active>
13920 + </developer>
13921 + <developer>
13922 + <name>Sara Golemon</name>
13923 + <user>pollita</user>
13924 + <email>pollita@php.net</email>
13925 + <active>yes</active>
13926 + </developer>
13927 + <developer>
13928 + <name>Brian Shire</name>
13929 + <user>shire</user>
13930 + <email>shire@php.net</email>
13931 + <active>yes</active>
13932 + </developer>
13933 + <date>2009-08-14</date>
13934 + <time>16:30:36</time>
13935 + <version>
13936 + <release>3.1.3p1</release>
13937 + <api>3.1.0</api>
13938 + </version>
13939 + <stability>
13940 + <release>beta</release>
13941 + <api>beta</api>
13942 + </stability>
13943 + <license uri="http://www.php.net/license">PHP License</license>
13944 + <notes>
13945 +- fix pecl build / package.xml (Gopal)
13946 + </notes>
13947 + <contents>
13948 + <dir name="/">
13949 + <file md5sum="841596cff3b9bd83e79d01ccb591ff55" name="tests/apc_001.phpt" role="test" />
13950 + <file md5sum="cc1dba4e429ff93dce1ca7dea01c2899" name="tests/apc_002.phpt" role="test" />
13951 + <file md5sum="04c800594e9934cf8e15157e9bd4c52f" name="tests/apc_003.phpt" role="test" />
13952 + <file md5sum="538f198f432614d9f2c0819fea5193a7" name="tests/apc_003b.phpt" role="test" />
13953 + <file md5sum="43c8e1c89fad5bb25ded528837e63b2b" name="tests/apc_004.phpt" role="test" />
13954 + <file md5sum="06432141cbc82df8ddde7fac52e9f65e" name="tests/apc_005.phpt" role="test" />
13955 + <file md5sum="74f802b99f111d1cdab6abaf20edae95" name="tests/apc_006.phpt" role="test" />
13956 + <file md5sum="b724592cd9629ab5e9dac9f1ef5d3e10" name="tests/apc_007.phpt" role="test" />
13957 + <file md5sum="0674cbe2e88fe5c331bee3fbb1395d4f" name="tests/apc_008.phpt" role="test" />
13958 + <file md5sum="4092ea60d4ff7bfdcbcc5795c06e60e7" name="tests/apc_009.phpt" role="test" />
13959 + <file md5sum="6640964ee33a683b1693b545d1ff2ed0" name="tests/apc_010.phpt" role="test" />
13960 + <file md5sum="611e5e725d57fcca216bf79778238290" name="tests/apc53_001.phpt" role="test" />
13961 + <file md5sum="1cd474d5a3567601d66d1078699fd587" name="tests/apc53_002.phpt" role="test" />
13962 + <file md5sum="3d863bb88c5f2624320b7b72e368d668" name="tests/apc53_003.phpt" role="test" />
13963 + <file md5sum="128e9590ff8d3d0791a1ef9ce9c078f5" name="tests/apc53_004.phpt" role="test" />
13964 + <file md5sum="c710a33310dfacef4d51cb721855857e" name="tests/apc53_005.phpt" role="test" />
13965 + <file md5sum="4b7dc1553dadcb3378d33e069387e35c" name="tests/apc_bin_001.phpt" role="test" />
13966 + <file md5sum="c992d44557b849a10984b089419d2e01" name="tests/apc_bin_002-1.inc" role="test" />
13967 + <file md5sum="409cadd9efc9d863421b15d63d8c6515" name="tests/apc_bin_002-2.inc" role="test" />
13968 + <file md5sum="2667d74094dac9e366020c11b3a9bd47" name="tests/apc_bin_002.phpt" role="test" />
13969 + <file md5sum="1bb542e50a5e6eb06b54a89ceaa81976" name="tests/iterator_001.phpt" role="test" />
13970 + <file md5sum="7ee077f992cd81940f74b5f1b0e885c0" name="tests/iterator_002.phpt" role="test" />
13971 + <file md5sum="eccbaee4d483213ee8ba0583c705224b" name="tests/iterator_003.phpt" role="test" />
13972 + <file md5sum="4ec172b4fc8ed2f45f3d7426865a0db5" name="tests/iterator_004.phpt" role="test" />
13973 + <file md5sum="eec4bf6bdfa4936cb122845216cad7e0" name="tests/iterator_005.phpt" role="test" />
13974 + <file md5sum="3206db85017077ed498fd9d5ac7585e7" name="tests/iterator_006.phpt" role="test" />
13975 + <file md5sum="82a40b37c545631cd87c3e1e421353b5" name="tests/iterator_007.phpt" role="test" />
13976 + <file md5sum="92e7b033fac8b625c6ad52e21d1222bf" name="tests/php_5_3_ns.inc" role="test" />
13977 + <file md5sum="6ecba4154b6bd6f8703000f5198710cc" name="tests/skipif.inc" role="test" />
13978 + <file md5sum="ed9a4192d7ab7f953856b92c5e689cf5" name="CHANGELOG" role="doc" />
13979 + <file md5sum="f5ca8db7fde5fb83ab79b509279b9856" name="INSTALL" role="doc" />
13980 + <file md5sum="694f49a7e1f276ba75a3dd2c5acd580d" name="LICENSE" role="doc" />
13981 + <file md5sum="eea150699d3dffb2cdf7d243854189d7" name="NOTICE" role="doc" />
13982 + <file md5sum="efa40416571fc54aa59912203c0391e6" name="TODO" role="doc" />
13983 + <file md5sum="b7dd14328e218d3ecc97d85fb83d7ba7" name="TECHNOTES.txt" role="doc" />
13984 + <file md5sum="e7fdf1aa7be78296ac3baf23654b2792" name="apc.c" role="src" />
13985 + <file md5sum="09a525ff9a3850e6de42eee2adf07463" name="apc.dsp" role="src" />
13986 + <file md5sum="b82f7ac9d62387e674ce33a67afc7a3b" name="apc.h" role="src" />
13987 + <file md5sum="849d4591945e68babb4efb03e3d424ae" name="apc_bin.c" role="src" />
13988 + <file md5sum="dcaf89f1b2266c5c41a0ab19785bee7d" name="apc_bin.h" role="src" />
13989 + <file md5sum="8121a318b3008f743d8bed06dec9f729" name="apc_cache.c" role="src" />
13990 + <file md5sum="9b419e40230069357142c22eab50bc0a" name="apc_cache.h" role="src" />
13991 + <file md5sum="29385884afc3dbd6b3c85fe224e2a365" name="apc_compile.c" role="src" />
13992 + <file md5sum="12cb41077d90d258aa7eb59b834ef261" name="apc_compile.h" role="src" />
13993 + <file md5sum="c2f45f382269e062291f4a1972891a95" name="apc_debug.c" role="src" />
13994 + <file md5sum="46d182a6122f3c29a1904f62af7cfb51" name="apc_debug.h" role="src" />
13995 + <file md5sum="3bd799be126de9a5b701de001c9fdc8d" name="apc_fcntl.c" role="src" />
13996 + <file md5sum="396db63ae5ac6622826cdd6ea0a0f4e5" name="apc_fcntl.h" role="src" />
13997 + <file md5sum="d474fc330719125798f1cc8893418fea" name="apc_globals.h" role="src" />
13998 + <file md5sum="681d7c13200e8c63e06a72c29d0d83f5" name="apc_lock.h" role="src" />
13999 + <file md5sum="4c36bea0b58da92e574d3788a091cdcd" name="apc_main.c" role="src" />
14000 + <file md5sum="4ff2542ab8b12f8bce6d0c71f2a4ffb7" name="apc_main.h" role="src" />
14001 + <file md5sum="a1128f11e4db3dae87640595180c7e76" name="apc_mmap.c" role="src" />
14002 + <file md5sum="8a27408dbf63cf115d2845d73c1100c3" name="apc_mmap.h" role="src" />
14003 + <file md5sum="0226513b1cd48f3004f01ad2a24c7a90" name="apc_php.h" role="src" />
14004 + <file md5sum="247b2ed6b2c9f5064a9352a84a675034" name="apc_pthreadmutex.c" role="src" />
14005 + <file md5sum="ce3c8071287af9608a70a201bc149e42" name="apc_pthreadmutex.h" role="src" />
14006 + <file md5sum="8364571d83c9304ddd63bab54ef59f0e" name="apc_sem.c" role="src" />
14007 + <file md5sum="85d68fac7619e136c5dd2dba7498cebe" name="apc_sem.h" role="src" />
14008 + <file md5sum="874b69fe7572b47ca0c427213a24a004" name="apc_shm.c" role="src" />
14009 + <file md5sum="adcbe11cf10939218758cea6155571b5" name="apc_shm.h" role="src" />
14010 + <file md5sum="55788ceff1d153856173e9cb1be30af5" name="apc_sma.c" role="src" />
14011 + <file md5sum="7b915d4e05f034544794c0a22aca28df" name="apc_sma.h" role="src" />
14012 + <file md5sum="3651ead82ae249829bdfbd247845023a" name="apc_spin.c" role="src" />
14013 + <file md5sum="39b7125d52a30ad45f467f897a4f49fd" name="apc_spin.h" role="src" />
14014 + <file md5sum="bac2bf4975f8d178509c35687aacf264" name="apc_stack.c" role="src" />
14015 + <file md5sum="769e2610340545503843be5d27338bc0" name="apc_stack.h" role="src" />
14016 + <file md5sum="e06026d546096ccfd153f7ce282ec3d3" name="apc_zend.c" role="src" />
14017 + <file md5sum="d23c3716dc2be32d93583bdf2ee67fc5" name="apc_zend.h" role="src" />
14018 + <file md5sum="43c72ad19c9b3c2b7107ac38ac890b9c" name="apc_signal.c" role="src" />
14019 + <file md5sum="a93d49b7187c228033a0e6c906c660a9" name="apc_signal.h" role="src" />
14020 + <file md5sum="10bc3c48bf67d1f19d590d8aef62096f" name="apc_iterator.c" role="src" />
14021 + <file md5sum="fa2801d6755aca597222263a5c327c17" name="apc_iterator.h" role="src" />
14022 + <file md5sum="2985b114a6c62d4c645da54e15362133" name="apc_pool.c" role="src" />
14023 + <file md5sum="d33cf9a06d75796db5d2d6d05ce69cb2" name="apc_pool.h" role="src" />
14024 + <file md5sum="4825b1162664c350544045d54dc88e26" name="config.m4" role="src" />
14025 + <file md5sum="f8892e31c76167187d69df7870ad4510" name="config.w32" role="src" />
14026 + <file md5sum="36e70be4ad90d876f34743323da54a94" name="php_apc.c" role="src" />
14027 + <file md5sum="b6fdcec040076e3895b885a87ca6315c" name="php_apc.h" role="src" />
14028 + <file md5sum="5f6b362f9d82a1c71f19ad1516935b03" name="pgsql_s_lock.c" role="src" />
14029 + <file md5sum="a8fb99edbfe1118664ffceb868fc4756" name="pgsql_s_lock.h" role="src" />
14030 + <file md5sum="56e973e39dd83277cd2dc091115dd06d" name="apc_fcntl_win32.c" role="src" />
14031 + <file md5sum="71dc597b764f4e6ea12253d50e2167d5" name="apc_rfc1867.c" role="src" />
14032 + <file md5sum="6022f9c20f05b1ce3524c1bd5b87f8db" name="apc.php" role="php" />
14033 + </dir>
14034 + </contents>
14035 + <dependencies>
14036 + <required>
14037 + <php>
14038 + <min>5.1.0</min>
14039 + </php>
14040 + <pearinstaller>
14041 + <min>1.4.0</min>
14042 + </pearinstaller>
14043 + </required>
14044 + </dependencies>
14045 + <providesextension>apc</providesextension>
14046 + <extsrcrelease>
14047 + <configureoption default="no" name="enable-apc-filehits" prompt="Enable per request file info about files used from the APC cache" />
14048 + <configureoption default="no" name="enable-apc-spinlocks" prompt="Enable spin locks (EXPERIMENTAL)" />
14049 + </extsrcrelease>
14050 + <changelog>
14051 + <release>
14052 + <stability>
14053 + <release>stable</release>
14054 + <api>stable</api>
14055 + </stability>
14056 + <version>
14057 + <release>2.0.0</release>
14058 + <api>2.0.0</api>
14059 + </version>
14060 + <date>2003-07-01</date>
14061 + <notes>
14062 +Complete rework.
14063 + </notes>
14064 + </release>
14065 + <release>
14066 + <stability>
14067 + <release>stable</release>
14068 + <api>stable</api>
14069 + </stability>
14070 + <version>
14071 + <release>2.0.1</release>
14072 + <api>2.0.0</api>
14073 + </version>
14074 + <date>2003-07-01</date>
14075 + <notes>
14076 +Win32 support added.
14077 + </notes>
14078 + </release>
14079 + <release>
14080 + <stability>
14081 + <release>stable</release>
14082 + <api>stable</api>
14083 + </stability>
14084 + <version>
14085 + <release>2.0.2</release>
14086 + <api>2.0.0</api>
14087 + </version>
14088 + <date>2004-03-12</date>
14089 + <notes>
14090 +Fixed non-existant class bug.
14091 + </notes>
14092 + </release>
14093 + <release>
14094 + <stability>
14095 + <release>stable</release>
14096 + <api>stable</api>
14097 + </stability>
14098 + <version>
14099 + <release>3.0.0</release>
14100 + <api>3.0.0</api>
14101 + </version>
14102 + <date>2005-07-05</date>
14103 + <notes>
14104 +PHP-5.1 Support and numerous fixes
14105 + </notes>
14106 + </release>
14107 + <release>
14108 + <stability>
14109 + <release>stable</release>
14110 + <api>stable</api>
14111 + </stability>
14112 + <version>
14113 + <release>3.0.1</release>
14114 + <api>3.0.0</api>
14115 + </version>
14116 + <date>2005-07-05</date>
14117 + <notes>
14118 +PHP4 build fix
14119 + </notes>
14120 + </release>
14121 + <release>
14122 + <stability>
14123 + <release>stable</release>
14124 + <api>stable</api>
14125 + </stability>
14126 + <version>
14127 + <release>3.0.2</release>
14128 + <api>3.0.0</api>
14129 + </version>
14130 + <date>2005-07-05</date>
14131 + <notes>
14132 +Default to mmap and add a better error message for shmget failures
14133 + </notes>
14134 + </release>
14135 + <release>
14136 + <stability>
14137 + <release>stable</release>
14138 + <api>stable</api>
14139 + </stability>
14140 + <version>
14141 + <release>3.0.3</release>
14142 + <api>3.0.0</api>
14143 + </version>
14144 + <date>2005-07-07</date>
14145 + <notes>
14146 +Fix compile problem against PHP 5.0.x
14147 + </notes>
14148 + </release>
14149 + <release>
14150 + <stability>
14151 + <release>stable</release>
14152 + <api>stable</api>
14153 + </stability>
14154 + <version>
14155 + <release>3.0.4</release>
14156 + <api>3.0.0</api>
14157 + </version>
14158 + <date>2005-07-18</date>
14159 + <notes>
14160 +Add win32 support from Edin.
14161 +Add --with-apxs switch to work around problem when loading APC into Apache binary compiled with LFS switches
14162 +A couple of other minor fixes.
14163 + </notes>
14164 + </release>
14165 + <release>
14166 + <stability>
14167 + <release>stable</release>
14168 + <api>stable</api>
14169 + </stability>
14170 + <version>
14171 + <release>3.0.5</release>
14172 + <api>3.0.0</api>
14173 + </version>
14174 + <date>2005-07-27</date>
14175 + <notes>
14176 +Make it easier for sapis that only populate file_handle-&gt;filename to use APC. (Rasmus)
14177 +Support extensions such as bcompiler that need to hook into compile_file. (Val)
14178 +Ralf Becker&apos;s apcgui code has now become the default apc.php status page. (Ralf, Rasmus, Ilia)
14179 +Segfault in cache cleanup code (Ilia, Rasmus)
14180 + </notes>
14181 + </release>
14182 + <release>
14183 + <stability>
14184 + <release>stable</release>
14185 + <api>stable</api>
14186 + </stability>
14187 + <version>
14188 + <release>3.0.6</release>
14189 + <api>3.0.0</api>
14190 + </version>
14191 + <date>2005-07-30</date>
14192 + <notes>
14193 +Added apc.php to package.xml file.
14194 +Track per-entry memory usage. (Val)
14195 +Various apc.php fixes and enhancements. (Ralf, Ilia, Rasmus)
14196 +fcntl locking robustness fixes. (Rasmus)
14197 +Shared read-locks where possible. (Rasmus)
14198 +Added file_update_protection configuration parameter. (Rasmus)
14199 +Windows ZTS fixes (Frank)
14200 + </notes>
14201 + </release>
14202 + <release>
14203 + <stability>
14204 + <release>stable</release>
14205 + <api>stable</api>
14206 + </stability>
14207 + <version>
14208 + <release>3.0.7</release>
14209 + <api>3.0.0</api>
14210 + </version>
14211 + <date>2005-08-16</date>
14212 + <notes>
14213 +Fix to apc.php to show final segment in frag chart. (Ilia)
14214 +A couple of win32 fixes. (Frank)
14215 +Add apc.enable_cli ini directive. (Rasmus)
14216 +Add test cases. (Marcus)
14217 +Fix apc_define_constants() bug - http://pecl.php.net/bugs/5084 (Rasmus)
14218 +Simplify user cache handling by removing the user_cache_stack (Rasmus)
14219 +Fix apc_fetch() memory corruption (Andrei,Rasmus)
14220 +Added apc.max_file_size INI setting that allows exclusion of large files from being cached. Default file size limit, 1 megabyte. (Ilia)
14221 + </notes>
14222 + </release>
14223 + <release>
14224 + <stability>
14225 + <release>stable</release>
14226 + <api>stable</api>
14227 + </stability>
14228 + <version>
14229 + <release>3.0.8</release>
14230 + <api>3.0.0</api>
14231 + </version>
14232 + <date>2005-08-24</date>
14233 + <notes>
14234 +Fix invalid free in globals destructor introduced in 3.0.7 (Rasmus)
14235 +Cache corruption fix in cache-full cleanup code (Gopal)
14236 + </notes>
14237 + </release>
14238 + <release>
14239 + <stability>
14240 + <release>stable</release>
14241 + <api>stable</api>
14242 + </stability>
14243 + <version>
14244 + <release>3.0.9</release>
14245 + <api>3.0.0</api>
14246 + </version>
14247 + <date>2006-03-04</date>
14248 + <notes>
14249 +Eliminate rand() call when slam_defense is not set (Rasmus)
14250 +Fix for __isset problem (Gopal)
14251 +Rewrite allocator from a &quot;best fit&quot; to a &quot;next fit&quot; algorithm (Rasmus)
14252 +Added a Cache Full counter so we have an idea how many times the segment has filled up causing an expunge (Rasmus)
14253 +Report back the correct number of available bytes in the segment instead of the allocated bytes. (Rasmus)
14254 +Add cache busy flag which is set when an expunge is underway (Rasmus)
14255 +Add automatic serialization of objects in apc_store() (Marcus)
14256 +64-bit .ini flag fix (Rasmus)
14257 +Static members fix (Gopal)
14258 +sma_cleanup() mem leak fix (Rasmus)
14259 +Fix for http://pecl.php.net/bugs/5311 (Rasmus)
14260 +Fix autoglobals JIT bug (Gopal)
14261 +Fix instance bug (Gopal)
14262 +Add a lock cleanup safety net to request shutdown (Rasmus)
14263 +Fix apc.slam_defense edge-case bug (Rasmus)
14264 +User entry memory usage tracking support (Ilia)
14265 +Allow keys used in apc_store/apc_fetch/apc_delete to be binary safe and prevent conflicts between keys that are found at the start of other keys. (Ilia)
14266 + </notes>
14267 + </release>
14268 + <release>
14269 + <stability>
14270 + <release>stable</release>
14271 + <api>stable</api>
14272 + </stability>
14273 + <version>
14274 + <release>3.0.10</release>
14275 + <api>3.0.0</api>
14276 + </version>
14277 + <date>2006-03-11</date>
14278 + <notes>
14279 +* Add apc.stat ini flag which defaults to 1. If set to 0, the main script and any fullpath
14280 + includes will not be stat&apos;ed for any changes. You will have to restart the server if you
14281 + change anything. This mode increases performance quite a bit, especially if you have a
14282 + lot of includes.
14283 +
14284 +* Get rid of the lock safety net hack I added in 3.0.9. It seems to cause more problems
14285 + than it solves. I&apos;ll need to revisit locking and signal handling at some point soon.
14286 + </notes>
14287 + </release>
14288 + <release>
14289 + <stability>
14290 + <release>stable</release>
14291 + <api>stable</api>
14292 + </stability>
14293 + <version>
14294 + <release>3.0.11</release>
14295 + <api>3.0.0</api>
14296 + </version>
14297 + <date>2006-08-16</date>
14298 + <notes>
14299 +* Made --enable-apc-mmap the default compile option (for real this time)
14300 +
14301 +* Add an optional flag to apc_cache_info() and some apc.php tweaks to make it
14302 + only fetch header information to make it useful when you have tens of
14303 + thousands of entries. (Brian Shire)
14304 +
14305 +* 64-bit fixes (George)
14306 +
14307 +* Don&apos;t mix Full Path and Inode keys (George)
14308 +
14309 +* Override ZEND_INCLUDE_OR_EVAL opcode (when possible) to speed up use of
14310 + require_once() and include_once() statements. (Sara)
14311 +
14312 +* Add a non-blocking write_lock for cache inserts. This is a better approach
14313 + to prevent cache slams and deprecates the slam_defense setting. (Rasmus)
14314 +
14315 +* A bit of work on the optimizer. (Sara)
14316 +
14317 +* Various memory issues resolved. (Gopal)
14318 + </notes>
14319 + </release>
14320 + <release>
14321 + <stability>
14322 + <release>stable</release>
14323 + <api>stable</api>
14324 + </stability>
14325 + <version>
14326 + <release>3.0.12</release>
14327 + <api>3.0.0</api>
14328 + </version>
14329 + <date>2006-09-04</date>
14330 + <notes>
14331 +* Fix stray debug message
14332 +
14333 +* Work on the optimizer - still not stable (Gopal, Ilia, Sara)
14334 +
14335 +* Performance boost - Replace multiple loops over the opcode
14336 + array with a single loop for copying, jump fixups and auto
14337 + global pre-fetches. (Gopal)
14338 +
14339 +* Perform fetch_global checks only in php5 and only if
14340 + auto_globals_jit is enabled. (Gopal)
14341 +
14342 +* Fix bug #8579 - scrub php4 classes&apos; function_table and default
14343 + properties before inserting into cache. (Gopal)
14344 +
14345 +* Fix bug #8606 - ZEND_FETCH_GLOBAL is not an opcode, but is a
14346 + op1-&gt;type. The opcodes applicable are ZEND_FETCH_R and
14347 + ZEND_FETCH_W. (Gopal)
14348 +
14349 +* PHP 5.2 Compatibility (Gopal)
14350 +
14351 +* Make the include_once override optional - default off (Sara)
14352 +
14353 +* Fixed crash when apc run in CLI, but enable_cli is off. (Ilia)
14354 +
14355 +* Ensure that the apc_globals-&gt;cache_stack is cleared before the
14356 + shm cache is destroyed. Fixes segfault for corner-case i.e request
14357 + shutdown (apc_deactivate) is not called before module shutdown
14358 + calls (php_apc_shutdown_globals) (Gopal)
14359 +
14360 +* TSRM fixes (ensure ts_free_id before apc.so is dlclosed) (Gopal)
14361 +
14362 +* Fix memory leak of apc_cache_info_t-&gt;deleted_list (Gopal)
14363 + </notes>
14364 + </release>
14365 + <release>
14366 + <stability>
14367 + <release>stable</release>
14368 + <api>stable</api>
14369 + </stability>
14370 + <version>
14371 + <release>3.0.12p1</release>
14372 + <api>3.0.0</api>
14373 + </version>
14374 + <date>2006-09-05</date>
14375 + <notes>
14376 +* The only change here is a trivial PHP 4 build fix.
14377 + </notes>
14378 + </release>
14379 + <release>
14380 + <stability>
14381 + <release>stable</release>
14382 + <api>stable</api>
14383 + </stability>
14384 + <version>
14385 + <release>3.0.12p2</release>
14386 + <api>3.0.0</api>
14387 + </version>
14388 + <date>2006-09-05</date>
14389 + <notes>
14390 +* Let&apos;s get the version number right. 3.0.12p2 now.
14391 + </notes>
14392 + </release>
14393 + <release>
14394 + <stability>
14395 + <release>stable</release>
14396 + <api>stable</api>
14397 + </stability>
14398 + <version>
14399 + <release>3.0.13</release>
14400 + <api>3.0.0</api>
14401 + </version>
14402 + <date>2007-02-24</date>
14403 + <notes>
14404 +* PHP 5.2 file upload progress tracking support (Rasmus)
14405 +* Pthread mutex and spin locks (Shire)
14406 +* Recursive zval support for apc_fetch/_store (Shire, Gopal)
14407 +* apc.stat_ctime flag for ctime checks (Rasmus)
14408 +* Multiple key fetches with apc_fetch (Shire)
14409 +* Canary checks for shm memory deallocation (Gopal)
14410 +* Add hooks for external optimizer (Shire)
14411 +* Obsolete and remove apc optimizer (Gopal)
14412 +* APC info changes - cache insert rate, hit and miss rates (Shire)
14413 +* Fix apc_load_constants (Gopal)
14414 +* Rewrite dump opcode code to use vld (Gopal)
14415 +* Use apc_[ewn]print functions for error reporting (Shire)
14416 +* Auto global fixes and refactoring (Gopal, Shire)
14417 +* Fix memory leaks in object serialization (Ilia)
14418 +* Memory cleanup code for destructor order (Gopal)
14419 +* Win32 build fixes (Ilia, Wez)
14420 +* ZTS and Php 4 build fixes (Bjori)
14421 +* Add apc_add() function (Rasmus)
14422 +* Add optional limited flag to apc_sma_info() (Rasmus)
14423 + </notes>
14424 + </release>
14425 + <release>
14426 + <stability>
14427 + <release>stable</release>
14428 + <api>stable</api>
14429 + </stability>
14430 + <version>
14431 + <release>3.0.14</release>
14432 + <api>3.0.0</api>
14433 + </version>
14434 + <date>2007-04-02</date>
14435 + <notes>
14436 +* Build fix (Shire)
14437 +* Don&apos;t hook the upload hook if APC is disabled (Rasmus)
14438 +* Local shadow cache support (Gopal)
14439 +* Avoid uneccessary loops over op_arrays for &quot;known&quot; auto-globals (Gopal)
14440 +* Fix apc_add() to overwrite timed out user entries (Rasmus)
14441 +* Fix double inclusion of files with conditional classes in php4 (Gopal)
14442 +* Allocator fixes to reduce fragmentation (Gopal)
14443 + </notes>
14444 + </release>
14445 + <release>
14446 + <stability>
14447 + <release>stable</release>
14448 + <api>stable</api>
14449 + </stability>
14450 + <version>
14451 + <release>3.0.15</release>
14452 + <api>3.0.0</api>
14453 + </version>
14454 + <date>2007-10-18</date>
14455 + <notes>
14456 +* Eliminate a per-request time() syscall (Rasmus)
14457 +* Added rfc1867 prefix, name, and freq ini options (Shire)
14458 +* Allow deletion of individual user cache entries via apc.php (Sara)
14459 +* Fix overzealous cleanup during RSHUTDOWN (Gopal)
14460 +* Fix memory alignment and locking issues (Gopal)
14461 +* Make apc_compile insert/replace entries (Shire)
14462 +* Make mixed inheritance recompile &amp; cache afresh (Gopal)
14463 +* Make nostat mode search include_path for canonicalization (Gopal)
14464 +* ZTS &amp; other compile fixes (Gopal, Edin, Shire)
14465 + </notes>
14466 + </release>
14467 + <release>
14468 + <version>
14469 + <release>3.0.16</release>
14470 + <api>3.0.0</api>
14471 + </version>
14472 + <stability>
14473 + <release>stable</release>
14474 + <api>stable</api>
14475 + </stability>
14476 + <license uri="http://www.php.net/license">PHP License</license>
14477 + <date>2008-03-26</date>
14478 + <notes>
14479 +* Fix for longstanding cache-full crash (Christian Seiler)
14480 + http://news.php.net/php.pecl.dev/4951 for the details
14481 +* Added optional shm unmap on a fatal signal feature (Lucas Nealan)
14482 +* Added PTHREAD_MUTEX_ADAPTIVE_NP option pthread locks (Paul Saab)
14483 +* Minor cleanups (Lucas Nealan)
14484 +* Added configure option to enable apc_cache_info(&apos;filehits&apos;) (Shire)
14485 + </notes>
14486 + </release>
14487 + <release>
14488 + <version>
14489 + <release>3.0.17</release>
14490 + <api>3.0.0</api>
14491 + </version>
14492 + <stability>
14493 + <release>stable</release>
14494 + <api>stable</api>
14495 + </stability>
14496 + <license uri="http://www.php.net/license">PHP License</license>
14497 + <date>2008-03-29</date>
14498 + <notes>
14499 +* Crash fixes
14500 +* Fix apc_add() cache expunge bug (Rasmus)
14501 +* Added parameter to apc_fetch to determine success/failure when fetching booleans (shire)
14502 +* Fix misc. memleaks (shire)
14503 + </notes>
14504 + </release>
14505 + <release>
14506 + <version>
14507 + <release>3.0.18</release>
14508 + <api>3.0.0</api>
14509 + </version>
14510 + <stability>
14511 + <release>stable</release>
14512 + <api>stable</api>
14513 + </stability>
14514 + <license uri="http://www.php.net/license">PHP License</license>
14515 + <date>2008-03-29</date>
14516 + <notes>
14517 +- Revert apc_expunge_cb bug-fix
14518 +- Misc memleaks
14519 + </notes>
14520 + </release>
14521 + <release>
14522 + <version>
14523 + <release>3.0.19</release>
14524 + <api>3.0.0</api>
14525 + </version>
14526 + <stability>
14527 + <release>stable</release>
14528 + <api>stable</api>
14529 + </stability>
14530 + <license uri="http://www.php.net/license">PHP License</license>
14531 + <date>2008-05-15</date>
14532 + <notes>
14533 +- Safe-mode and fast-cgi fixes
14534 +- Fix double-free of builtin_functions
14535 +- php 5.3 fixes
14536 + </notes>
14537 + </release>
14538 + <release>
14539 + <version>
14540 + <release>3.1.1</release>
14541 + <api>3.1.0</api>
14542 + </version>
14543 + <stability>
14544 + <release>beta</release>
14545 + <api>beta</api>
14546 + </stability>
14547 + <license uri="http://www.php.net/license">PHP License</license>
14548 + <date>2008-12-12</date>
14549 + <notes>
14550 +- PHP4 compatibilty break
14551 +- apc_pool allocator (Gopal)
14552 +- doubly-linked sma allocator (Shire)
14553 +- php 5.3 gc compatibility (Gopal)
14554 +- APCIterator for easy access (Shire)
14555 +- apc_delete_file (Shire)
14556 +- apc_inc/apc_dec/apc_cas functions (Shire)
14557 +- apc.canonicalize (Gopal)
14558 +- apc.preload_path (Gopal)
14559 +- apc.rfc1867_ttl (Shire)
14560 +- apc.file_md5 (Shire)
14561 +- consolidate locking macros (Shire)
14562 +- remove futex/TSRM locks (Shire)
14563 +- non-blocking semaphore locks (Shire)
14564 +- zval* object rework (Gopal)
14565 + </notes>
14566 + </release>
14567 + <release>
14568 + <version>
14569 + <release>3.1.2</release>
14570 + <api>3.1.0</api>
14571 + </version>
14572 + <stability>
14573 + <release>beta</release>
14574 + <api>beta</api>
14575 + </stability>
14576 + <license uri="http://www.php.net/license">PHP License</license>
14577 + <date>2008-12-12</date>
14578 + <notes>
14579 +- pecl package.xml/build fixes (bjori)
14580 + </notes>
14581 + </release>
14582 + <release>
14583 + <version>
14584 + <release>3.1.3</release>
14585 + <api>3.1.0</api>
14586 + </version>
14587 + <stability>
14588 + <release>beta</release>
14589 + <api>beta</api>
14590 + </stability>
14591 + <license uri="http://www.php.net/license">PHP License</license>
14592 + <date>2009-08-13</date>
14593 + <notes>
14594 +- pecl package.xml/build fixes (bjori)
14595 +- 5.3 support + test-cases (Gopal)
14596 +- Lazy loading support (Shire)
14597 +- Fix PCRE module init order issues (Shire)
14598 +- APCIterator fixes (Shire)
14599 +- Cache slam checks (Gopal)
14600 +- ZEND_JMP_SET support (Shire)
14601 +- apc.use_request_time option (shire)
14602 +- apc.php hostname fixes (Shire)
14603 +- memprotect framework (Gopal)
14604 +- Win32 build-fixes (Kalle)
14605 + </notes>
14606 + </release>
14607 + </changelog>
14608 +</package>
14609 diff -Naur php-5.3.1.orig/ext/apc/pgsql_s_lock.c php-5.3.1/ext/apc/pgsql_s_lock.c
14610 --- php-5.3.1.orig/ext/apc/pgsql_s_lock.c 1970-01-01 01:00:00.000000000 +0100
14611 +++ php-5.3.1/ext/apc/pgsql_s_lock.c 1970-01-01 10:13:08.000000000 +0100
14612 @@ -0,0 +1,485 @@
14613 +/*
14614 + +----------------------------------------------------------------------+
14615 + | APC |
14616 + +----------------------------------------------------------------------+
14617 + | Copyright (c) 2007-2008 The PHP Group |
14618 + +----------------------------------------------------------------------+
14619 + | This source file is subject to version 3.01 of the PHP license, |
14620 + | that is bundled with this package in the file LICENSE, and is |
14621 + | available through the world-wide-web at the following url: |
14622 + | http://www.php.net/license/3_01.txt |
14623 + | If you did not receive a copy of the PHP license and are unable to |
14624 + | obtain it through the world-wide-web, please send a note to |
14625 + | license@php.net so we can mail you a copy immediately. |
14626 + +----------------------------------------------------------------------+
14627 + | The following code was ported from the PostgreSQL project, please |
14628 + | see appropriate copyright notices that follow. |
14629 + | Initial conversion by Brian Shire <shire@php.net> |
14630 + +----------------------------------------------------------------------+
14631 +
14632 + */
14633 +
14634 +/* $Id: pgsql_s_lock.c 284592 2009-07-22 10:53:50Z kalle $ */
14635 +
14636 +/*-------------------------------------------------------------------------
14637 + *
14638 + * s_lock.c
14639 + * Hardware-dependent implementation of spinlocks.
14640 + *
14641 + *
14642 + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
14643 + * Portions Copyright (c) 1994, Regents of the University of California
14644 + *
14645 + *
14646 + * IDENTIFICATION
14647 + * $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.47 2006/10/04 00:29:58 momjian Exp $
14648 + *
14649 + *-------------------------------------------------------------------------
14650 + */
14651 +/* #include "postgres.h" -- Removed for APC */
14652 +
14653 +/* -- Added for APC -- */
14654 +#include "apc.h"
14655 +#ifdef APC_SPIN_LOCKS
14656 +
14657 +#ifdef S_LOCK_TEST
14658 +#include <stdio.h>
14659 +#endif
14660 +#ifndef WIN32
14661 +#include <sys/select.h>
14662 +#endif
14663 +/* ---- */
14664 +
14665 +#include <time.h>
14666 +#ifdef WIN32
14667 +#include "win32/unistd.h"
14668 +#else
14669 +#include <unistd.h>
14670 +#endif
14671 +
14672 +/* #include "storage/s_lock.h" -- Removed for APC */
14673 +#include "pgsql_s_lock.h"
14674 +
14675 +static int spins_per_delay = DEFAULT_SPINS_PER_DELAY;
14676 +
14677 +
14678 +/* -- APC specific additions ------------------------------*/
14679 +/* The following dependencies have been copied from
14680 + * other pgsql source files. The original locations
14681 + * have been noted.
14682 + */
14683 +
14684 +/* -- from include/c.h -- */
14685 +#ifndef TRUE
14686 +#define TRUE 1
14687 +#endif
14688 +
14689 +#ifndef FALSE
14690 +#define FALSE 0
14691 +#endif
14692 +
14693 +/* -- from include/pg_config_manual.h -- */
14694 +#define MAX_RANDOM_VALUE (0x7FFFFFFF)
14695 +
14696 +/*
14697 + * Max
14698 + * Return the maximum of two numbers.
14699 + */
14700 +#define Max(x, y) ((x) > (y) ? (x) : (y))
14701 +
14702 +/* -- from include/c.h -- */
14703 +/*
14704 + * Min
14705 + * Return the minimum of two numbers.
14706 + */
14707 +#define Min(x, y) ((x) < (y) ? (x) : (y))
14708 +
14709 +
14710 +/* -- from backend/port/win32/signal.c -- */
14711 +/*
14712 + * pg_usleep --- delay the specified number of microseconds.
14713 + *
14714 + * NOTE: although the delay is specified in microseconds, the effective
14715 + * resolution is only 1/HZ, or 10 milliseconds, on most Unixen. Expect
14716 + * the requested delay to be rounded up to the next resolution boundary.
14717 + *
14718 + * On machines where "long" is 32 bits, the maximum delay is ~2000 seconds.
14719 + */
14720 +void
14721 +pg_usleep(long microsec)
14722 +{
14723 + if (microsec > 0)
14724 + {
14725 +#ifndef WIN32
14726 + struct timeval delay;
14727 +
14728 + delay.tv_sec = microsec / 1000000L;
14729 + delay.tv_usec = microsec % 1000000L;
14730 + (void) select(0, NULL, NULL, NULL, &delay);
14731 +#else
14732 + SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
14733 +#endif
14734 + }
14735 +}
14736 +
14737 +/* -- End APC specific additions ------------------------------*/
14738 +
14739 +
14740 +/*
14741 + * s_lock_stuck() - complain about a stuck spinlock
14742 + */
14743 +static void
14744 +s_lock_stuck(volatile slock_t *lock, const char *file, int line)
14745 +{
14746 +#if defined(S_LOCK_TEST)
14747 + fprintf(stderr,
14748 + "\nStuck spinlock (%p) detected at %s:%d.\n",
14749 + lock, file, line);
14750 + exit(1);
14751 +#else
14752 + /* -- Removed for APC
14753 + elog(PANIC, "stuck spinlock (%p) detected at %s:%d",
14754 + lock, file, line);
14755 + */
14756 + apc_eprint("Stuck spinlock (%p) detected", lock);
14757 +#endif
14758 +}
14759 +
14760 +
14761 +/*
14762 + * s_lock(lock) - platform-independent portion of waiting for a spinlock.
14763 + */
14764 +void
14765 +s_lock(volatile slock_t *lock, const char *file, int line)
14766 +{
14767 + /*
14768 + * We loop tightly for awhile, then delay using pg_usleep() and try again.
14769 + * Preferably, "awhile" should be a small multiple of the maximum time we
14770 + * expect a spinlock to be held. 100 iterations seems about right as an
14771 + * initial guess. However, on a uniprocessor the loop is a waste of
14772 + * cycles, while in a multi-CPU scenario it's usually better to spin a bit
14773 + * longer than to call the kernel, so we try to adapt the spin loop count
14774 + * depending on whether we seem to be in a uniprocessor or multiprocessor.
14775 + *
14776 + * Note: you might think MIN_SPINS_PER_DELAY should be just 1, but you'd
14777 + * be wrong; there are platforms where that can result in a "stuck
14778 + * spinlock" failure. This has been seen particularly on Alphas; it seems
14779 + * that the first TAS after returning from kernel space will always fail
14780 + * on that hardware.
14781 + *
14782 + * Once we do decide to block, we use randomly increasing pg_usleep()
14783 + * delays. The first delay is 1 msec, then the delay randomly increases to
14784 + * about one second, after which we reset to 1 msec and start again. The
14785 + * idea here is that in the presence of heavy contention we need to
14786 + * increase the delay, else the spinlock holder may never get to run and
14787 + * release the lock. (Consider situation where spinlock holder has been
14788 + * nice'd down in priority by the scheduler --- it will not get scheduled
14789 + * until all would-be acquirers are sleeping, so if we always use a 1-msec
14790 + * sleep, there is a real possibility of starvation.) But we can't just
14791 + * clamp the delay to an upper bound, else it would take a long time to
14792 + * make a reasonable number of tries.
14793 + *
14794 + * We time out and declare error after NUM_DELAYS delays (thus, exactly
14795 + * that many tries). With the given settings, this will usually take 2 or
14796 + * so minutes. It seems better to fix the total number of tries (and thus
14797 + * the probability of unintended failure) than to fix the total time
14798 + * spent.
14799 + *
14800 + * The pg_usleep() delays are measured in milliseconds because 1 msec is a
14801 + * common resolution limit at the OS level for newer platforms. On older
14802 + * platforms the resolution limit is usually 10 msec, in which case the
14803 + * total delay before timeout will be a bit more.
14804 + */
14805 +#define MIN_SPINS_PER_DELAY 10
14806 +#define MAX_SPINS_PER_DELAY 1000
14807 +#define NUM_DELAYS 1000
14808 +#define MIN_DELAY_MSEC 1
14809 +#define MAX_DELAY_MSEC 1000
14810 +
14811 + int spins = 0;
14812 + int delays = 0;
14813 + int cur_delay = 0;
14814 +
14815 + while (TAS(lock))
14816 + {
14817 + /* CPU-specific delay each time through the loop */
14818 + SPIN_DELAY();
14819 +
14820 + /* Block the process every spins_per_delay tries */
14821 + if (++spins >= spins_per_delay)
14822 + {
14823 + if (++delays > NUM_DELAYS)
14824 + s_lock_stuck(lock, file, line);
14825 +
14826 + if (cur_delay == 0) /* first time to delay? */
14827 + cur_delay = MIN_DELAY_MSEC;
14828 +
14829 + pg_usleep(cur_delay * 1000L);
14830 +
14831 +#if defined(S_LOCK_TEST)
14832 + fprintf(stdout, "*");
14833 + fflush(stdout);
14834 +#endif
14835 +
14836 + /* increase delay by a random fraction between 1X and 2X */
14837 + cur_delay += (int) (cur_delay *
14838 + ((double) rand() / (double) MAX_RANDOM_VALUE) + 0.5);
14839 + /* wrap back to minimum delay when max is exceeded */
14840 + if (cur_delay > MAX_DELAY_MSEC)
14841 + cur_delay = MIN_DELAY_MSEC;
14842 +
14843 + spins = 0;
14844 + }
14845 + }
14846 +
14847 + /*
14848 + * If we were able to acquire the lock without delaying, it's a good
14849 + * indication we are in a multiprocessor. If we had to delay, it's a sign
14850 + * (but not a sure thing) that we are in a uniprocessor. Hence, we
14851 + * decrement spins_per_delay slowly when we had to delay, and increase it
14852 + * rapidly when we didn't. It's expected that spins_per_delay will
14853 + * converge to the minimum value on a uniprocessor and to the maximum
14854 + * value on a multiprocessor.
14855 + *
14856 + * Note: spins_per_delay is local within our current process. We want to
14857 + * average these observations across multiple backends, since it's
14858 + * relatively rare for this function to even get entered, and so a single
14859 + * backend might not live long enough to converge on a good value. That
14860 + * is handled by the two routines below.
14861 + */
14862 + if (cur_delay == 0)
14863 + {
14864 + /* we never had to delay */
14865 + if (spins_per_delay < MAX_SPINS_PER_DELAY)
14866 + spins_per_delay = Min(spins_per_delay + 100, MAX_SPINS_PER_DELAY);
14867 + }
14868 + else
14869 + {
14870 + if (spins_per_delay > MIN_SPINS_PER_DELAY)
14871 + spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY);
14872 + }
14873 +}
14874 +
14875 +
14876 +#if 0 /* -- APC doesn't use the set_spins_per_delay or update_spins_per_delay -- */
14877 +/*
14878 + * Set local copy of spins_per_delay during backend startup.
14879 + *
14880 + * NB: this has to be pretty fast as it is called while holding a spinlock
14881 + */
14882 +void
14883 +set_spins_per_delay(int shared_spins_per_delay)
14884 +{
14885 + spins_per_delay = shared_spins_per_delay;
14886 +}
14887 +
14888 +/*
14889 + * Update shared estimate of spins_per_delay during backend exit.
14890 + *
14891 + * NB: this has to be pretty fast as it is called while holding a spinlock
14892 + */
14893 +int
14894 +update_spins_per_delay(int shared_spins_per_delay)
14895 +{
14896 + /*
14897 + * We use an exponential moving average with a relatively slow adaption
14898 + * rate, so that noise in any one backend's result won't affect the shared
14899 + * value too much. As long as both inputs are within the allowed range,
14900 + * the result must be too, so we need not worry about clamping the result.
14901 + *
14902 + * We deliberately truncate rather than rounding; this is so that single
14903 + * adjustments inside a backend can affect the shared estimate (see the
14904 + * asymmetric adjustment rules above).
14905 + */
14906 + return (shared_spins_per_delay * 15 + spins_per_delay) / 16;
14907 +}
14908 +#endif
14909 +
14910 +/*
14911 + * Various TAS implementations that cannot live in s_lock.h as no inline
14912 + * definition exists (yet).
14913 + * In the future, get rid of tas.[cso] and fold it into this file.
14914 + *
14915 + * If you change something here, you will likely need to modify s_lock.h too,
14916 + * because the definitions for these are split between this file and s_lock.h.
14917 + */
14918 +
14919 +
14920 +#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
14921 +
14922 +
14923 +#if defined(__GNUC__)
14924 +
14925 +/*
14926 + * All the gcc flavors that are not inlined
14927 + */
14928 +
14929 +
14930 +/*
14931 + * Note: all the if-tests here probably ought to be testing gcc version
14932 + * rather than platform, but I don't have adequate info to know what to
14933 + * write. Ideally we'd flush all this in favor of the inline version.
14934 + */
14935 +#if defined(__m68k__) && !defined(__linux__)
14936 +/* really means: extern int tas(slock_t* **lock); */
14937 +static void
14938 +tas_dummy()
14939 +{
14940 + __asm__ __volatile__(
14941 +#if defined(__NetBSD__) && defined(__ELF__)
14942 +/* no underscore for label and % for registers */
14943 + "\
14944 +.global tas \n\
14945 +tas: \n\
14946 + movel %sp@(0x4),%a0 \n\
14947 + tas %a0@ \n\
14948 + beq _success \n\
14949 + moveq #-128,%d0 \n\
14950 + rts \n\
14951 +_success: \n\
14952 + moveq #0,%d0 \n\
14953 + rts \n"
14954 +#else
14955 + "\
14956 +.global _tas \n\
14957 +_tas: \n\
14958 + movel sp@(0x4),a0 \n\
14959 + tas a0@ \n\
14960 + beq _success \n\
14961 + moveq #-128,d0 \n\
14962 + rts \n\
14963 +_success: \n\
14964 + moveq #0,d0 \n\
14965 + rts \n"
14966 +#endif /* __NetBSD__ && __ELF__ */
14967 + );
14968 +}
14969 +#endif /* __m68k__ && !__linux__ */
14970 +#else /* not __GNUC__ */
14971 +
14972 +/*
14973 + * All non gcc
14974 + */
14975 +
14976 +
14977 +#if defined(sun3)
14978 +static void
14979 +tas_dummy() /* really means: extern int tas(slock_t
14980 + * *lock); */
14981 +{
14982 + asm("LLA0:");
14983 + asm(" .data");
14984 + asm(" .text");
14985 + asm("|#PROC# 04");
14986 + asm(" .globl _tas");
14987 + asm("_tas:");
14988 + asm("|#PROLOGUE# 1");
14989 + asm(" movel sp@(0x4),a0");
14990 + asm(" tas a0@");
14991 + asm(" beq LLA1");
14992 + asm(" moveq #-128,d0");
14993 + asm(" rts");
14994 + asm("LLA1:");
14995 + asm(" moveq #0,d0");
14996 + asm(" rts");
14997 + asm(" .data");
14998 +}
14999 +#endif /* sun3 */
15000 +#endif /* not __GNUC__ */
15001 +#endif /* HAVE_SPINLOCKS */
15002 +
15003 +
15004 +
15005 +/*****************************************************************************/
15006 +#if defined(S_LOCK_TEST)
15007 +
15008 +/*
15009 + * test program for verifying a port's spinlock support.
15010 + */
15011 +
15012 +struct test_lock_struct
15013 +{
15014 + char pad1;
15015 + slock_t lock;
15016 + char pad2;
15017 +};
15018 +
15019 +volatile struct test_lock_struct test_lock;
15020 +
15021 +int
15022 +main()
15023 +{
15024 + srandom((unsigned int) time(NULL));
15025 +
15026 + test_lock.pad1 = test_lock.pad2 = 0x44;
15027 +
15028 + S_INIT_LOCK(&test_lock.lock);
15029 +
15030 + if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)
15031 + {
15032 + printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");
15033 + return 1;
15034 + }
15035 +
15036 + if (!S_LOCK_FREE(&test_lock.lock))
15037 + {
15038 + printf("S_LOCK_TEST: failed, lock not initialized\n");
15039 + return 1;
15040 + }
15041 +
15042 + S_LOCK(&test_lock.lock);
15043 +
15044 + if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)
15045 + {
15046 + printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");
15047 + return 1;
15048 + }
15049 +
15050 + if (S_LOCK_FREE(&test_lock.lock))
15051 + {
15052 + printf("S_LOCK_TEST: failed, lock not locked\n");
15053 + return 1;
15054 + }
15055 +
15056 + S_UNLOCK(&test_lock.lock);
15057 +
15058 + if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)
15059 + {
15060 + printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");
15061 + return 1;
15062 + }
15063 +
15064 + if (!S_LOCK_FREE(&test_lock.lock))
15065 + {
15066 + printf("S_LOCK_TEST: failed, lock not unlocked\n");
15067 + return 1;
15068 + }
15069 +
15070 + S_LOCK(&test_lock.lock);
15071 +
15072 + if (test_lock.pad1 != 0x44 || test_lock.pad2 != 0x44)
15073 + {
15074 + printf("S_LOCK_TEST: failed, declared datatype is wrong size\n");
15075 + return 1;
15076 + }
15077 +
15078 + if (S_LOCK_FREE(&test_lock.lock))
15079 + {
15080 + printf("S_LOCK_TEST: failed, lock not re-locked\n");
15081 + return 1;
15082 + }
15083 +
15084 + printf("S_LOCK_TEST: this will print %d stars and then\n", NUM_DELAYS);
15085 + printf(" exit with a 'stuck spinlock' message\n");
15086 + printf(" if S_LOCK() and TAS() are working.\n");
15087 + fflush(stdout);
15088 +
15089 + s_lock(&test_lock.lock, __FILE__, __LINE__);
15090 +
15091 + printf("S_LOCK_TEST: failed, lock not locked\n");
15092 + return 1;
15093 +}
15094 +
15095 +#endif /* S_LOCK_TEST */
15096 +
15097 +#endif /* APC_SPIN_LOCKS */
15098 diff -Naur php-5.3.1.orig/ext/apc/pgsql_s_lock.h php-5.3.1/ext/apc/pgsql_s_lock.h
15099 --- php-5.3.1.orig/ext/apc/pgsql_s_lock.h 1970-01-01 01:00:00.000000000 +0100
15100 +++ php-5.3.1/ext/apc/pgsql_s_lock.h 1970-01-01 10:13:08.000000000 +0100
15101 @@ -0,0 +1,928 @@
15102 +/*
15103 + +----------------------------------------------------------------------+
15104 + | APC |
15105 + +----------------------------------------------------------------------+
15106 + | Copyright (c) 2007-2008 The PHP Group |
15107 + +----------------------------------------------------------------------+
15108 + | This source file is subject to version 3.01 of the PHP license, |
15109 + | that is bundled with this package in the file LICENSE, and is |
15110 + | available through the world-wide-web at the following url: |
15111 + | http://www.php.net/license/3_01.txt |
15112 + | If you did not receive a copy of the PHP license and are unable to |
15113 + | obtain it through the world-wide-web, please send a note to |
15114 + | license@php.net so we can mail you a copy immediately. |
15115 + +----------------------------------------------------------------------+
15116 + | The following code was ported from the PostgreSQL project, please |
15117 + | see appropriate copyright notices that follow. |
15118 + | Initial conversion by Brian Shire <shire@php.net> |
15119 + +----------------------------------------------------------------------+
15120 +
15121 + */
15122 +
15123 +/* $Id: pgsql_s_lock.h 268255 2008-11-04 05:42:11Z rasmus $ */
15124 +
15125 +/*-------------------------------------------------------------------------
15126 + *
15127 + * s_lock.h
15128 + * Hardware-dependent implementation of spinlocks.
15129 + *
15130 + * NOTE: none of the macros in this file are intended to be called directly.
15131 + * Call them through the hardware-independent macros in spin.h.
15132 + *
15133 + * The following hardware-dependent macros must be provided for each
15134 + * supported platform:
15135 + *
15136 + * void S_INIT_LOCK(slock_t *lock)
15137 + * Initialize a spinlock (to the unlocked state).
15138 + *
15139 + * void S_LOCK(slock_t *lock)
15140 + * Acquire a spinlock, waiting if necessary.
15141 + * Time out and abort() if unable to acquire the lock in a
15142 + * "reasonable" amount of time --- typically ~ 1 minute.
15143 + *
15144 + * void S_UNLOCK(slock_t *lock)
15145 + * Unlock a previously acquired lock.
15146 + *
15147 + * bool S_LOCK_FREE(slock_t *lock)
15148 + * Tests if the lock is free. Returns TRUE if free, FALSE if locked.
15149 + * This does *not* change the state of the lock.
15150 + *
15151 + * void SPIN_DELAY(void)
15152 + * Delay operation to occur inside spinlock wait loop.
15153 + *
15154 + * Note to implementors: there are default implementations for all these
15155 + * macros at the bottom of the file. Check if your platform can use
15156 + * these or needs to override them.
15157 + *
15158 + * Usually, S_LOCK() is implemented in terms of an even lower-level macro
15159 + * TAS():
15160 + *
15161 + * int TAS(slock_t *lock)
15162 + * Atomic test-and-set instruction. Attempt to acquire the lock,
15163 + * but do *not* wait. Returns 0 if successful, nonzero if unable
15164 + * to acquire the lock.
15165 + *
15166 + * TAS() is NOT part of the API, and should never be called directly.
15167 + *
15168 + * CAUTION: on some platforms TAS() may sometimes report failure to acquire
15169 + * a lock even when the lock is not locked. For example, on Alpha TAS()
15170 + * will "fail" if interrupted. Therefore TAS() should always be invoked
15171 + * in a retry loop, even if you are certain the lock is free.
15172 + *
15173 + * ANOTHER CAUTION: be sure that TAS() and S_UNLOCK() represent sequence
15174 + * points, ie, loads and stores of other values must not be moved across
15175 + * a lock or unlock. In most cases it suffices to make the operation be
15176 + * done through a "volatile" pointer.
15177 + *
15178 + * On most supported platforms, TAS() uses a tas() function written
15179 + * in assembly language to execute a hardware atomic-test-and-set
15180 + * instruction. Equivalent OS-supplied mutex routines could be used too.
15181 + *
15182 + * If no system-specific TAS() is available (ie, HAVE_SPINLOCKS is not
15183 + * defined), then we fall back on an emulation that uses SysV semaphores
15184 + * (see spin.c). This emulation will be MUCH MUCH slower than a proper TAS()
15185 + * implementation, because of the cost of a kernel call per lock or unlock.
15186 + * An old report is that Postgres spends around 40% of its time in semop(2)
15187 + * when using the SysV semaphore code.
15188 + *
15189 + *
15190 + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
15191 + * Portions Copyright (c) 1994, Regents of the University of California
15192 + *
15193 + * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.157 2006/06/07 22:24:45 momjian Exp $
15194 + *
15195 + *-------------------------------------------------------------------------
15196 + */
15197 +#ifndef S_LOCK_H
15198 +#define S_LOCK_H
15199 +
15200 +/** APC namespace protection ************************************************/
15201 +/* hack to protect against any possible runtime namespace collisions...*/
15202 +#define pg_usleep apc_spin_pg_usleep
15203 +#define s_lock apc_spin_s_lock
15204 +#define spins_per_delay apc_spin_spins_per_delay
15205 +/****************************************************************************/
15206 +
15207 +
15208 +/* #include "storage/pg_sema.h" -- Removed for APC */
15209 +
15210 +#define HAVE_SPINLOCKS 1 /* -- Added for APC */
15211 +
15212 +#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
15213 +
15214 +
15215 +#if defined(__GNUC__) || defined(__ICC)
15216 +/*************************************************************************
15217 + * All the gcc inlines
15218 + * Gcc consistently defines the CPU as __cpu__.
15219 + * Other compilers use __cpu or __cpu__ so we test for both in those cases.
15220 + */
15221 +
15222 +/*----------
15223 + * Standard gcc asm format (assuming "volatile slock_t *lock"):
15224 +
15225 + __asm__ __volatile__(
15226 + " instruction \n"
15227 + " instruction \n"
15228 + " instruction \n"
15229 +: "=r"(_res), "+m"(*lock) // return register, in/out lock value
15230 +: "r"(lock) // lock pointer, in input register
15231 +: "memory", "cc"); // show clobbered registers here
15232 +
15233 + * The output-operands list (after first colon) should always include
15234 + * "+m"(*lock), whether or not the asm code actually refers to this
15235 + * operand directly. This ensures that gcc believes the value in the
15236 + * lock variable is used and set by the asm code. Also, the clobbers
15237 + * list (after third colon) should always include "memory"; this prevents
15238 + * gcc from thinking it can cache the values of shared-memory fields
15239 + * across the asm code. Add "cc" if your asm code changes the condition
15240 + * code register, and also list any temp registers the code uses.
15241 + *----------
15242 + */
15243 +
15244 +
15245 +#ifdef __i386__ /* 32-bit i386 */
15246 +#define HAS_TEST_AND_SET
15247 +
15248 +typedef unsigned char slock_t;
15249 +
15250 +#define TAS(lock) tas(lock)
15251 +
15252 +static __inline__ int
15253 +tas(volatile slock_t *lock)
15254 +{
15255 + register slock_t _res = 1;
15256 +
15257 + /*
15258 + * Use a non-locking test before asserting the bus lock. Note that the
15259 + * extra test appears to be a small loss on some x86 platforms and a small
15260 + * win on others; it's by no means clear that we should keep it.
15261 + */
15262 + __asm__ __volatile__(
15263 + " cmpb $0,%1 \n"
15264 + " jne 1f \n"
15265 + " lock \n"
15266 + " xchgb %0,%1 \n"
15267 + "1: \n"
15268 +: "+q"(_res), "+m"(*lock)
15269 +:
15270 +: "memory", "cc");
15271 + return (int) _res;
15272 +}
15273 +
15274 +#define SPIN_DELAY() spin_delay()
15275 +
15276 +static __inline__ void
15277 +spin_delay(void)
15278 +{
15279 + /*
15280 + * This sequence is equivalent to the PAUSE instruction ("rep" is
15281 + * ignored by old IA32 processors if the following instruction is
15282 + * not a string operation); the IA-32 Architecture Software
15283 + * Developer's Manual, Vol. 3, Section 7.7.2 describes why using
15284 + * PAUSE in the inner loop of a spin lock is necessary for good
15285 + * performance:
15286 + *
15287 + * The PAUSE instruction improves the performance of IA-32
15288 + * processors supporting Hyper-Threading Technology when
15289 + * executing spin-wait loops and other routines where one
15290 + * thread is accessing a shared lock or semaphore in a tight
15291 + * polling loop. When executing a spin-wait loop, the
15292 + * processor can suffer a severe performance penalty when
15293 + * exiting the loop because it detects a possible memory order
15294 + * violation and flushes the core processor's pipeline. The
15295 + * PAUSE instruction provides a hint to the processor that the
15296 + * code sequence is a spin-wait loop. The processor uses this
15297 + * hint to avoid the memory order violation and prevent the
15298 + * pipeline flush. In addition, the PAUSE instruction
15299 + * de-pipelines the spin-wait loop to prevent it from
15300 + * consuming execution resources excessively.
15301 + */
15302 + __asm__ __volatile__(
15303 + " rep; nop \n");
15304 +}
15305 +
15306 +#endif /* __i386__ */
15307 +
15308 +
15309 +#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */
15310 +#define HAS_TEST_AND_SET
15311 +
15312 +typedef unsigned char slock_t;
15313 +
15314 +#define TAS(lock) tas(lock)
15315 +
15316 +static __inline__ int
15317 +tas(volatile slock_t *lock)
15318 +{
15319 + register slock_t _res = 1;
15320 +
15321 + /*
15322 + * On Opteron, using a non-locking test before the locking instruction
15323 + * is a huge loss. On EM64T, it appears to be a wash or small loss,
15324 + * so we needn't bother to try to distinguish the sub-architectures.
15325 + */
15326 + __asm__ __volatile__(
15327 + " lock \n"
15328 + " xchgb %0,%1 \n"
15329 +: "+q"(_res), "+m"(*lock)
15330 +:
15331 +: "memory", "cc");
15332 + return (int) _res;
15333 +}
15334 +
15335 +#define SPIN_DELAY() spin_delay()
15336 +
15337 +static __inline__ void
15338 +spin_delay(void)
15339 +{
15340 + /*
15341 + * Adding a PAUSE in the spin delay loop is demonstrably a no-op on
15342 + * Opteron, but it may be of some use on EM64T, so we keep it.
15343 + */
15344 + __asm__ __volatile__(
15345 + " rep; nop \n");
15346 +}
15347 +
15348 +#endif /* __x86_64__ */
15349 +
15350 +
15351 +#if defined(__ia64__) || defined(__ia64) /* Intel Itanium */
15352 +#define HAS_TEST_AND_SET
15353 +
15354 +typedef unsigned int slock_t;
15355 +
15356 +#define TAS(lock) tas(lock)
15357 +
15358 +#ifndef __INTEL_COMPILER
15359 +
15360 +static __inline__ int
15361 +tas(volatile slock_t *lock)
15362 +{
15363 + long int ret;
15364 +
15365 + __asm__ __volatile__(
15366 + " xchg4 %0=%1,%2 \n"
15367 +: "=r"(ret), "+m"(*lock)
15368 +: "r"(1)
15369 +: "memory");
15370 + return (int) ret;
15371 +}
15372 +
15373 +#else /* __INTEL_COMPILER */
15374 +
15375 +static __inline__ int
15376 +tas(volatile slock_t *lock)
15377 +{
15378 + int ret;
15379 +
15380 + ret = _InterlockedExchange(lock,1); /* this is a xchg asm macro */
15381 +
15382 + return ret;
15383 +}
15384 +
15385 +#endif /* __INTEL_COMPILER */
15386 +#endif /* __ia64__ || __ia64 */
15387 +
15388 +
15389 +#if defined(__arm__) || defined(__arm)
15390 +#define HAS_TEST_AND_SET
15391 +
15392 +typedef unsigned char slock_t;
15393 +
15394 +#define TAS(lock) tas(lock)
15395 +
15396 +static __inline__ int
15397 +tas(volatile slock_t *lock)
15398 +{
15399 + register slock_t _res = 1;
15400 +
15401 + __asm__ __volatile__(
15402 + " swpb %0, %0, [%2] \n"
15403 +: "+r"(_res), "+m"(*lock)
15404 +: "r"(lock)
15405 +: "memory");
15406 + return (int) _res;
15407 +}
15408 +
15409 +#endif /* __arm__ */
15410 +
15411 +
15412 +/* S/390 and S/390x Linux (32- and 64-bit zSeries) */
15413 +#if defined(__s390__) || defined(__s390x__)
15414 +#define HAS_TEST_AND_SET
15415 +
15416 +typedef unsigned int slock_t;
15417 +
15418 +#define TAS(lock) tas(lock)
15419 +
15420 +static __inline__ int
15421 +tas(volatile slock_t *lock)
15422 +{
15423 + int _res = 0;
15424 +
15425 + __asm__ __volatile__(
15426 + " cs %0,%3,0(%2) \n"
15427 +: "+d"(_res), "+m"(*lock)
15428 +: "a"(lock), "d"(1)
15429 +: "memory", "cc");
15430 + return _res;
15431 +}
15432 +
15433 +#endif /* __s390__ || __s390x__ */
15434 +
15435 +
15436 +#if defined(__sparc__) /* Sparc */
15437 +#define HAS_TEST_AND_SET
15438 +
15439 +typedef unsigned char slock_t;
15440 +
15441 +#define TAS(lock) tas(lock)
15442 +
15443 +static __inline__ int
15444 +tas(volatile slock_t *lock)
15445 +{
15446 + register slock_t _res;
15447 +
15448 + /*
15449 + * See comment in /pg/backend/port/tas/solaris_sparc.s for why this
15450 + * uses "ldstub", and that file uses "cas". gcc currently generates
15451 + * sparcv7-targeted binaries, so "cas" use isn't possible.
15452 + */
15453 + __asm__ __volatile__(
15454 + " ldstub [%2], %0 \n"
15455 +: "=r"(_res), "+m"(*lock)
15456 +: "r"(lock)
15457 +: "memory");
15458 + return (int) _res;
15459 +}
15460 +
15461 +#endif /* __sparc__ */
15462 +
15463 +
15464 +/* PowerPC */
15465 +#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
15466 +#define HAS_TEST_AND_SET
15467 +
15468 +#if defined(__ppc64__) || defined(__powerpc64__)
15469 +typedef unsigned long slock_t;
15470 +#else
15471 +typedef unsigned int slock_t;
15472 +#endif
15473 +
15474 +#define TAS(lock) tas(lock)
15475 +/*
15476 + * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
15477 + * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
15478 + */
15479 +static __inline__ int
15480 +tas(volatile slock_t *lock)
15481 +{
15482 + slock_t _t;
15483 + int _res;
15484 +
15485 + __asm__ __volatile__(
15486 +" lwarx %0,0,%3 \n"
15487 +" cmpwi %0,0 \n"
15488 +" bne 1f \n"
15489 +" addi %0,%0,1 \n"
15490 +" stwcx. %0,0,%3 \n"
15491 +" beq 2f \n"
15492 +"1: li %1,1 \n"
15493 +" b 3f \n"
15494 +"2: \n"
15495 +" isync \n"
15496 +" li %1,0 \n"
15497 +"3: \n"
15498 +
15499 +: "=&r"(_t), "=r"(_res), "+m"(*lock)
15500 +: "r"(lock)
15501 +: "memory", "cc");
15502 + return _res;
15503 +}
15504 +
15505 +/* PowerPC S_UNLOCK is almost standard but requires a "sync" instruction */
15506 +#define S_UNLOCK(lock) \
15507 +do \
15508 +{ \
15509 + __asm__ __volatile__ (" sync \n"); \
15510 + *((volatile slock_t *) (lock)) = 0; \
15511 +} while (0)
15512 +
15513 +#endif /* powerpc */
15514 +
15515 +
15516 +/* Linux Motorola 68k */
15517 +#if (defined(__mc68000__) || defined(__m68k__)) && defined(__linux__)
15518 +#define HAS_TEST_AND_SET
15519 +
15520 +typedef unsigned char slock_t;
15521 +
15522 +#define TAS(lock) tas(lock)
15523 +
15524 +static __inline__ int
15525 +tas(volatile slock_t *lock)
15526 +{
15527 + register int rv;
15528 +
15529 + __asm__ __volatile__(
15530 + " clrl %0 \n"
15531 + " tas %1 \n"
15532 + " sne %0 \n"
15533 +: "=d"(rv), "+m"(*lock)
15534 +:
15535 +: "memory", "cc");
15536 + return rv;
15537 +}
15538 +
15539 +#endif /* (__mc68000__ || __m68k__) && __linux__ */
15540 +
15541 +
15542 +/*
15543 + * VAXen -- even multiprocessor ones
15544 + * (thanks to Tom Ivar Helbekkmo)
15545 + */
15546 +#if defined(__vax__)
15547 +#define HAS_TEST_AND_SET
15548 +
15549 +typedef unsigned char slock_t;
15550 +
15551 +#define TAS(lock) tas(lock)
15552 +
15553 +static __inline__ int
15554 +tas(volatile slock_t *lock)
15555 +{
15556 + register int _res;
15557 +
15558 + __asm__ __volatile__(
15559 + " movl $1, %0 \n"
15560 + " bbssi $0, (%2), 1f \n"
15561 + " clrl %0 \n"
15562 + "1: \n"
15563 +: "=&r"(_res), "+m"(*lock)
15564 +: "r"(lock)
15565 +: "memory");
15566 + return _res;
15567 +}
15568 +
15569 +#endif /* __vax__ */
15570 +
15571 +
15572 +#if defined(__ns32k__) /* National Semiconductor 32K */
15573 +#define HAS_TEST_AND_SET
15574 +
15575 +typedef unsigned char slock_t;
15576 +
15577 +#define TAS(lock) tas(lock)
15578 +
15579 +static __inline__ int
15580 +tas(volatile slock_t *lock)
15581 +{
15582 + register int _res;
15583 +
15584 + __asm__ __volatile__(
15585 + " sbitb 0, %1 \n"
15586 + " sfsd %0 \n"
15587 +: "=r"(_res), "+m"(*lock)
15588 +:
15589 +: "memory");
15590 + return _res;
15591 +}
15592 +
15593 +#endif /* __ns32k__ */
15594 +
15595 +
15596 +#if defined(__alpha) || defined(__alpha__) /* Alpha */
15597 +/*
15598 + * Correct multi-processor locking methods are explained in section 5.5.3
15599 + * of the Alpha AXP Architecture Handbook, which at this writing can be
15600 + * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html.
15601 + * For gcc we implement the handbook's code directly with inline assembler.
15602 + */
15603 +#define HAS_TEST_AND_SET
15604 +
15605 +typedef unsigned long slock_t;
15606 +
15607 +#define TAS(lock) tas(lock)
15608 +
15609 +static __inline__ int
15610 +tas(volatile slock_t *lock)
15611 +{
15612 + register slock_t _res;
15613 +
15614 + __asm__ __volatile__(
15615 + " ldq $0, %1 \n"
15616 + " bne $0, 2f \n"
15617 + " ldq_l %0, %1 \n"
15618 + " bne %0, 2f \n"
15619 + " mov 1, $0 \n"
15620 + " stq_c $0, %1 \n"
15621 + " beq $0, 2f \n"
15622 + " mb \n"
15623 + " br 3f \n"
15624 + "2: mov 1, %0 \n"
15625 + "3: \n"
15626 +: "=&r"(_res), "+m"(*lock)
15627 +:
15628 +: "memory", "0");
15629 + return (int) _res;
15630 +}
15631 +
15632 +#define S_UNLOCK(lock) \
15633 +do \
15634 +{\
15635 + __asm__ __volatile__ (" mb \n"); \
15636 + *((volatile slock_t *) (lock)) = 0; \
15637 +} while (0)
15638 +
15639 +#endif /* __alpha || __alpha__ */
15640 +
15641 +
15642 +#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */
15643 +/* Note: on SGI we use the OS' mutex ABI, see below */
15644 +/* Note: R10000 processors require a separate SYNC */
15645 +#define HAS_TEST_AND_SET
15646 +
15647 +typedef unsigned int slock_t;
15648 +
15649 +#define TAS(lock) tas(lock)
15650 +
15651 +static __inline__ int
15652 +tas(volatile slock_t *lock)
15653 +{
15654 + register volatile slock_t *_l = lock;
15655 + register int _res;
15656 + register int _tmp;
15657 +
15658 + __asm__ __volatile__(
15659 + " .set push \n"
15660 + " .set mips2 \n"
15661 + " .set noreorder \n"
15662 + " .set nomacro \n"
15663 + " ll %0, %2 \n"
15664 + " or %1, %0, 1 \n"
15665 + " sc %1, %2 \n"
15666 + " xori %1, 1 \n"
15667 + " or %0, %0, %1 \n"
15668 + " sync \n"
15669 + " .set pop "
15670 +: "=&r" (_res), "=&r" (_tmp), "+R" (*_l)
15671 +:
15672 +: "memory");
15673 + return _res;
15674 +}
15675 +
15676 +/* MIPS S_UNLOCK is almost standard but requires a "sync" instruction */
15677 +#define S_UNLOCK(lock) \
15678 +do \
15679 +{ \
15680 + __asm__ __volatile__( \
15681 + " .set push \n" \
15682 + " .set mips2 \n" \
15683 + " .set noreorder \n" \
15684 + " .set nomacro \n" \
15685 + " sync \n" \
15686 + " .set pop "); \
15687 + *((volatile slock_t *) (lock)) = 0; \
15688 +} while (0)
15689 +
15690 +#endif /* __mips__ && !__sgi */
15691 +
15692 +
15693 +/* These live in s_lock.c, but only for gcc */
15694 +
15695 +
15696 +#if defined(__m68k__) && !defined(__linux__) /* non-Linux Motorola 68k */
15697 +#define HAS_TEST_AND_SET
15698 +
15699 +typedef unsigned char slock_t;
15700 +#endif
15701 +
15702 +
15703 +#endif /* __GNUC__ */
15704 +
15705 +
15706 +
15707 +/*
15708 + * ---------------------------------------------------------------------
15709 + * Platforms that use non-gcc inline assembly:
15710 + * ---------------------------------------------------------------------
15711 + */
15712 +
15713 +#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */
15714 +
15715 +
15716 +#if defined(USE_UNIVEL_CC) /* Unixware compiler */
15717 +#define HAS_TEST_AND_SET
15718 +
15719 +typedef unsigned char slock_t;
15720 +
15721 +#define TAS(lock) tas(lock)
15722 +
15723 +asm int
15724 +tas(volatile slock_t *s_lock)
15725 +{
15726 +/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */
15727 +%mem s_lock
15728 + pushl %ebx
15729 + movl s_lock, %ebx
15730 + movl $255, %eax
15731 + lock
15732 + xchgb %al, (%ebx)
15733 + popl %ebx
15734 +}
15735 +
15736 +#endif /* defined(USE_UNIVEL_CC) */
15737 +
15738 +
15739 +#if defined(__alpha) || defined(__alpha__) /* Tru64 Unix Alpha compiler */
15740 +/*
15741 + * The Tru64 compiler doesn't support gcc-style inline asm, but it does
15742 + * have some builtin functions that accomplish much the same results.
15743 + * For simplicity, slock_t is defined as long (ie, quadword) on Alpha
15744 + * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only
15745 + * operate on an int (ie, longword), but that's OK as long as we define
15746 + * S_INIT_LOCK to zero out the whole quadword.
15747 + */
15748 +#define HAS_TEST_AND_SET
15749 +
15750 +typedef unsigned long slock_t;
15751 +
15752 +#include <alpha/builtins.h>
15753 +#define S_INIT_LOCK(lock) (*(lock) = 0)
15754 +#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0)
15755 +#define S_UNLOCK(lock) __UNLOCK_LONG(lock)
15756 +
15757 +#endif /* __alpha || __alpha__ */
15758 +
15759 +
15760 +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */
15761 +/*
15762 + * HP's PA-RISC
15763 + *
15764 + * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because
15765 + * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte
15766 + * struct. The active word in the struct is whichever has the aligned address;
15767 + * the other three words just sit at -1.
15768 + *
15769 + * When using gcc, we can inline the required assembly code.
15770 + */
15771 +#define HAS_TEST_AND_SET
15772 +
15773 +typedef struct
15774 +{
15775 + int sema[4];
15776 +} slock_t;
15777 +
15778 +#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((long) (lock) + 15) & ~15))
15779 +
15780 +#if defined(__GNUC__)
15781 +
15782 +static __inline__ int
15783 +tas(volatile slock_t *lock)
15784 +{
15785 + volatile int *lockword = TAS_ACTIVE_WORD(lock);
15786 + register int lockval;
15787 +
15788 + __asm__ __volatile__(
15789 + " ldcwx 0(0,%2),%0 \n"
15790 +: "=r"(lockval), "+m"(*lockword)
15791 +: "r"(lockword)
15792 +: "memory");
15793 + return (lockval == 0);
15794 +}
15795 +
15796 +#endif /* __GNUC__ */
15797 +
15798 +#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1)
15799 +
15800 +#define S_INIT_LOCK(lock) \
15801 + do { \
15802 + volatile slock_t *lock_ = (lock); \
15803 + lock_->sema[0] = -1; \
15804 + lock_->sema[1] = -1; \
15805 + lock_->sema[2] = -1; \
15806 + lock_->sema[3] = -1; \
15807 + } while (0)
15808 +
15809 +#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
15810 +
15811 +#endif /* __hppa || __hppa__ */
15812 +
15813 +
15814 +#if defined(__hpux) && defined(__ia64) && !defined(__GNUC__)
15815 +
15816 +#define HAS_TEST_AND_SET
15817 +
15818 +typedef unsigned int slock_t;
15819 +
15820 +#include <ia64/sys/inline.h>
15821 +#define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
15822 +
15823 +#endif /* HPUX on IA64, non gcc */
15824 +
15825 +
15826 +#if defined(__sgi) /* SGI compiler */
15827 +/*
15828 + * SGI IRIX 5
15829 + * slock_t is defined as a unsigned long. We use the standard SGI
15830 + * mutex API.
15831 + *
15832 + * The following comment is left for historical reasons, but is probably
15833 + * not a good idea since the mutex ABI is supported.
15834 + *
15835 + * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II
15836 + * assembly from his NECEWS SVR4 port, but we probably ought to retain this
15837 + * for the R3000 chips out there.
15838 + */
15839 +#define HAS_TEST_AND_SET
15840 +
15841 +typedef unsigned long slock_t;
15842 +
15843 +#include "mutex.h"
15844 +#define TAS(lock) (test_and_set(lock,1))
15845 +#define S_UNLOCK(lock) (test_then_and(lock,0))
15846 +#define S_INIT_LOCK(lock) (test_then_and(lock,0))
15847 +#define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0)
15848 +#endif /* __sgi */
15849 +
15850 +
15851 +#if defined(sinix) /* Sinix */
15852 +/*
15853 + * SINIX / Reliant UNIX
15854 + * slock_t is defined as a struct abilock_t, which has a single unsigned long
15855 + * member. (Basically same as SGI)
15856 + */
15857 +#define HAS_TEST_AND_SET
15858 +
15859 +#include "abi_mutex.h"
15860 +typedef abilock_t slock_t;
15861 +
15862 +#define TAS(lock) (!acquire_lock(lock))
15863 +#define S_UNLOCK(lock) release_lock(lock)
15864 +#define S_INIT_LOCK(lock) init_lock(lock)
15865 +#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED)
15866 +#endif /* sinix */
15867 +
15868 +
15869 +#if defined(_AIX) /* AIX */
15870 +/*
15871 + * AIX (POWER)
15872 + */
15873 +#define HAS_TEST_AND_SET
15874 +
15875 +typedef unsigned int slock_t;
15876 +
15877 +#define TAS(lock) _check_lock(lock, 0, 1)
15878 +#define S_UNLOCK(lock) _clear_lock(lock, 0)
15879 +#endif /* _AIX */
15880 +
15881 +
15882 +#if defined (nextstep) /* Nextstep */
15883 +#define HAS_TEST_AND_SET
15884 +
15885 +typedef struct mutex slock_t;
15886 +
15887 +#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 0 /* -- APC: non-blocking lock not available in this case -- */
15888 +
15889 +#define S_LOCK(lock) mutex_lock(lock)
15890 +#define S_UNLOCK(lock) mutex_unlock(lock)
15891 +#define S_INIT_LOCK(lock) mutex_init(lock)
15892 +/* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */
15893 +#define S_LOCK_FREE(alock) ((alock)->lock == 0)
15894 +#endif /* nextstep */
15895 +
15896 +
15897 +/* These are in s_lock.c */
15898 +
15899 +
15900 +#if defined(sun3) /* Sun3 */
15901 +#define HAS_TEST_AND_SET
15902 +
15903 +typedef unsigned char slock_t;
15904 +#endif
15905 +
15906 +
15907 +#if defined(__sun) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
15908 +#define HAS_TEST_AND_SET
15909 +
15910 +#if defined(__i386) || defined(__x86_64__) || defined(__sparcv9) || defined(__sparcv8plus)
15911 +typedef unsigned int slock_t;
15912 +#else
15913 +typedef unsigned char slock_t;
15914 +#endif
15915 +
15916 +extern slock_t pg_atomic_cas(volatile slock_t *lock, slock_t with,
15917 + slock_t cmp);
15918 +
15919 +#define TAS(a) (pg_atomic_cas((a), 1, 0) != 0)
15920 +#endif
15921 +
15922 +
15923 +#ifdef WIN32_ONLY_COMPILER
15924 +typedef LONG slock_t;
15925 +
15926 +#define HAS_TEST_AND_SET
15927 +#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
15928 +
15929 +#define SPIN_DELAY() spin_delay()
15930 +
15931 +static __forceinline void
15932 +spin_delay(void)
15933 +{
15934 + /* See comment for gcc code. Same code, MASM syntax */
15935 + __asm rep nop;
15936 +}
15937 +
15938 +#endif
15939 +
15940 +
15941 +#endif /* !defined(HAS_TEST_AND_SET) */
15942 +
15943 +
15944 +/* Blow up if we didn't have any way to do spinlocks */
15945 +#ifndef HAS_TEST_AND_SET
15946 +/* -- APC: We have better options in APC than this, that should be specified explicitly so just fail out and notify the user -- */
15947 +#error Spin locking is not available on your platform, please select another locking method (see ./configure --help).
15948 +/* #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. */
15949 +#endif
15950 +
15951 +
15952 +#else /* !HAVE_SPINLOCKS */
15953 +
15954 +
15955 +/*
15956 + * Fake spinlock implementation using semaphores --- slow and prone
15957 + * to fall foul of kernel limits on number of semaphores, so don't use this
15958 + * unless you must! The subroutines appear in spin.c.
15959 + */
15960 +
15961 +/* -- Removed for APC
15962 +typedef PGSemaphoreData slock_t;
15963 +
15964 +extern bool s_lock_free_sema(volatile slock_t *lock);
15965 +extern void s_unlock_sema(volatile slock_t *lock);
15966 +extern void s_init_lock_sema(volatile slock_t *lock);
15967 +extern int tas_sema(volatile slock_t *lock);
15968 +
15969 +#define S_LOCK_FREE(lock) s_lock_free_sema(lock)
15970 +#define S_UNLOCK(lock) s_unlock_sema(lock)
15971 +#define S_INIT_LOCK(lock) s_init_lock_sema(lock)
15972 +#define TAS(lock) tas_sema(lock)
15973 +*/
15974 +
15975 +#endif /* HAVE_SPINLOCKS */
15976 +
15977 +
15978 +/*
15979 + * Default Definitions - override these above as needed.
15980 + */
15981 +
15982 +#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 1 /* -- APC: Non-blocking lock available for this case -- */
15983 +
15984 +#if !defined(S_LOCK)
15985 +#define S_LOCK(lock) \
15986 + do { \
15987 + if (TAS(lock)) \
15988 + s_lock((lock), __FILE__, __LINE__); \
15989 + } while (0)
15990 +#endif /* S_LOCK */
15991 +
15992 +#if !defined(S_LOCK_FREE)
15993 +#define S_LOCK_FREE(lock) (*(lock) == 0)
15994 +#endif /* S_LOCK_FREE */
15995 +
15996 +#if !defined(S_UNLOCK)
15997 +#define S_UNLOCK(lock) (*((volatile slock_t *) (lock)) = 0)
15998 +#endif /* S_UNLOCK */
15999 +
16000 +#if !defined(S_INIT_LOCK)
16001 +#define S_INIT_LOCK(lock) S_UNLOCK(lock)
16002 +#endif /* S_INIT_LOCK */
16003 +
16004 +#if !defined(SPIN_DELAY)
16005 +#define SPIN_DELAY() ((void) 0)
16006 +#endif /* SPIN_DELAY */
16007 +
16008 +#if !defined(TAS)
16009 +extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
16010 + * s_lock.c */
16011 +
16012 +#define TAS(lock) tas(lock)
16013 +#endif /* TAS */
16014 +
16015 +
16016 +/*
16017 + * Platform-independent out-of-line support routines
16018 + */
16019 +extern void s_lock(volatile slock_t *lock, const char *file, int line);
16020 +
16021 +/* Support for dynamic adjustment of spins_per_delay */
16022 +#define DEFAULT_SPINS_PER_DELAY 100
16023 +
16024 +#if 0 /* -- Removed from APC use -- */
16025 +extern void set_spins_per_delay(int shared_spins_per_delay);
16026 +extern int update_spins_per_delay(int shared_spins_per_delay);
16027 +#endif
16028 +
16029 +#endif /* S_LOCK_H */
16030 diff -Naur php-5.3.1.orig/ext/apc/php_apc.c php-5.3.1/ext/apc/php_apc.c
16031 --- php-5.3.1.orig/ext/apc/php_apc.c 1970-01-01 01:00:00.000000000 +0100
16032 +++ php-5.3.1/ext/apc/php_apc.c 1970-01-01 10:13:08.000000000 +0100
16033 @@ -0,0 +1,1649 @@
16034 +/*
16035 + +----------------------------------------------------------------------+
16036 + | APC |
16037 + +----------------------------------------------------------------------+
16038 + | Copyright (c) 2006-2008 The PHP Group |
16039 + +----------------------------------------------------------------------+
16040 + | This source file is subject to version 3.01 of the PHP license, |
16041 + | that is bundled with this package in the file LICENSE, and is |
16042 + | available through the world-wide-web at the following url: |
16043 + | http://www.php.net/license/3_01.txt |
16044 + | If you did not receive a copy of the PHP license and are unable to |
16045 + | obtain it through the world-wide-web, please send a note to |
16046 + | license@php.net so we can mail you a copy immediately. |
16047 + +----------------------------------------------------------------------+
16048 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
16049 + | Rasmus Lerdorf <rasmus@php.net> |
16050 + +----------------------------------------------------------------------+
16051 +
16052 + This software was contributed to PHP by Community Connect Inc. in 2002
16053 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
16054 + Future revisions and derivatives of this source code must acknowledge
16055 + Community Connect Inc. as the original contributor of this module by
16056 + leaving this note intact in the source code.
16057 +
16058 + All other licensing and usage conditions are those of the PHP Group.
16059 +
16060 + */
16061 +
16062 +/* $Id: php_apc.c 286798 2009-08-04 11:27:12Z gopalv $ */
16063 +
16064 +#include "apc_zend.h"
16065 +#include "apc_cache.h"
16066 +#include "apc_iterator.h"
16067 +#include "apc_main.h"
16068 +#include "apc_sma.h"
16069 +#include "apc_lock.h"
16070 +#include "apc_bin.h"
16071 +#include "php_globals.h"
16072 +#include "php_ini.h"
16073 +#include "ext/standard/info.h"
16074 +#include "ext/standard/file.h"
16075 +#include "ext/standard/flock_compat.h"
16076 +#ifdef HAVE_SYS_FILE_H
16077 +#include <sys/file.h>
16078 +#endif
16079 +#include "SAPI.h"
16080 +#include "rfc1867.h"
16081 +#include "php_apc.h"
16082 +#include "ext/standard/md5.h"
16083 +
16084 +#if HAVE_SIGACTION
16085 +#include "apc_signal.h"
16086 +#endif
16087 +
16088 +/* {{{ PHP_FUNCTION declarations */
16089 +PHP_FUNCTION(apc_cache_info);
16090 +PHP_FUNCTION(apc_clear_cache);
16091 +PHP_FUNCTION(apc_sma_info);
16092 +PHP_FUNCTION(apc_store);
16093 +PHP_FUNCTION(apc_fetch);
16094 +PHP_FUNCTION(apc_delete);
16095 +PHP_FUNCTION(apc_delete_file);
16096 +PHP_FUNCTION(apc_compile_file);
16097 +PHP_FUNCTION(apc_define_constants);
16098 +PHP_FUNCTION(apc_load_constants);
16099 +PHP_FUNCTION(apc_add);
16100 +PHP_FUNCTION(apc_inc);
16101 +PHP_FUNCTION(apc_dec);
16102 +PHP_FUNCTION(apc_cas);
16103 +PHP_FUNCTION(apc_bin_dump);
16104 +PHP_FUNCTION(apc_bin_load);
16105 +PHP_FUNCTION(apc_bin_dumpfile);
16106 +PHP_FUNCTION(apc_bin_loadfile);
16107 +/* }}} */
16108 +
16109 +/* {{{ ZEND_DECLARE_MODULE_GLOBALS(apc) */
16110 +ZEND_DECLARE_MODULE_GLOBALS(apc)
16111 +
16112 +/* True globals */
16113 +apc_cache_t* apc_cache = NULL;
16114 +apc_cache_t* apc_user_cache = NULL;
16115 +
16116 +static void php_apc_init_globals(zend_apc_globals* apc_globals TSRMLS_DC)
16117 +{
16118 + apc_globals->filters = NULL;
16119 + apc_globals->compiled_filters = NULL;
16120 + apc_globals->initialized = 0;
16121 + apc_globals->cache_stack = apc_stack_create(0);
16122 + apc_globals->cache_by_default = 1;
16123 + apc_globals->fpstat = 1;
16124 + apc_globals->canonicalize = 1;
16125 + apc_globals->stat_ctime = 0;
16126 + apc_globals->write_lock = 1;
16127 + apc_globals->report_autofilter = 0;
16128 + apc_globals->include_once = 0;
16129 + apc_globals->apc_optimize_function = NULL;
16130 +#ifdef MULTIPART_EVENT_FORMDATA
16131 + apc_globals->rfc1867 = 0;
16132 + memset(&(apc_globals->rfc1867_data), 0, sizeof(apc_rfc1867_data));
16133 +#endif
16134 + memset(&apc_globals->copied_zvals, 0, sizeof(HashTable));
16135 + apc_globals->force_file_update = 0;
16136 + apc_globals->coredump_unmap = 0;
16137 + apc_globals->preload_path = NULL;
16138 + apc_globals->use_request_time = 1;
16139 + apc_globals->lazy_class_table = NULL;
16140 + apc_globals->lazy_function_table = NULL;
16141 +}
16142 +
16143 +static void php_apc_shutdown_globals(zend_apc_globals* apc_globals TSRMLS_DC)
16144 +{
16145 + /* deallocate the ignore patterns */
16146 + if (apc_globals->filters != NULL) {
16147 + int i;
16148 + for (i=0; apc_globals->filters[i] != NULL; i++) {
16149 + apc_efree(apc_globals->filters[i]);
16150 + }
16151 + apc_efree(apc_globals->filters);
16152 + }
16153 +
16154 + /* the stack should be empty */
16155 + assert(apc_stack_size(apc_globals->cache_stack) == 0);
16156 +
16157 + /* apc cleanup */
16158 + apc_stack_destroy(apc_globals->cache_stack);
16159 +
16160 + /* the rest of the globals are cleaned up in apc_module_shutdown() */
16161 +}
16162 +
16163 +/* }}} */
16164 +
16165 +/* {{{ PHP_INI */
16166 +
16167 +static PHP_INI_MH(OnUpdate_filters) /* {{{ */
16168 +{
16169 + APCG(filters) = apc_tokenize(new_value, ',');
16170 + return SUCCESS;
16171 +}
16172 +/* }}} */
16173 +
16174 +static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */
16175 +{
16176 +#if APC_MMAP
16177 + if(atoi(new_value)!=1) {
16178 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "apc.shm_segments setting ignored in MMAP mode");
16179 + }
16180 + APCG(shm_segments) = 1;
16181 +#else
16182 + APCG(shm_segments) = atoi(new_value);
16183 +#endif
16184 + return SUCCESS;
16185 +}
16186 +/* }}} */
16187 +
16188 +#ifdef MULTIPART_EVENT_FORMDATA
16189 +static PHP_INI_MH(OnUpdateRfc1867Freq) /* {{{ */
16190 +{
16191 + int tmp;
16192 + tmp = zend_atoi(new_value, new_value_length);
16193 + if(tmp < 0) {
16194 + apc_eprint("rfc1867_freq must be greater than or equal to zero.");
16195 + return FAILURE;
16196 + }
16197 + if(new_value[new_value_length-1] == '%') {
16198 + if(tmp > 100) {
16199 + apc_eprint("rfc1867_freq cannot be over 100%%");
16200 + return FAILURE;
16201 + }
16202 + APCG(rfc1867_freq) = tmp / 100.0;
16203 + } else {
16204 + APCG(rfc1867_freq) = tmp;
16205 + }
16206 + return SUCCESS;
16207 +}
16208 +/* }}} */
16209 +#endif
16210 +
16211 +#define OnUpdateInt OnUpdateLong
16212 +
16213 +PHP_INI_BEGIN()
16214 +STD_PHP_INI_BOOLEAN("apc.enabled", "1", PHP_INI_SYSTEM, OnUpdateBool, enabled, zend_apc_globals, apc_globals)
16215 +STD_PHP_INI_ENTRY("apc.shm_segments", "1", PHP_INI_SYSTEM, OnUpdateShmSegments, shm_segments, zend_apc_globals, apc_globals)
16216 +STD_PHP_INI_ENTRY("apc.shm_size", "30", PHP_INI_SYSTEM, OnUpdateInt, shm_size, zend_apc_globals, apc_globals)
16217 +STD_PHP_INI_BOOLEAN("apc.include_once_override", "0", PHP_INI_SYSTEM, OnUpdateBool, include_once, zend_apc_globals, apc_globals)
16218 +STD_PHP_INI_ENTRY("apc.num_files_hint", "1000", PHP_INI_SYSTEM, OnUpdateInt, num_files_hint, zend_apc_globals, apc_globals)
16219 +STD_PHP_INI_ENTRY("apc.user_entries_hint", "4096", PHP_INI_SYSTEM, OnUpdateInt, user_entries_hint, zend_apc_globals, apc_globals)
16220 +STD_PHP_INI_ENTRY("apc.gc_ttl", "3600", PHP_INI_SYSTEM, OnUpdateInt, gc_ttl, zend_apc_globals, apc_globals)
16221 +STD_PHP_INI_ENTRY("apc.ttl", "0", PHP_INI_SYSTEM, OnUpdateInt, ttl, zend_apc_globals, apc_globals)
16222 +STD_PHP_INI_ENTRY("apc.user_ttl", "0", PHP_INI_SYSTEM, OnUpdateInt, user_ttl, zend_apc_globals, apc_globals)
16223 +#if APC_MMAP
16224 +STD_PHP_INI_ENTRY("apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apc_globals, apc_globals)
16225 +#endif
16226 +PHP_INI_ENTRY("apc.filters", NULL, PHP_INI_SYSTEM, OnUpdate_filters)
16227 +STD_PHP_INI_BOOLEAN("apc.cache_by_default", "1", PHP_INI_ALL, OnUpdateBool, cache_by_default, zend_apc_globals, apc_globals)
16228 +STD_PHP_INI_ENTRY("apc.file_update_protection", "2", PHP_INI_SYSTEM, OnUpdateInt,file_update_protection, zend_apc_globals, apc_globals)
16229 +STD_PHP_INI_BOOLEAN("apc.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_apc_globals, apc_globals)
16230 +STD_PHP_INI_ENTRY("apc.max_file_size", "1M", PHP_INI_SYSTEM, OnUpdateInt, max_file_size, zend_apc_globals, apc_globals)
16231 +STD_PHP_INI_BOOLEAN("apc.stat", "1", PHP_INI_SYSTEM, OnUpdateBool, fpstat, zend_apc_globals, apc_globals)
16232 +STD_PHP_INI_BOOLEAN("apc.canonicalize", "1", PHP_INI_SYSTEM, OnUpdateBool, canonicalize, zend_apc_globals, apc_globals)
16233 +STD_PHP_INI_BOOLEAN("apc.stat_ctime", "0", PHP_INI_SYSTEM, OnUpdateBool, stat_ctime, zend_apc_globals, apc_globals)
16234 +STD_PHP_INI_BOOLEAN("apc.write_lock", "1", PHP_INI_SYSTEM, OnUpdateBool, write_lock, zend_apc_globals, apc_globals)
16235 +STD_PHP_INI_BOOLEAN("apc.report_autofilter", "0", PHP_INI_SYSTEM, OnUpdateBool, report_autofilter,zend_apc_globals, apc_globals)
16236 +#ifdef MULTIPART_EVENT_FORMDATA
16237 +STD_PHP_INI_BOOLEAN("apc.rfc1867", "0", PHP_INI_SYSTEM, OnUpdateBool, rfc1867, zend_apc_globals, apc_globals)
16238 +STD_PHP_INI_ENTRY("apc.rfc1867_prefix", "upload_", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_prefix, zend_apc_globals, apc_globals)
16239 +STD_PHP_INI_ENTRY("apc.rfc1867_name", "APC_UPLOAD_PROGRESS", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_name, zend_apc_globals, apc_globals)
16240 +STD_PHP_INI_ENTRY("apc.rfc1867_freq", "0", PHP_INI_SYSTEM, OnUpdateRfc1867Freq, rfc1867_freq, zend_apc_globals, apc_globals)
16241 +STD_PHP_INI_ENTRY("apc.rfc1867_ttl", "3600", PHP_INI_SYSTEM, OnUpdateInt, rfc1867_ttl, zend_apc_globals, apc_globals)
16242 +#endif
16243 +STD_PHP_INI_BOOLEAN("apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apc_globals, apc_globals)
16244 +STD_PHP_INI_ENTRY("apc.preload_path", (char*)NULL, PHP_INI_SYSTEM, OnUpdateString, preload_path, zend_apc_globals, apc_globals)
16245 +STD_PHP_INI_BOOLEAN("apc.file_md5", "0", PHP_INI_SYSTEM, OnUpdateBool, file_md5, zend_apc_globals, apc_globals)
16246 +STD_PHP_INI_BOOLEAN("apc.use_request_time", "1", PHP_INI_ALL, OnUpdateBool, use_request_time, zend_apc_globals, apc_globals)
16247 +STD_PHP_INI_BOOLEAN("apc.lazy_functions", "0", PHP_INI_SYSTEM, OnUpdateBool, lazy_functions, zend_apc_globals, apc_globals)
16248 +STD_PHP_INI_BOOLEAN("apc.lazy_classes", "0", PHP_INI_SYSTEM, OnUpdateBool, lazy_classes, zend_apc_globals, apc_globals)
16249 +PHP_INI_END()
16250 +
16251 +/* }}} */
16252 +
16253 +/* {{{ PHP_MINFO_FUNCTION(apc) */
16254 +static PHP_MINFO_FUNCTION(apc)
16255 +{
16256 + php_info_print_table_start();
16257 + php_info_print_table_header(2, "APC Support", APCG(enabled) ? "enabled" : "disabled");
16258 + php_info_print_table_row(2, "Version", PHP_APC_VERSION);
16259 +#if APC_MMAP
16260 + php_info_print_table_row(2, "MMAP Support", "Enabled");
16261 + php_info_print_table_row(2, "MMAP File Mask", APCG(mmap_file_mask));
16262 +#else
16263 + php_info_print_table_row(2, "MMAP Support", "Disabled");
16264 +#endif
16265 + php_info_print_table_row(2, "Locking type", APC_LOCK_TYPE);
16266 + php_info_print_table_row(2, "Revision", "$Revision: 286798 $");
16267 + php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__);
16268 + php_info_print_table_end();
16269 + DISPLAY_INI_ENTRIES();
16270 +}
16271 +/* }}} */
16272 +
16273 +#ifdef MULTIPART_EVENT_FORMDATA
16274 +extern int apc_rfc1867_progress(unsigned int event, void *event_data, void **extra TSRMLS_DC);
16275 +#endif
16276 +
16277 +/* {{{ PHP_MINIT_FUNCTION(apc) */
16278 +static PHP_MINIT_FUNCTION(apc)
16279 +{
16280 + ZEND_INIT_MODULE_GLOBALS(apc, php_apc_init_globals, php_apc_shutdown_globals);
16281 +
16282 + REGISTER_INI_ENTRIES();
16283 +
16284 + /* Disable APC in cli mode unless overridden by apc.enable_cli */
16285 + if(!APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) {
16286 + APCG(enabled) = 0;
16287 + }
16288 +
16289 + if (APCG(enabled)) {
16290 + if(APCG(initialized)) {
16291 + apc_process_init(module_number TSRMLS_CC);
16292 + } else {
16293 + apc_module_init(module_number TSRMLS_CC);
16294 + apc_zend_init(TSRMLS_C);
16295 + apc_process_init(module_number TSRMLS_CC);
16296 +#ifdef MULTIPART_EVENT_FORMDATA
16297 + /* File upload progress tracking */
16298 + if(APCG(rfc1867)) {
16299 + php_rfc1867_callback = apc_rfc1867_progress;
16300 + }
16301 +#endif
16302 + apc_iterator_init(module_number TSRMLS_CC);
16303 + }
16304 +
16305 + zend_register_long_constant("APC_BIN_VERIFY_MD5", sizeof("APC_BIN_VERIFY_MD5"), APC_BIN_VERIFY_MD5, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
16306 + zend_register_long_constant("APC_BIN_VERIFY_CRC32", sizeof("APC_BIN_VERIFY_CRC32"), APC_BIN_VERIFY_CRC32, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
16307 + }
16308 +
16309 + return SUCCESS;
16310 +}
16311 +/* }}} */
16312 +
16313 +/* {{{ PHP_MSHUTDOWN_FUNCTION(apc) */
16314 +static PHP_MSHUTDOWN_FUNCTION(apc)
16315 +{
16316 + if(APCG(enabled)) {
16317 + apc_process_shutdown(TSRMLS_C);
16318 + apc_zend_shutdown(TSRMLS_C);
16319 + apc_module_shutdown(TSRMLS_C);
16320 +#ifndef ZTS
16321 + php_apc_shutdown_globals(&apc_globals);
16322 +#endif
16323 +#if HAVE_SIGACTION
16324 + apc_shutdown_signals();
16325 +#endif
16326 + }
16327 +#ifdef ZTS
16328 + ts_free_id(apc_globals_id);
16329 +#endif
16330 + UNREGISTER_INI_ENTRIES();
16331 + return SUCCESS;
16332 +}
16333 +/* }}} */
16334 +
16335 +/* {{{ PHP_RINIT_FUNCTION(apc) */
16336 +static PHP_RINIT_FUNCTION(apc)
16337 +{
16338 + if(APCG(enabled)) {
16339 + apc_request_init(TSRMLS_C);
16340 +
16341 +#if HAVE_SIGACTION
16342 + apc_set_signals(TSRMLS_C);
16343 +#endif
16344 + }
16345 + return SUCCESS;
16346 +}
16347 +/* }}} */
16348 +
16349 +/* {{{ PHP_RSHUTDOWN_FUNCTION(apc) */
16350 +static PHP_RSHUTDOWN_FUNCTION(apc)
16351 +{
16352 + if(APCG(enabled)) {
16353 + apc_request_shutdown(TSRMLS_C);
16354 + }
16355 + return SUCCESS;
16356 +}
16357 +/* }}} */
16358 +
16359 +/* {{{ proto array apc_cache_info([string type [, bool limited]]) */
16360 +PHP_FUNCTION(apc_cache_info)
16361 +{
16362 + apc_cache_info_t* info;
16363 + apc_cache_link_t* p;
16364 + zval* list;
16365 + char *cache_type;
16366 + int ct_len;
16367 + zend_bool limited=0;
16368 + char md5str[33];
16369 +
16370 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &cache_type, &ct_len, &limited) == FAILURE) {
16371 + return;
16372 + }
16373 +
16374 + if(ZEND_NUM_ARGS()) {
16375 + if(!strcasecmp(cache_type,"user")) {
16376 + info = apc_cache_info(apc_user_cache, limited);
16377 + } else if(!strcasecmp(cache_type,"filehits")) {
16378 +#ifdef APC_FILEHITS
16379 + RETVAL_ZVAL(APCG(filehits), 1, 0);
16380 + return;
16381 +#else
16382 + RETURN_FALSE;
16383 +#endif
16384 + } else {
16385 + info = apc_cache_info(apc_cache, limited);
16386 + }
16387 + } else info = apc_cache_info(apc_cache, limited);
16388 +
16389 + if(!info) {
16390 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC info available. Perhaps APC is not enabled? Check apc.enabled in your ini file");
16391 + RETURN_FALSE;
16392 + }
16393 +
16394 + array_init(return_value);
16395 + add_assoc_long(return_value, "num_slots", info->num_slots);
16396 + add_assoc_long(return_value, "ttl", info->ttl);
16397 +
16398 + add_assoc_double(return_value, "num_hits", (double)info->num_hits);
16399 + add_assoc_double(return_value, "num_misses", (double)info->num_misses);
16400 + add_assoc_double(return_value, "num_inserts", (double)info->num_inserts);
16401 + add_assoc_double(return_value, "expunges", (double)info->expunges);
16402 +
16403 + add_assoc_long(return_value, "start_time", info->start_time);
16404 + add_assoc_double(return_value, "mem_size", (double)info->mem_size);
16405 + add_assoc_long(return_value, "num_entries", info->num_entries);
16406 +#ifdef MULTIPART_EVENT_FORMDATA
16407 + add_assoc_long(return_value, "file_upload_progress", 1);
16408 +#else
16409 + add_assoc_long(return_value, "file_upload_progress", 0);
16410 +#endif
16411 +#if APC_MMAP
16412 + add_assoc_stringl(return_value, "memory_type", "mmap", sizeof("mmap")-1, 1);
16413 +#else
16414 + add_assoc_stringl(return_value, "memory_type", "IPC shared", sizeof("IPC shared")-1, 1);
16415 +#endif
16416 +#if APC_SEM_LOCKS
16417 + add_assoc_stringl(return_value, "locking_type", "IPC semaphore", sizeof("IPC semaphore")-1, 1);
16418 +#elif APC_PTHREADMUTEX_LOCKS
16419 + add_assoc_stringl(return_value, "locking_type", "pthread mutex", sizeof("pthread mutex")-1, 1);
16420 +#elif APC_SPIN_LOCKS
16421 + add_assoc_stringl(return_value, "locking_type", "spin", sizeof("spin")-1, 1);
16422 +#else
16423 + add_assoc_stringl(return_value, "locking_type", "file", sizeof("file")-1, 1);
16424 +#endif
16425 + if(limited) {
16426 + apc_cache_free_info(info);
16427 + return;
16428 + }
16429 +
16430 + ALLOC_INIT_ZVAL(list);
16431 + array_init(list);
16432 +
16433 + for (p = info->list; p != NULL; p = p->next) {
16434 + zval* link;
16435 +
16436 + ALLOC_INIT_ZVAL(link);
16437 + array_init(link);
16438 +
16439 + if(p->type == APC_CACHE_ENTRY_FILE) {
16440 + add_assoc_string(link, "filename", p->data.file.filename, 1);
16441 + add_assoc_long(link, "device", p->data.file.device);
16442 + add_assoc_long(link, "inode", p->data.file.inode);
16443 + add_assoc_string(link, "type", "file", 1);
16444 + if(APCG(file_md5)) {
16445 + make_digest(md5str, p->data.file.md5);
16446 + add_assoc_string(link, "md5", md5str, 1);
16447 + }
16448 + } else if(p->type == APC_CACHE_ENTRY_USER) {
16449 + add_assoc_string(link, "info", p->data.user.info, 1);
16450 + add_assoc_long(link, "ttl", (long)p->data.user.ttl);
16451 + add_assoc_string(link, "type", "user", 1);
16452 + }
16453 +
16454 + add_assoc_double(link, "num_hits", (double)p->num_hits);
16455 +
16456 + add_assoc_long(link, "mtime", p->mtime);
16457 + add_assoc_long(link, "creation_time", p->creation_time);
16458 + add_assoc_long(link, "deletion_time", p->deletion_time);
16459 + add_assoc_long(link, "access_time", p->access_time);
16460 + add_assoc_long(link, "ref_count", p->ref_count);
16461 + add_assoc_long(link, "mem_size", p->mem_size);
16462 +
16463 +
16464 + add_next_index_zval(list, link);
16465 + }
16466 + add_assoc_zval(return_value, "cache_list", list);
16467 +
16468 + ALLOC_INIT_ZVAL(list);
16469 + array_init(list);
16470 +
16471 + for (p = info->deleted_list; p != NULL; p = p->next) {
16472 + zval* link;
16473 +
16474 + ALLOC_INIT_ZVAL(link);
16475 + array_init(link);
16476 +
16477 + if(p->type == APC_CACHE_ENTRY_FILE) {
16478 + add_assoc_string(link, "filename", p->data.file.filename, 1);
16479 + add_assoc_long(link, "device", p->data.file.device);
16480 + add_assoc_long(link, "inode", p->data.file.inode);
16481 + add_assoc_string(link, "type", "file", 1);
16482 + if(APCG(file_md5)) {
16483 + make_digest(md5str, p->data.file.md5);
16484 + add_assoc_string(link, "md5", md5str, 1);
16485 + }
16486 + } else if(p->type == APC_CACHE_ENTRY_USER) {
16487 + add_assoc_string(link, "info", p->data.user.info, 1);
16488 + add_assoc_long(link, "ttl", (long)p->data.user.ttl);
16489 + add_assoc_string(link, "type", "user", 1);
16490 + }
16491 +
16492 + add_assoc_double(link, "num_hits", (double)p->num_hits);
16493 +
16494 + add_assoc_long(link, "mtime", p->mtime);
16495 + add_assoc_long(link, "creation_time", p->creation_time);
16496 + add_assoc_long(link, "deletion_time", p->deletion_time);
16497 + add_assoc_long(link, "access_time", p->access_time);
16498 + add_assoc_long(link, "ref_count", p->ref_count);
16499 + add_assoc_long(link, "mem_size", p->mem_size);
16500 + add_next_index_zval(list, link);
16501 + }
16502 + add_assoc_zval(return_value, "deleted_list", list);
16503 +
16504 + apc_cache_free_info(info);
16505 +}
16506 +/* }}} */
16507 +
16508 +/* {{{ proto void apc_clear_cache([string cache]) */
16509 +PHP_FUNCTION(apc_clear_cache)
16510 +{
16511 + char *cache_type;
16512 + int ct_len = 0;
16513 +
16514 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &cache_type, &ct_len) == FAILURE) {
16515 + return;
16516 + }
16517 +
16518 + if(ct_len) {
16519 + if(!strcasecmp(cache_type, "user")) {
16520 + apc_cache_clear(apc_user_cache);
16521 + RETURN_TRUE;
16522 + }
16523 + }
16524 + apc_cache_clear(apc_cache);
16525 + RETURN_TRUE;
16526 +}
16527 +/* }}} */
16528 +
16529 +/* {{{ proto array apc_sma_info([bool limited]) */
16530 +PHP_FUNCTION(apc_sma_info)
16531 +{
16532 + apc_sma_info_t* info;
16533 + zval* block_lists;
16534 + int i;
16535 + zend_bool limited = 0;
16536 +
16537 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &limited) == FAILURE) {
16538 + return;
16539 + }
16540 +
16541 + info = apc_sma_info(limited);
16542 +
16543 + if(!info) {
16544 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No APC SMA info available. Perhaps APC is disabled via apc.enabled?");
16545 + RETURN_FALSE;
16546 + }
16547 +
16548 + array_init(return_value);
16549 + add_assoc_long(return_value, "num_seg", info->num_seg);
16550 + add_assoc_double(return_value, "seg_size", (double)info->seg_size);
16551 + add_assoc_double(return_value, "avail_mem", (double)apc_sma_get_avail_mem());
16552 +
16553 + if(limited) {
16554 + apc_sma_free_info(info);
16555 + return;
16556 + }
16557 +
16558 +#if ALLOC_DISTRIBUTION
16559 + {
16560 + size_t *adist = apc_sma_get_alloc_distribution();
16561 + zval* list;
16562 + ALLOC_INIT_ZVAL(list);
16563 + array_init(list);
16564 + for(i=0; i<30; i++) {
16565 + add_next_index_long(list, adist[i]);
16566 + }
16567 + add_assoc_zval(return_value, "adist", list);
16568 + }
16569 +#endif
16570 + ALLOC_INIT_ZVAL(block_lists);
16571 + array_init(block_lists);
16572 +
16573 + for (i = 0; i < info->num_seg; i++) {
16574 + apc_sma_link_t* p;
16575 + zval* list;
16576 +
16577 + ALLOC_INIT_ZVAL(list);
16578 + array_init(list);
16579 +
16580 + for (p = info->list[i]; p != NULL; p = p->next) {
16581 + zval* link;
16582 +
16583 + ALLOC_INIT_ZVAL(link);
16584 + array_init(link);
16585 +
16586 + add_assoc_long(link, "size", p->size);
16587 + add_assoc_long(link, "offset", p->offset);
16588 + add_next_index_zval(list, link);
16589 + }
16590 + add_next_index_zval(block_lists, list);
16591 + }
16592 + add_assoc_zval(return_value, "block_lists", block_lists);
16593 + apc_sma_free_info(info);
16594 +}
16595 +/* }}} */
16596 +
16597 +/* {{{ */
16598 +int _apc_update(char *strkey, int strkey_len, apc_cache_updater_t updater, void* data TSRMLS_DC)
16599 +{
16600 + if(!APCG(enabled)) {
16601 + return 0;
16602 + }
16603 +
16604 + HANDLE_BLOCK_INTERRUPTIONS();
16605 + APCG(current_cache) = apc_user_cache;
16606 +
16607 + if (!_apc_cache_user_update(apc_user_cache, strkey, strkey_len + 1, updater, data TSRMLS_CC)) {
16608 + HANDLE_UNBLOCK_INTERRUPTIONS();
16609 + return 0;
16610 + }
16611 +
16612 + APCG(current_cache) = NULL;
16613 + HANDLE_UNBLOCK_INTERRUPTIONS();
16614 +
16615 + return 1;
16616 +}
16617 +/* }}} */
16618 +
16619 +/* {{{ _apc_store */
16620 +int _apc_store(char *strkey, int strkey_len, const zval *val, const unsigned int ttl, const int exclusive TSRMLS_DC) {
16621 + apc_cache_entry_t *entry;
16622 + apc_cache_key_t key;
16623 + time_t t;
16624 + apc_context_t ctxt={0,};
16625 + int ret = 1;
16626 +
16627 + t = apc_time();
16628 +
16629 + if(!APCG(enabled)) return 0;
16630 +
16631 + HANDLE_BLOCK_INTERRUPTIONS();
16632 +
16633 + APCG(current_cache) = apc_user_cache;
16634 +
16635 + ctxt.pool = apc_pool_create(APC_SMALL_POOL, apc_sma_malloc, apc_sma_free, apc_sma_protect, apc_sma_unprotect);
16636 + if (!ctxt.pool) {
16637 + apc_wprint("Unable to allocate memory for pool.");
16638 + return 0;
16639 + }
16640 + ctxt.copy = APC_COPY_IN_USER;
16641 + ctxt.force_update = 0;
16642 +
16643 + if(!ctxt.pool) {
16644 + ret = 0;
16645 + goto nocache;
16646 + }
16647 +
16648 + if (!apc_cache_make_user_key(&key, strkey, strkey_len, t)) {
16649 + goto freepool;
16650 + }
16651 +
16652 + if (apc_cache_is_last_key(apc_user_cache, &key, t)) {
16653 + goto freepool;
16654 + }
16655 +
16656 + if (!(entry = apc_cache_make_user_entry(strkey, strkey_len, val, &ctxt, ttl))) {
16657 + goto freepool;
16658 + }
16659 +
16660 + if (!apc_cache_user_insert(apc_user_cache, key, entry, &ctxt, t, exclusive TSRMLS_CC)) {
16661 +freepool:
16662 + apc_pool_destroy(ctxt.pool);
16663 + ret = 0;
16664 + }
16665 +
16666 +nocache:
16667 +
16668 + APCG(current_cache) = NULL;
16669 +
16670 + HANDLE_UNBLOCK_INTERRUPTIONS();
16671 +
16672 + return ret;
16673 +}
16674 +/* }}} */
16675 +
16676 +/* {{{ apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const int exclusive)
16677 + */
16678 +static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const int exclusive)
16679 +{
16680 + zval *key = NULL;
16681 + zval *val = NULL;
16682 + long ttl = 0L;
16683 + HashTable *hash;
16684 + HashPosition hpos;
16685 + zval **hentry;
16686 + char *hkey=NULL;
16687 + uint hkey_len;
16688 + ulong hkey_idx;
16689 +
16690 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zl", &key, &val, &ttl) == FAILURE) {
16691 + return;
16692 + }
16693 +
16694 + if (!key) RETURN_FALSE;
16695 +
16696 + if (Z_TYPE_P(key) == IS_ARRAY) {
16697 + hash = Z_ARRVAL_P(key);
16698 + array_init(return_value);
16699 + zend_hash_internal_pointer_reset_ex(hash, &hpos);
16700 + while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
16701 + zend_hash_get_current_key_ex(hash, &hkey, &hkey_len, &hkey_idx, 0, &hpos);
16702 + if (hkey) {
16703 + /* hkey_len - 1 for consistency, because it includes '\0', while Z_STRLEN_P() doesn't */
16704 + if(!_apc_store(hkey, hkey_len - 1, *hentry, (unsigned int)ttl, exclusive TSRMLS_CC)) {
16705 + add_assoc_long_ex(return_value, hkey, hkey_len, -1); /* -1: insertion error */
16706 + }
16707 + hkey = NULL;
16708 + } else {
16709 + add_index_long(return_value, hkey_idx, -1); /* -1: insertion error */
16710 + }
16711 + zend_hash_move_forward_ex(hash, &hpos);
16712 + }
16713 + return;
16714 + } else if (Z_TYPE_P(key) == IS_STRING) {
16715 + if (!val) RETURN_FALSE;
16716 + if(_apc_store(Z_STRVAL_P(key), Z_STRLEN_P(key), val, (unsigned int)ttl, exclusive TSRMLS_CC))
16717 + RETURN_TRUE;
16718 + } else {
16719 + apc_wprint("apc_store expects key parameter to be a string or an array of key/value pairs.");
16720 + }
16721 +
16722 + RETURN_FALSE;
16723 +}
16724 +/* }}} */
16725 +
16726 +/* {{{ proto int apc_store(mixed key, mixed var [, long ttl ])
16727 + */
16728 +PHP_FUNCTION(apc_store) {
16729 + apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
16730 +}
16731 +/* }}} */
16732 +
16733 +/* {{{ proto int apc_add(mixed key, mixed var [, long ttl ])
16734 + */
16735 +PHP_FUNCTION(apc_add) {
16736 + apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
16737 +}
16738 +/* }}} */
16739 +
16740 +/* {{{ inc_updater */
16741 +
16742 +struct _inc_update_args {
16743 + long step;
16744 + long lval;
16745 +};
16746 +
16747 +static int inc_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
16748 +
16749 + struct _inc_update_args *args = (struct _inc_update_args*) data;
16750 +
16751 + zval* val = entry->data.user.val;
16752 +
16753 + if(Z_TYPE_P(val) == IS_LONG) {
16754 + Z_LVAL_P(val) += args->step;
16755 + args->lval = Z_LVAL_P(val);
16756 + return 1;
16757 + }
16758 +
16759 + return 0;
16760 +}
16761 +/* }}} */
16762 +
16763 +/* {{{ proto long apc_inc(string key [, long step [, bool& success]])
16764 + */
16765 +PHP_FUNCTION(apc_inc) {
16766 + char *strkey;
16767 + int strkey_len;
16768 + struct _inc_update_args args = {1L, -1};
16769 + zval *success = NULL;
16770 +
16771 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &strkey, &strkey_len, &(args.step), &success) == FAILURE) {
16772 + return;
16773 + }
16774 +
16775 + if(_apc_update(strkey, strkey_len, inc_updater, &args TSRMLS_CC)) {
16776 + if(success) ZVAL_TRUE(success);
16777 + RETURN_LONG(args.lval);
16778 + }
16779 +
16780 + if(success) ZVAL_FALSE(success);
16781 +
16782 + RETURN_FALSE;
16783 +}
16784 +/* }}} */
16785 +
16786 +/* {{{ proto long apc_dec(string key [, long step [, bool &success]])
16787 + */
16788 +PHP_FUNCTION(apc_dec) {
16789 + char *strkey;
16790 + int strkey_len;
16791 + struct _inc_update_args args = {1L, -1};
16792 + zval *success = NULL;
16793 +
16794 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &strkey, &strkey_len, &(args.step), &success) == FAILURE) {
16795 + return;
16796 + }
16797 +
16798 + args.step = args.step * -1;
16799 +
16800 + if(_apc_update(strkey, strkey_len, inc_updater, &args TSRMLS_CC)) {
16801 + if(success) ZVAL_TRUE(success);
16802 + RETURN_LONG(args.lval);
16803 + }
16804 +
16805 + if(success) ZVAL_FALSE(success);
16806 +
16807 + RETURN_FALSE;
16808 +}
16809 +/* }}} */
16810 +
16811 +/* {{{ cas_updater */
16812 +static int cas_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) {
16813 + long* vals = ((long*)data);
16814 + long old = vals[0];
16815 + long new = vals[1];
16816 + zval* val = entry->data.user.val;
16817 +
16818 + if(Z_TYPE_P(val) == IS_LONG) {
16819 + if(Z_LVAL_P(val) == old) {
16820 + Z_LVAL_P(val) = new;
16821 + return 1;
16822 + }
16823 + }
16824 +
16825 + return 0;
16826 +}
16827 +/* }}} */
16828 +
16829 +/* {{{ proto int apc_cas(string key, int old, int new)
16830 + */
16831 +PHP_FUNCTION(apc_cas) {
16832 + char *strkey;
16833 + int strkey_len;
16834 + long vals[2];
16835 +
16836 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &strkey, &strkey_len, &vals[0], &vals[1]) == FAILURE) {
16837 + return;
16838 + }
16839 +
16840 + if(_apc_update(strkey, strkey_len, cas_updater, &vals TSRMLS_CC)) RETURN_TRUE;
16841 + RETURN_FALSE;
16842 +}
16843 +/* }}} */
16844 +
16845 +void *apc_erealloc_wrapper(void *ptr, size_t size) {
16846 + return _erealloc(ptr, size, 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
16847 +}
16848 +
16849 +/* {{{ proto mixed apc_fetch(mixed key[, bool &success])
16850 + */
16851 +PHP_FUNCTION(apc_fetch) {
16852 + zval *key;
16853 + zval *success = NULL;
16854 + HashTable *hash;
16855 + HashPosition hpos;
16856 + zval **hentry;
16857 + zval *result;
16858 + zval *result_entry;
16859 + char *strkey;
16860 + int strkey_len;
16861 + apc_cache_entry_t* entry;
16862 + time_t t;
16863 + apc_context_t ctxt = {0,};
16864 +
16865 + if(!APCG(enabled)) RETURN_FALSE;
16866 +
16867 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &key, &success) == FAILURE) {
16868 + return;
16869 + }
16870 +
16871 + t = apc_time();
16872 +
16873 + if (success) {
16874 + ZVAL_BOOL(success, 0);
16875 + }
16876 +
16877 + ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, NULL, NULL);
16878 + if (!ctxt.pool) {
16879 + apc_wprint("Unable to allocate memory for pool.");
16880 + RETURN_FALSE;
16881 + }
16882 + ctxt.copy = APC_COPY_OUT_USER;
16883 + ctxt.force_update = 0;
16884 +
16885 + if(Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) {
16886 + convert_to_string(key);
16887 + }
16888 +
16889 + if(Z_TYPE_P(key) == IS_STRING) {
16890 + strkey = Z_STRVAL_P(key);
16891 + strkey_len = Z_STRLEN_P(key);
16892 + if(!strkey_len) RETURN_FALSE;
16893 + entry = apc_cache_user_find(apc_user_cache, strkey, strkey_len + 1, t);
16894 + if(entry) {
16895 + /* deep-copy returned shm zval to emalloc'ed return_value */
16896 + apc_cache_fetch_zval(return_value, entry->data.user.val, &ctxt);
16897 + apc_cache_release(apc_user_cache, entry);
16898 + } else {
16899 + goto freepool;
16900 + }
16901 + } else if(Z_TYPE_P(key) == IS_ARRAY) {
16902 + hash = Z_ARRVAL_P(key);
16903 + MAKE_STD_ZVAL(result);
16904 + array_init(result);
16905 + zend_hash_internal_pointer_reset_ex(hash, &hpos);
16906 + while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
16907 + if(Z_TYPE_PP(hentry) != IS_STRING) {
16908 + apc_wprint("apc_fetch() expects a string or array of strings.");
16909 + goto freepool;
16910 + }
16911 + entry = apc_cache_user_find(apc_user_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1, t);
16912 + if(entry) {
16913 + /* deep-copy returned shm zval to emalloc'ed return_value */
16914 + MAKE_STD_ZVAL(result_entry);
16915 + apc_cache_fetch_zval(result_entry, entry->data.user.val, &ctxt);
16916 + apc_cache_release(apc_user_cache, entry);
16917 + zend_hash_add(Z_ARRVAL_P(result), Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) +1, &result_entry, sizeof(zval*), NULL);
16918 + } /* don't set values we didn't find */
16919 + zend_hash_move_forward_ex(hash, &hpos);
16920 + }
16921 + RETVAL_ZVAL(result, 0, 1);
16922 + } else {
16923 + apc_wprint("apc_fetch() expects a string or array of strings.");
16924 +freepool:
16925 + apc_pool_destroy(ctxt.pool);
16926 + RETURN_FALSE;
16927 + }
16928 +
16929 + if (success) {
16930 + ZVAL_BOOL(success, 1);
16931 + }
16932 +
16933 + apc_pool_destroy(ctxt.pool);
16934 + return;
16935 +}
16936 +/* }}} */
16937 +
16938 +
16939 +/* {{{ proto mixed apc_delete(mixed keys)
16940 + */
16941 +PHP_FUNCTION(apc_delete) {
16942 + zval *keys;
16943 +
16944 + if(!APCG(enabled)) RETURN_FALSE;
16945 +
16946 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &keys) == FAILURE) {
16947 + return;
16948 + }
16949 +
16950 + if (Z_TYPE_P(keys) == IS_STRING) {
16951 + if (!Z_STRLEN_P(keys)) RETURN_FALSE;
16952 + if(apc_cache_user_delete(apc_user_cache, Z_STRVAL_P(keys), Z_STRLEN_P(keys) + 1)) {
16953 + RETURN_TRUE;
16954 + } else {
16955 + RETURN_FALSE;
16956 + }
16957 + } else if (Z_TYPE_P(keys) == IS_ARRAY) {
16958 + HashTable *hash = Z_ARRVAL_P(keys);
16959 + HashPosition hpos;
16960 + zval **hentry;
16961 + array_init(return_value);
16962 + zend_hash_internal_pointer_reset_ex(hash, &hpos);
16963 + while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
16964 + if(Z_TYPE_PP(hentry) != IS_STRING) {
16965 + apc_wprint("apc_delete() expects a string, array of strings, or APCIterator instance.");
16966 + add_next_index_zval(return_value, *hentry);
16967 + Z_ADDREF_PP(hentry);
16968 + } else if(apc_cache_user_delete(apc_user_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1) != 1) {
16969 + add_next_index_zval(return_value, *hentry);
16970 + Z_ADDREF_PP(hentry);
16971 + }
16972 + zend_hash_move_forward_ex(hash, &hpos);
16973 + }
16974 + return;
16975 + } else if (Z_TYPE_P(keys) == IS_OBJECT) {
16976 + if (apc_iterator_delete(keys TSRMLS_CC)) {
16977 + RETURN_TRUE;
16978 + } else {
16979 + RETURN_FALSE;
16980 + }
16981 + } else {
16982 + apc_wprint("apc_delete() expects a string, array of strings, or APCIterator instance.");
16983 + }
16984 +}
16985 +/* }}} */
16986 +
16987 +/* {{{ proto mixed apc_delete_file(mixed keys)
16988 + * Deletes the given files from the opcode cache.
16989 + * Accepts a string, array of strings, or APCIterator object.
16990 + * Returns True/False, or for an Array an Array of failed files.
16991 + */
16992 +PHP_FUNCTION(apc_delete_file) {
16993 + zval *keys;
16994 +
16995 + if(!APCG(enabled)) RETURN_FALSE;
16996 +
16997 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &keys) == FAILURE) {
16998 + return;
16999 + }
17000 +
17001 + if (Z_TYPE_P(keys) == IS_STRING) {
17002 + if (!Z_STRLEN_P(keys)) RETURN_FALSE;
17003 + if(apc_cache_delete(apc_cache, Z_STRVAL_P(keys), Z_STRLEN_P(keys) + 1) != 1) {
17004 + RETURN_FALSE;
17005 + } else {
17006 + RETURN_TRUE;
17007 + }
17008 + } else if (Z_TYPE_P(keys) == IS_ARRAY) {
17009 + HashTable *hash = Z_ARRVAL_P(keys);
17010 + HashPosition hpos;
17011 + zval **hentry;
17012 + array_init(return_value);
17013 + zend_hash_internal_pointer_reset_ex(hash, &hpos);
17014 + while(zend_hash_get_current_data_ex(hash, (void**)&hentry, &hpos) == SUCCESS) {
17015 + if(Z_TYPE_PP(hentry) != IS_STRING) {
17016 + apc_wprint("apc_delete_file() expects a string, array of strings, or APCIterator instance.");
17017 + add_next_index_zval(return_value, *hentry);
17018 + Z_ADDREF_PP(hentry);
17019 + } else if(apc_cache_delete(apc_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1) != 1) {
17020 + add_next_index_zval(return_value, *hentry);
17021 + Z_ADDREF_PP(hentry);
17022 + }
17023 + zend_hash_move_forward_ex(hash, &hpos);
17024 + }
17025 + return;
17026 + } else if (Z_TYPE_P(keys) == IS_OBJECT) {
17027 + if (apc_iterator_delete(keys TSRMLS_CC)) {
17028 + RETURN_TRUE;
17029 + } else {
17030 + RETURN_FALSE;
17031 + }
17032 + } else {
17033 + apc_wprint("apc_delete_file() expects a string, array of strings, or APCIterator instance.");
17034 + }
17035 +}
17036 +/* }}} */
17037 +
17038 +static void _apc_define_constants(zval *constants, zend_bool case_sensitive TSRMLS_DC) {
17039 + char *const_key;
17040 + unsigned int const_key_len;
17041 + zval **entry;
17042 + HashPosition pos;
17043 +
17044 + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(constants), &pos);
17045 + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(constants), (void**)&entry, &pos) == SUCCESS) {
17046 + zend_constant c;
17047 + int key_type;
17048 + ulong num_key;
17049 +
17050 + key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(constants), &const_key, &const_key_len, &num_key, 0, &pos);
17051 + if(key_type != HASH_KEY_IS_STRING) {
17052 + zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
17053 + continue;
17054 + }
17055 + switch(Z_TYPE_PP(entry)) {
17056 + case IS_LONG:
17057 + case IS_DOUBLE:
17058 + case IS_STRING:
17059 + case IS_BOOL:
17060 + case IS_RESOURCE:
17061 + case IS_NULL:
17062 + break;
17063 + default:
17064 + zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
17065 + continue;
17066 + }
17067 + c.value = **entry;
17068 + zval_copy_ctor(&c.value);
17069 + c.flags = case_sensitive;
17070 + c.name = zend_strndup(const_key, const_key_len);
17071 + c.name_len = const_key_len;
17072 + c.module_number = PHP_USER_CONSTANT;
17073 + zend_register_constant(&c TSRMLS_CC);
17074 +
17075 + zend_hash_move_forward_ex(Z_ARRVAL_P(constants), &pos);
17076 + }
17077 +}
17078 +
17079 +/* {{{ proto mixed apc_define_constants(string key, array constants [, bool case_sensitive])
17080 + */
17081 +PHP_FUNCTION(apc_define_constants) {
17082 + char *strkey;
17083 + int strkey_len;
17084 + zval *constants = NULL;
17085 + zend_bool case_sensitive = 1;
17086 + int argc = ZEND_NUM_ARGS();
17087 +
17088 + if (zend_parse_parameters(argc TSRMLS_CC, "sa|b", &strkey, &strkey_len, &constants, &case_sensitive) == FAILURE) {
17089 + return;
17090 + }
17091 +
17092 + if(!strkey_len) RETURN_FALSE;
17093 +
17094 + _apc_define_constants(constants, case_sensitive TSRMLS_CC);
17095 + if(_apc_store(strkey, strkey_len, constants, 0, 0 TSRMLS_CC)) RETURN_TRUE;
17096 + RETURN_FALSE;
17097 +} /* }}} */
17098 +
17099 +/* {{{ proto mixed apc_load_constants(string key [, bool case_sensitive])
17100 + */
17101 +PHP_FUNCTION(apc_load_constants) {
17102 + char *strkey;
17103 + int strkey_len;
17104 + apc_cache_entry_t* entry;
17105 + time_t t;
17106 + zend_bool case_sensitive = 1;
17107 +
17108 + if(!APCG(enabled)) RETURN_FALSE;
17109 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &strkey, &strkey_len, &case_sensitive) == FAILURE) {
17110 + return;
17111 + }
17112 +
17113 + if(!strkey_len) RETURN_FALSE;
17114 +
17115 + t = apc_time();
17116 +
17117 + entry = apc_cache_user_find(apc_user_cache, strkey, strkey_len + 1, t);
17118 +
17119 + if(entry) {
17120 + _apc_define_constants(entry->data.user.val, case_sensitive TSRMLS_CC);
17121 + apc_cache_release(apc_user_cache, entry);
17122 + RETURN_TRUE;
17123 + } else {
17124 + RETURN_FALSE;
17125 + }
17126 +}
17127 +/* }}} */
17128 +
17129 +/* {{{ proto mixed apc_compile_file(mixed filenames [, bool atomic])
17130 + */
17131 +PHP_FUNCTION(apc_compile_file) {
17132 + zval *file;
17133 + zend_file_handle file_handle;
17134 + zend_op_array *op_array;
17135 + char** filters = NULL;
17136 + zend_bool cache_by_default = 1;
17137 + HashTable cg_function_table, cg_class_table;
17138 + HashTable *cg_orig_function_table, *cg_orig_class_table, *eg_orig_function_table, *eg_orig_class_table;
17139 + apc_cache_entry_t** cache_entries;
17140 + apc_cache_key_t* keys;
17141 + zend_op_array **op_arrays;
17142 + time_t t;
17143 + zval **hentry;
17144 + HashPosition hpos;
17145 + int i=0, c=0;
17146 + int *rval=NULL;
17147 + int count=0;
17148 + zend_bool atomic=1;
17149 + apc_context_t ctxt = {0,};
17150 + zend_execute_data *orig_current_execute_data;
17151 + int atomic_fail;
17152 +
17153 + if(!APCG(enabled)) RETURN_FALSE;
17154 +
17155 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &file, &atomic) == FAILURE) {
17156 + return;
17157 + }
17158 +
17159 + if (Z_TYPE_P(file) != IS_ARRAY && Z_TYPE_P(file) != IS_STRING) {
17160 + apc_wprint("apc_compile_file argument must be a string or an array of strings");
17161 + RETURN_FALSE;
17162 + }
17163 +
17164 + HANDLE_BLOCK_INTERRUPTIONS();
17165 + APCG(current_cache) = apc_cache;
17166 +
17167 + /* reset filters and cache_by_default */
17168 + filters = APCG(filters);
17169 + APCG(filters) = NULL;
17170 +
17171 + cache_by_default = APCG(cache_by_default);
17172 + APCG(cache_by_default) = 1;
17173 +
17174 + /* Replace function/class tables to avoid namespace conflicts */
17175 + zend_hash_init_ex(&cg_function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
17176 + cg_orig_function_table = CG(function_table);
17177 + CG(function_table) = &cg_function_table;
17178 + zend_hash_init_ex(&cg_class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
17179 + cg_orig_class_table = CG(class_table);
17180 + CG(class_table) = &cg_class_table;
17181 + eg_orig_function_table = EG(function_table);
17182 + EG(function_table) = CG(function_table);
17183 + eg_orig_class_table = EG(class_table);
17184 + EG(class_table) = CG(class_table);
17185 + APCG(force_file_update) = 1;
17186 +
17187 + /* Compile the file(s), loading it into the cache */
17188 + if (Z_TYPE_P(file) == IS_STRING) {
17189 + file_handle.type = ZEND_HANDLE_FILENAME;
17190 + file_handle.filename = Z_STRVAL_P(file);
17191 + file_handle.free_filename = 0;
17192 + file_handle.opened_path = NULL;
17193 +
17194 + orig_current_execute_data = EG(current_execute_data);
17195 + zend_try {
17196 + op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC);
17197 + } zend_catch {
17198 + EG(current_execute_data) = orig_current_execute_data;
17199 + EG(in_execution) = 1;
17200 + CG(unclean_shutdown) = 0;
17201 + apc_wprint("Error compiling %s in apc_compile_file.", file_handle.filename);
17202 + op_array = NULL;
17203 + } zend_end_try();
17204 + if(op_array != NULL) {
17205 + /* Free up everything */
17206 + destroy_op_array(op_array TSRMLS_CC);
17207 + efree(op_array);
17208 + RETVAL_TRUE;
17209 + } else {
17210 + RETVAL_FALSE;
17211 + }
17212 + zend_destroy_file_handle(&file_handle TSRMLS_CC);
17213 +
17214 + } else { /* IS_ARRAY */
17215 +
17216 + array_init(return_value);
17217 +
17218 + t = apc_time();
17219 +
17220 + op_arrays = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(zend_op_array*));
17221 + cache_entries = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(apc_cache_entry_t*));
17222 + keys = ecalloc(Z_ARRVAL_P(file)->nNumOfElements, sizeof(apc_cache_key_t));
17223 + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(file), &hpos);
17224 + while(zend_hash_get_current_data_ex(Z_ARRVAL_P(file), (void**)&hentry, &hpos) == SUCCESS) {
17225 + if (Z_TYPE_PP(hentry) != IS_STRING) {
17226 + apc_wprint("apc_compile_file array values must be strings, aborting.");
17227 + break;
17228 + }
17229 + file_handle.type = ZEND_HANDLE_FILENAME;
17230 + file_handle.filename = Z_STRVAL_PP(hentry);
17231 + file_handle.free_filename = 0;
17232 + file_handle.opened_path = NULL;
17233 +
17234 + if (!apc_cache_make_file_key(&(keys[i]), file_handle.filename, PG(include_path), t TSRMLS_CC)) {
17235 + add_assoc_long(return_value, Z_STRVAL_PP(hentry), -1); /* -1: compilation error */
17236 + apc_wprint("Error compiling %s in apc_compile_file.", file_handle.filename);
17237 + break;
17238 + }
17239 +
17240 + if (keys[i].type == APC_CACHE_KEY_FPFILE) {
17241 + keys[i].data.fpfile.fullpath = estrndup(keys[i].data.fpfile.fullpath, keys[i].data.fpfile.fullpath_len);
17242 + } else if (keys[i].type == APC_CACHE_KEY_USER) {
17243 + keys[i].data.user.identifier = estrndup(keys[i].data.user.identifier, keys[i].data.user.identifier_len);
17244 + }
17245 +
17246 + orig_current_execute_data = EG(current_execute_data);
17247 + zend_try {
17248 + if (apc_compile_cache_entry(keys[i], &file_handle, ZEND_INCLUDE, t, &op_arrays[i], &cache_entries[i] TSRMLS_CC) != SUCCESS) {
17249 + op_arrays[i] = NULL;
17250 + cache_entries[i] = NULL;
17251 + add_assoc_long(return_value, Z_STRVAL_PP(hentry), -2); /* -2: input or cache insertion error */
17252 + apc_wprint("Error compiling %s in apc_compile_file.", file_handle.filename);
17253 + }
17254 + } zend_catch {
17255 + EG(current_execute_data) = orig_current_execute_data;
17256 + EG(in_execution) = 1;
17257 + CG(unclean_shutdown) = 0;
17258 + op_arrays[i] = NULL;
17259 + cache_entries[i] = NULL;
17260 + add_assoc_long(return_value, Z_STRVAL_PP(hentry), -1); /* -1: compilation error */
17261 + apc_wprint("Error compiling %s in apc_compile_file.", file_handle.filename);
17262 + } zend_end_try();
17263 +
17264 + zend_destroy_file_handle(&file_handle TSRMLS_CC);
17265 + if(op_arrays[i] != NULL) {
17266 + count++;
17267 + }
17268 +
17269 + /* clean out the function/class tables */
17270 + zend_hash_clean(&cg_function_table);
17271 + zend_hash_clean(&cg_class_table);
17272 +
17273 + zend_hash_move_forward_ex(Z_ARRVAL_P(file), &hpos);
17274 + i++;
17275 + }
17276 +
17277 + /* atomically update the cache if no errors or not atomic */
17278 + ctxt.copy = APC_COPY_IN_OPCODE;
17279 + ctxt.force_update = 1;
17280 + if (count == i || !atomic) {
17281 + rval = apc_cache_insert_mult(apc_cache, keys, cache_entries, &ctxt, t, i);
17282 + atomic_fail = 0;
17283 + } else {
17284 + atomic_fail = 1;
17285 + }
17286 +
17287 + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(file), &hpos);
17288 + for(c=0; c < i; c++) {
17289 + zend_hash_get_current_data_ex(Z_ARRVAL_P(file), (void**)&hentry, &hpos);
17290 + if (rval && rval[c] != 1) {
17291 + add_assoc_long(return_value, Z_STRVAL_PP(hentry), -2); /* -2: input or cache insertion error */
17292 + if (cache_entries[c]) {
17293 + apc_pool_destroy(cache_entries[c]->pool);
17294 + }
17295 + }
17296 + if (op_arrays[c]) {
17297 + destroy_op_array(op_arrays[c] TSRMLS_CC);
17298 + efree(op_arrays[c]);
17299 + }
17300 + if (atomic_fail && cache_entries[c]) {
17301 + apc_pool_destroy(cache_entries[c]->pool);
17302 + }
17303 + if (keys[c].type == APC_CACHE_KEY_FPFILE) {
17304 + efree((void*)keys[c].data.fpfile.fullpath);
17305 + } else if (keys[c].type == APC_CACHE_KEY_USER) {
17306 + efree((void*)keys[c].data.user.identifier);
17307 + }
17308 + zend_hash_move_forward_ex(Z_ARRVAL_P(file), &hpos);
17309 + }
17310 + efree(op_arrays);
17311 + efree(keys);
17312 + efree(cache_entries);
17313 + if (rval) {
17314 + efree(rval);
17315 + }
17316 +
17317 + }
17318 +
17319 + /* Return class/function tables to previous states, destroy temp tables */
17320 + APCG(force_file_update) = 0;
17321 + CG(function_table) = cg_orig_function_table;
17322 + zend_hash_destroy(&cg_function_table);
17323 + CG(class_table) = cg_orig_class_table;
17324 + zend_hash_destroy(&cg_class_table);
17325 + EG(function_table) = eg_orig_function_table;
17326 + EG(class_table) = eg_orig_class_table;
17327 +
17328 + /* Restore global settings */
17329 + APCG(filters) = filters;
17330 + APCG(cache_by_default) = cache_by_default;
17331 +
17332 + APCG(current_cache) = NULL;
17333 + HANDLE_UNBLOCK_INTERRUPTIONS();
17334 +
17335 +}
17336 +/* }}} */
17337 +
17338 +/* {{{ proto mixed apc_bin_dump([array files [, array user_vars]])
17339 + Returns a binary dump of the given files and user variables from the APC cache.
17340 + A NULL for files or user_vars signals a dump of every entry, while array() will dump nothing.
17341 + */
17342 +PHP_FUNCTION(apc_bin_dump) {
17343 +
17344 + zval *z_files, *z_user_vars;
17345 + HashTable *h_files, *h_user_vars;
17346 + apc_bd_t *bd;
17347 +
17348 + if(!APCG(enabled)) {
17349 + apc_wprint("APC is not enabled, apc_bin_dump not available.");
17350 + RETURN_FALSE;
17351 + }
17352 +
17353 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!a!", &z_files, &z_user_vars) == FAILURE) {
17354 + return;
17355 + }
17356 +
17357 + h_files = z_files ? Z_ARRVAL_P(z_files) : NULL;
17358 + h_user_vars = z_user_vars ? Z_ARRVAL_P(z_user_vars) : NULL;
17359 + bd = apc_bin_dump(h_files, h_user_vars TSRMLS_CC);
17360 + if(bd) {
17361 + RETVAL_STRINGL((char*)bd, bd->size-1, 0);
17362 + } else {
17363 + apc_eprint("Unkown error encounterd during apc_bin_dump.");
17364 + RETVAL_NULL();
17365 + }
17366 +
17367 + return;
17368 +}
17369 +
17370 +/* {{{ proto mixed apc_bin_dumpfile(array files, array user_vars, string filename, [int flags [, resource context]])
17371 + Output a binary dump of the given files and user variables from the APC cache to the named file.
17372 + */
17373 +PHP_FUNCTION(apc_bin_dumpfile) {
17374 +
17375 + zval *z_files, *z_user_vars;
17376 + HashTable *h_files, *h_user_vars;
17377 + char *filename;
17378 + int filename_len;
17379 + long flags=0;
17380 + zval *zcontext = NULL;
17381 + php_stream_context *context = NULL;
17382 + php_stream *stream;
17383 + int numbytes = 0;
17384 + apc_bd_t *bd;
17385 +
17386 + if(!APCG(enabled)) {
17387 + apc_wprint("APC is not enabled, apc_bin_dumpfile not available.");
17388 + RETURN_FALSE;
17389 + }
17390 +
17391 +
17392 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!s|lr!", &z_files, &z_user_vars, &filename, &filename_len, &flags, &zcontext) == FAILURE) {
17393 + return;
17394 + }
17395 +
17396 + if(!filename_len) {
17397 + apc_eprint("apc_bin_dumpfile filename argument must be a valid filename.");
17398 + RETURN_FALSE;
17399 + }
17400 +
17401 + h_files = z_files ? Z_ARRVAL_P(z_files) : NULL;
17402 + h_user_vars = z_user_vars ? Z_ARRVAL_P(z_user_vars) : NULL;
17403 + bd = apc_bin_dump(h_files, h_user_vars TSRMLS_CC);
17404 + if(!bd) {
17405 + apc_eprint("Unkown error uncountered during apc binary dump.");
17406 + RETURN_FALSE;
17407 + }
17408 +
17409 +
17410 + /* Most of the following has been taken from the file_get/put_contents functions */
17411 +
17412 + context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
17413 + stream = php_stream_open_wrapper_ex(filename, (flags & PHP_FILE_APPEND) ? "ab" : "wb",
17414 + ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
17415 + if (stream == NULL) {
17416 + efree(bd);
17417 + apc_eprint("Unable to write to file in apc_bin_dumpfile.");
17418 + RETURN_FALSE;
17419 + }
17420 +
17421 + if (flags & LOCK_EX && php_stream_lock(stream, LOCK_EX)) {
17422 + php_stream_close(stream);
17423 + efree(bd);
17424 + apc_eprint("Unable to get a lock on file in apc_bin_dumpfile.");
17425 + RETURN_FALSE;
17426 + }
17427 +
17428 + numbytes = php_stream_write(stream, (char*)bd, bd->size);
17429 + if(numbytes != bd->size) {
17430 + numbytes = -1;
17431 + }
17432 +
17433 + php_stream_close(stream);
17434 + efree(bd);
17435 +
17436 + if(numbytes < 0) {
17437 + apc_wprint("Only %d of %d bytes written, possibly out of free disk space", numbytes, bd->size);
17438 + RETURN_FALSE;
17439 + }
17440 +
17441 + RETURN_LONG(numbytes);
17442 +}
17443 +
17444 +/* {{{ proto mixed apc_bin_load(string data, [int flags])
17445 + Load the given binary dump into the APC file/user cache.
17446 + */
17447 +PHP_FUNCTION(apc_bin_load) {
17448 +
17449 + int data_len;
17450 + char *data;
17451 + long flags = 0;
17452 +
17453 + if(!APCG(enabled)) {
17454 + apc_wprint("APC is not enabled, apc_bin_load not available.");
17455 + RETURN_FALSE;
17456 + }
17457 +
17458 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags) == FAILURE) {
17459 + return;
17460 + }
17461 +
17462 + if(!data_len || data_len != ((apc_bd_t*)data)->size -1) {
17463 + apc_eprint("apc_bin_load string argument does not appear to be a valid APC binary dump due to size (%d vs expected %d).", data_len, ((apc_bd_t*)data)->size -1);
17464 + RETURN_FALSE;
17465 + }
17466 +
17467 + apc_bin_load((apc_bd_t*)data, (int)flags TSRMLS_CC);
17468 +
17469 + RETURN_TRUE;
17470 +}
17471 +
17472 +/* {{{ proto mixed apc_bin_loadfile(string filename, [resource context, [int flags]])
17473 + Load the given binary dump from the named file into the APC file/user cache.
17474 + */
17475 +PHP_FUNCTION(apc_bin_loadfile) {
17476 +
17477 + char *filename;
17478 + int filename_len;
17479 + zval *zcontext = NULL;
17480 + long flags;
17481 + php_stream_context *context = NULL;
17482 + php_stream *stream;
17483 + char *data;
17484 + int len;
17485 +
17486 + if(!APCG(enabled)) {
17487 + apc_wprint("APC is not enabled, apc_bin_loadfile not available.");
17488 + RETURN_FALSE;
17489 + }
17490 +
17491 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r!l", &filename, &filename_len, &zcontext, &flags) == FAILURE) {
17492 + return;
17493 + }
17494 +
17495 + if(!filename_len) {
17496 + apc_eprint("apc_bin_loadfile filename argument must be a valid filename.");
17497 + RETURN_FALSE;
17498 + }
17499 +
17500 + context = php_stream_context_from_zval(zcontext, 0);
17501 + stream = php_stream_open_wrapper_ex(filename, "rb",
17502 + ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
17503 + if (!stream) {
17504 + apc_eprint("Unable to read from file in apc_bin_loadfile.");
17505 + RETURN_FALSE;
17506 + }
17507 +
17508 + len = php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0);
17509 + if(len == 0) {
17510 + apc_wprint("File passed to apc_bin_loadfile was empty: %s.", filename);
17511 + RETURN_FALSE;
17512 + } else if(len < 0) {
17513 + apc_wprint("Error reading file passed to apc_bin_loadfile: %s.", filename);
17514 + RETURN_FALSE;
17515 + } else if(len != ((apc_bd_t*)data)->size) {
17516 + apc_wprint("file passed to apc_bin_loadfile does not appear to be valid due to size (%d vs expected %d).", len, ((apc_bd_t*)data)->size -1);
17517 + RETURN_FALSE;
17518 + }
17519 + php_stream_close(stream);
17520 +
17521 + apc_bin_load((apc_bd_t*)data, (int)flags TSRMLS_CC);
17522 + efree(data);
17523 +
17524 + RETURN_TRUE;
17525 +}
17526 +/* }}} */
17527 +
17528 +/* {{{ arginfo */
17529 +#if (PHP_MAJOR_VERSION >= 6 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3))
17530 +# define PHP_APC_ARGINFO
17531 +#else
17532 +# define PHP_APC_ARGINFO static
17533 +#endif
17534 +
17535 +PHP_APC_ARGINFO
17536 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_store, 0, 0, 2)
17537 + ZEND_ARG_INFO(0, key)
17538 + ZEND_ARG_INFO(0, var)
17539 + ZEND_ARG_INFO(0, ttl)
17540 +ZEND_END_ARG_INFO()
17541 +
17542 +PHP_APC_ARGINFO
17543 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_clear_cache, 0, 0, 0)
17544 + ZEND_ARG_INFO(0, info)
17545 +ZEND_END_ARG_INFO()
17546 +
17547 +PHP_APC_ARGINFO
17548 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_cache_info, 0, 0, 0)
17549 + ZEND_ARG_INFO(0, type)
17550 + ZEND_ARG_INFO(0, limited)
17551 +ZEND_END_ARG_INFO()
17552 +
17553 +PHP_APC_ARGINFO
17554 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_define_constants, 0, 0, 2)
17555 + ZEND_ARG_INFO(0, key)
17556 + ZEND_ARG_INFO(0, constants)
17557 + ZEND_ARG_INFO(0, case_sensitive)
17558 +ZEND_END_ARG_INFO()
17559 +
17560 +PHP_APC_ARGINFO
17561 +ZEND_BEGIN_ARG_INFO(arginfo_apc_delete_file, 0)
17562 + ZEND_ARG_INFO(0, keys)
17563 +ZEND_END_ARG_INFO()
17564 +
17565 +PHP_APC_ARGINFO
17566 +ZEND_BEGIN_ARG_INFO(arginfo_apc_delete, 0)
17567 + ZEND_ARG_INFO(0, keys)
17568 +ZEND_END_ARG_INFO()
17569 +
17570 +PHP_APC_ARGINFO
17571 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_fetch, 0, 0, 1)
17572 + ZEND_ARG_INFO(0, key)
17573 + ZEND_ARG_INFO(1, success)
17574 +ZEND_END_ARG_INFO()
17575 +
17576 +PHP_APC_ARGINFO
17577 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_inc, 0, 0, 1)
17578 + ZEND_ARG_INFO(0, key)
17579 + ZEND_ARG_INFO(0, step)
17580 + ZEND_ARG_INFO(1, success)
17581 +ZEND_END_ARG_INFO()
17582 +
17583 +PHP_APC_ARGINFO
17584 +ZEND_BEGIN_ARG_INFO(arginfo_apc_cas, 0)
17585 + ZEND_ARG_INFO(0, key)
17586 + ZEND_ARG_INFO(0, old)
17587 + ZEND_ARG_INFO(0, new)
17588 +ZEND_END_ARG_INFO()
17589 +
17590 +PHP_APC_ARGINFO
17591 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_load_constants, 0, 0, 1)
17592 + ZEND_ARG_INFO(0, key)
17593 + ZEND_ARG_INFO(0, case_sensitive)
17594 +ZEND_END_ARG_INFO()
17595 +
17596 +PHP_APC_ARGINFO
17597 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_compile_file, 0, 0, 1)
17598 + ZEND_ARG_INFO(0, filenames)
17599 + ZEND_ARG_INFO(0, atomic)
17600 +ZEND_END_ARG_INFO()
17601 +
17602 +PHP_APC_ARGINFO
17603 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_dump, 0, 0, 0)
17604 + ZEND_ARG_INFO(0, files)
17605 + ZEND_ARG_INFO(0, user_vars)
17606 +ZEND_END_ARG_INFO()
17607 +
17608 +PHP_APC_ARGINFO
17609 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_dumpfile, 0, 0, 3)
17610 + ZEND_ARG_INFO(0, files)
17611 + ZEND_ARG_INFO(0, user_vars)
17612 + ZEND_ARG_INFO(0, filename)
17613 + ZEND_ARG_INFO(0, flags)
17614 + ZEND_ARG_INFO(0, context)
17615 +ZEND_END_ARG_INFO()
17616 +
17617 +PHP_APC_ARGINFO
17618 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_load, 0, 0, 1)
17619 + ZEND_ARG_INFO(0, data)
17620 + ZEND_ARG_INFO(0, flags)
17621 +ZEND_END_ARG_INFO()
17622 +
17623 +PHP_APC_ARGINFO
17624 +ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_bin_loadfile, 0, 0, 1)
17625 + ZEND_ARG_INFO(0, filename)
17626 + ZEND_ARG_INFO(0, context)
17627 + ZEND_ARG_INFO(0, flags)
17628 +ZEND_END_ARG_INFO()
17629 +/* }}} */
17630 +
17631 +/* {{{ apc_functions[] */
17632 +function_entry apc_functions[] = {
17633 + PHP_FE(apc_cache_info, arginfo_apc_cache_info)
17634 + PHP_FE(apc_clear_cache, arginfo_apc_clear_cache)
17635 + PHP_FE(apc_sma_info, arginfo_apc_clear_cache)
17636 + PHP_FE(apc_store, arginfo_apc_store)
17637 + PHP_FE(apc_fetch, arginfo_apc_fetch)
17638 + PHP_FE(apc_delete, arginfo_apc_delete)
17639 + PHP_FE(apc_delete_file, arginfo_apc_delete_file)
17640 + PHP_FE(apc_define_constants, arginfo_apc_define_constants)
17641 + PHP_FE(apc_load_constants, arginfo_apc_load_constants)
17642 + PHP_FE(apc_compile_file, arginfo_apc_compile_file)
17643 + PHP_FE(apc_add, arginfo_apc_store)
17644 + PHP_FE(apc_inc, arginfo_apc_inc)
17645 + PHP_FE(apc_dec, arginfo_apc_inc)
17646 + PHP_FE(apc_cas, arginfo_apc_cas)
17647 + PHP_FE(apc_bin_dump, arginfo_apc_bin_dump)
17648 + PHP_FE(apc_bin_load, arginfo_apc_bin_load)
17649 + PHP_FE(apc_bin_dumpfile, arginfo_apc_bin_dumpfile)
17650 + PHP_FE(apc_bin_loadfile, arginfo_apc_bin_loadfile)
17651 + {NULL, NULL, NULL}
17652 +};
17653 +/* }}} */
17654 +
17655 +/* {{{ module definition structure */
17656 +
17657 +zend_module_entry apc_module_entry = {
17658 + STANDARD_MODULE_HEADER,
17659 + "apc",
17660 + apc_functions,
17661 + PHP_MINIT(apc),
17662 + PHP_MSHUTDOWN(apc),
17663 + PHP_RINIT(apc),
17664 + PHP_RSHUTDOWN(apc),
17665 + PHP_MINFO(apc),
17666 + PHP_APC_VERSION,
17667 + STANDARD_MODULE_PROPERTIES
17668 +};
17669 +
17670 +#ifdef COMPILE_DL_APC
17671 +ZEND_GET_MODULE(apc)
17672 +#endif
17673 +/* }}} */
17674 +
17675 +/*
17676 + * Local variables:
17677 + * tab-width: 4
17678 + * c-basic-offset: 4
17679 + * End:
17680 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
17681 + * vim<600: expandtab sw=4 ts=4 sts=4
17682 + */
17683 diff -Naur php-5.3.1.orig/ext/apc/php_apc.h php-5.3.1/ext/apc/php_apc.h
17684 --- php-5.3.1.orig/ext/apc/php_apc.h 1970-01-01 01:00:00.000000000 +0100
17685 +++ php-5.3.1/ext/apc/php_apc.h 1970-01-01 10:13:08.000000000 +0100
17686 @@ -0,0 +1,54 @@
17687 +/*
17688 + +----------------------------------------------------------------------+
17689 + | APC |
17690 + +----------------------------------------------------------------------+
17691 + | Copyright (c) 2006-2008 The PHP Group |
17692 + +----------------------------------------------------------------------+
17693 + | This source file is subject to version 3.01 of the PHP license, |
17694 + | that is bundled with this package in the file LICENSE, and is |
17695 + | available through the world-wide-web at the following url: |
17696 + | http://www.php.net/license/3_01.txt |
17697 + | If you did not receive a copy of the PHP license and are unable to |
17698 + | obtain it through the world-wide-web, please send a note to |
17699 + | license@php.net so we can mail you a copy immediately. |
17700 + +----------------------------------------------------------------------+
17701 + | Authors: Daniel Cowgill <dcowgill@communityconnect.com> |
17702 + | George Schlossnagle <george@omniti.com> |
17703 + | Rasmus Lerdorf <rasmus@php.net> |
17704 + +----------------------------------------------------------------------+
17705 +
17706 + This software was contributed to PHP by Community Connect Inc. in 2002
17707 + and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
17708 + Future revisions and derivatives of this source code must acknowledge
17709 + Community Connect Inc. as the original contributor of this module by
17710 + leaving this note intact in the source code.
17711 +
17712 + All other licensing and usage conditions are those of the PHP Group.
17713 +
17714 + */
17715 +
17716 +/* $Id: php_apc.h 287286 2009-08-14 10:50:22Z gopalv $ */
17717 +
17718 +#ifndef PHP_APC_H
17719 +#define PHP_APC_H
17720 +
17721 +#include "apc_php.h"
17722 +#include "apc_globals.h"
17723 +
17724 +#define PHP_APC_VERSION "3.1.3p1"
17725 +
17726 +extern zend_module_entry apc_module_entry;
17727 +#define apc_module_ptr &apc_module_entry
17728 +
17729 +#define phpext_apc_ptr apc_module_ptr
17730 +
17731 +#endif /* PHP_APC_H */
17732 +
17733 +/*
17734 + * Local variables:
17735 + * tab-width: 4
17736 + * c-basic-offset: 4
17737 + * End:
17738 + * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
17739 + * vim<600: expandtab sw=4 ts=4 sts=4
17740 + */
17741 diff -Naur php-5.3.1.orig/ext/apc/TECHNOTES.txt php-5.3.1/ext/apc/TECHNOTES.txt
17742 --- php-5.3.1.orig/ext/apc/TECHNOTES.txt 1970-01-01 01:00:00.000000000 +0100
17743 +++ php-5.3.1/ext/apc/TECHNOTES.txt 1970-01-01 10:13:08.000000000 +0100
17744 @@ -0,0 +1,361 @@
17745 +APC Quick-Start Braindump
17746 +
17747 +This is a rapidly written braindump of how APC currently works in the
17748 +form of a quick-start guide to start hacking on APC.
17749 +
17750 +1. Install and use APC a bit so you know what it does from the end-user's
17751 + perspective.
17752 + user-space functions are all explained here:
17753 +
17754 +2. Grab the current APC code from CVS:
17755 +
17756 + cvs -d:pserver:cvsread@cvs.php.net:/repository login
17757 + Password: phpfi
17758 + cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/apc
17759 +
17760 + apc/php_apc.c has most of the code for the user-visible stuff. It is
17761 + also a regular PHP extension in the sense that there are MINIT, MINFO,
17762 + MSHUTDOWN, RSHUTDOWN, etc. functions.
17763 +
17764 +3. Build it.
17765 +
17766 + cd pecl/apc
17767 + phpize
17768 + ./configure --enable-apc --enable-mmap
17769 + make
17770 + cp modules/apc.so /usr/local/lib/php
17771 + apachectl restart
17772 +
17773 +4. Debugging Hints
17774 +
17775 + apachectl stop
17776 + gdb /usr/bin/httpd
17777 + break ??
17778 + run -X
17779 +
17780 + Grab the .gdbinit from the PHP source tree and have a look at the macros.
17781 +
17782 +5. Look through apc/apc_sma.c
17783 + It is a pretty standard memory allocator.
17784 +
17785 + apc_sma_malloc, apc_sma_realloc, apc_sma_strdup and apc_sma_free behave to the
17786 + caller just like malloc, realloc, strdup and free
17787 +
17788 + On server startup the MINIT hook in php_apc.c calls apc_module_init() in
17789 + apc_main.c which in turn calls apc_sma_init(). apc_sma_init calls into
17790 + apc_mmap.c to mmap the specified sized segment (I tend to just use a single
17791 + segment). apc_mmap.c should be self-explanatory. It mmaps a temp file and
17792 + then unlinks that file right after the mmap to provide automatic shared memory
17793 + cleanup in case the process dies.
17794 +
17795 + Once the region has been initialized we stick a header_t at the beginning
17796 + of the region. It contains the total size in header->segsize and the number
17797 + of bytes available in header->avail.
17798 +
17799 + After the header comes a bit of a hack. A zero-sized block is inserted just
17800 + to make things easier later on. And then a huge block that is basically
17801 + the size of the entire segment minus the two (for the 0-sized block, and this one)
17802 + block headers.
17803 +
17804 + The code for this is:
17805 +
17806 + header = (header_t*) shmaddr;
17807 + header->segsize = sma_segsize;
17808 + header->avail = sma_segsize - sizeof(header_t) - sizeof(block_t) - alignword(sizeof(int));
17809 + memset(&header->lock,0,sizeof(header->lock));
17810 + sma_lock = &header->lock;
17811 + block = BLOCKAT(sizeof(header_t));
17812 + block->size = 0;
17813 + block->next = sizeof(header_t) + sizeof(block_t);
17814 + block = BLOCKAT(block->next);
17815 + block->size = header->avail;
17816 + block->next = 0;
17817 +
17818 + So the shared memory looks like this:
17819 +
17820 + +--------+-------+---------------------------------+
17821 + | header | block | block |
17822 + +--------+-------+---------------------------------+
17823 +
17824 + sma_shmaddrs[0] gives you the address of header
17825 +
17826 + The blocks are just a simple offset-based linked list (so no pointers):
17827 +
17828 + typedef struct block_t block_t;
17829 + struct block_t {
17830 + size_t size; /* size of this block */
17831 + size_t next; /* offset in segment of next free block */
17832 + size_t canary; /* canary to check for memory overwrites */
17833 +#ifdef __APC_SMA_DEBUG__
17834 + int id; /* identifier for the memory block */
17835 +#endif
17836 + };
17837 +
17838 + The BLOCKAT macro turns an offset into an actual address for you:
17839 +
17840 + #define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset))
17841 +
17842 + where shmaddr = sma_shaddrs[0]
17843 +
17844 + And the OFFSET macro goes the other way:
17845 +
17846 + #define OFFSET(block) ((int)(((char*)block) - (char*)shmaddr))
17847 +
17848 + Allocating a block with a call to apc_sma_allocate() walks through the
17849 + linked list of blocks until it finds one that is >= to the requested size.
17850 + The first call to apc_sma_allocate() will hit the second block. We then
17851 + chop up that block so it looks like this:
17852 +
17853 + +--------+-------+-------+-------------------------+
17854 + | header | block | block | block |
17855 + +--------+-------+-------+-------------------------+
17856 +
17857 + Then we unlink that block from the linked list so it won't show up
17858 + as an available block on the next allocate. So we actually have:
17859 +
17860 + +--------+-------+ +-------------------------+
17861 + | header | block |------>| block |
17862 + +--------+-------+ +-------------------------+
17863 +
17864 + And header->avail along with block->size of the remaining large
17865 + block are updated accordingly. The arrow there representing the
17866 + link which now points to a block with an offset further along in
17867 + the segment.
17868 +
17869 + When the block is freed using apc_sma_deallocate() the steps are
17870 + basically just reversed. The block is put back and then the deallocate
17871 + code looks at the block before and after to see if the block immediately
17872 + before and after are free and if so the blocks are combined. So you never
17873 + have 2 free blocks next to each other, apart from at the front with that
17874 + 0-sized dummy block. This mostly prevents fragmentation. I have been
17875 + toying with the idea of always allocating block at 2^n boundaries to make
17876 + it more likely that they will be re-used to cut down on fragmentation further.
17877 + That's what the POWER_OF_TWO_BLOCKSIZE you see in apc_sma.c is all about.
17878 +
17879 + Of course, anytime we fiddle with our shared memory segment we lock using
17880 + the locking macros, LOCK() and UNLOCK().
17881 +
17882 + That should mostly take care of the low-level shared memory handling.
17883 +
17884 +6. Next up is apc_main.c and apc_cache.c which implement the meat of the
17885 + cache logic.
17886 +
17887 + The apc_main.c file mostly calls functions in apc_sma.c to allocate memory
17888 + and apc_cache.c for actual cache manipulation.
17889 +
17890 + After the shared memory segment is created and the caches are initialized,
17891 + apc_module_init() installs the my_compile_file() function overriding Zend's
17892 + version. I'll talk about my_compile_file() and the rest of apc_compile.c
17893 + in the next section. For now I will stick with apc_main.c and apc_cache.c
17894 + and talk about the actual caches. A cache consists of a block of shared
17895 + memory returned by apc_sma_allocate() via apc_sma_malloc(). You will
17896 + notice references to apc_emalloc(). apc_emalloc() is just a thin wrapper
17897 + around PHP's own emalloc() function which allocates per-process memory from
17898 + PHP's pool-based memory allocator. Don't confuse apc_emalloc() and
17899 + apc_sma_malloc() as the first is per-process and the second is shared memory.
17900 +
17901 + The cache is stored in/described by this struct allocated locally using
17902 + emalloc():
17903 +
17904 + struct apc_cache_t {
17905 + void* shmaddr; /* process (local) address of shared cache */
17906 + header_t* header; /* cache header (stored in SHM) */
17907 + slot_t** slots; /* array of cache slots (stored in SHM) */
17908 + int num_slots; /* number of slots in cache */
17909 + int gc_ttl; /* maximum time on GC list for a slot */
17910 + int ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */
17911 + };
17912 +
17913 + Whenever you see functions that take a 'cache' argument, this is what they
17914 + take. And apc_cache_create() returns a pointer to this populated struct.
17915 +
17916 + At the beginning of the cache we have a header. Remember, we are down a level now
17917 + from the sma stuff. The sma stuff is the low-level shared-memory allocator which
17918 + has its own header which is completely separate and invisible to apc_cache.c.
17919 + As far as apc_cache.c is concerned the block of memory it is working with could
17920 + have come from a call to malloc().
17921 +
17922 + The header looks like this:
17923 +
17924 + typedef struct header_t header_t;
17925 + struct header_t {
17926 + int num_hits; /* total successful hits in cache */
17927 + int num_misses; /* total unsuccessful hits in cache */
17928 + slot_t* deleted_list; /* linked list of to-be-deleted slots */
17929 + };
17930 +
17931 + Since this is at the start of the shared memory segment, these values are accessible
17932 + across all the yapache processes and hence access to them has to be locked.
17933 +
17934 + After the header we have an array of slots. The number of slots is user-defined
17935 + through the apc.num_slots ini hint. Each slot is described by:
17936 +
17937 + typedef struct slot_t slot_t;
17938 + struct slot_t {
17939 + apc_cache_key_t key; /* slot key */
17940 + apc_cache_entry_t* value; /* slot value */
17941 + slot_t* next; /* next slot in linked list */
17942 + int num_hits; /* number of hits to this bucket */
17943 + time_t creation_time; /* time slot was initialized */
17944 + time_t deletion_time; /* time slot was removed from cache */
17945 + time_t access_time; /* time slot was last accessed */
17946 + };
17947 +
17948 + The slot_t *next there is a linked list to other slots that happened to hash to the
17949 + same array position.
17950 +
17951 + apc_cache_insert() shows what happens on a new cache insert.
17952 +
17953 + slot = &cache->slots[hash(key) % cache->num_slots];
17954 +
17955 + cache->slots is our array of slots in the segment. hash() is simply:
17956 +
17957 + static unsigned int hash(apc_cache_key_t key)
17958 + {
17959 + return key.data.file.device + key.data.file.inode;
17960 + }
17961 +
17962 + That is, we use the file's device and inode to uniquely identify it. Initially
17963 + we had used the file's full path, but getting that requires a realpath() call which
17964 + is amazingly expensive since it has to stat each component of the path to resolve
17965 + symlinks and get rid of relative path components. By using the device+inode we
17966 + can uniquely identify a file with a single stat.
17967 +
17968 + So, on an insert we find the array position in the slots array by hasing the device+inode.
17969 + If there are currently no other slots there, we just create the slot and stick it into
17970 + the array:
17971 +
17972 + *slot = make_slot(key, value, *slot, t)
17973 +
17974 + If there are other slots already at this position we walk the link list to get to
17975 + the end. Here is the loop:
17976 +
17977 + while (*slot) {
17978 + if (key_equals((*slot)->key.data.file, key.data.file)) {
17979 + /* If existing slot for the same device+inode is different, remove it and insert the new version */
17980 + if ((*slot)->key.mtime != key.mtime) {
17981 + remove_slot(cache, slot);
17982 + break;
17983 + }
17984 + UNLOCK(cache);
17985 + return 0;
17986 + } else if(cache->ttl && (*slot)->access_time < (t - cache->ttl)) {
17987 + remove_slot(cache, slot);
17988 + continue;
17989 + }
17990 + slot = &(*slot)->next;
17991 + }
17992 +
17993 + That first key_equals() check sees if we have an exact match meaning the file
17994 + is already in the cache. Since we try to find the file in the cache before doing
17995 + an insert, this will generally only happen if another process managed to beat us
17996 + to inserting it. If we have a newer version of the file at this point we remove
17997 + it an insert the new version. If our version is not newer we just return without
17998 + doing anything.
17999 +
18000 + While walking the linked list we also check to see if the cache has a TTL defined.
18001 + If while walking the linked list we see a slot that has expired, we remove it
18002 + since we are right there looking at it. This is the only place we remove stale
18003 + entries unless the shared memory segment fills up and we force a full expunge via
18004 + apc_cache_expunge(). apc_cache_expunge() walks the entire slots array and walks
18005 + down every linked list removing stale slots to free up room. This is obviously
18006 + slow and thus only happens when we have run out of room.
18007 +
18008 + apc_cache_find() simply hashes and returns the entry if it is there. If it is there
18009 + but older than the mtime in the entry we are looking for, we delete the one that is
18010 + there and return indicating we didn't find it.
18011 +
18012 + Next we need to understand what an actual cache entry looks like. Have a look at
18013 + apc_cache.h for the structs. I sort of glossed over the key part earlier saying
18014 + that we just used the device+inode to find a hash slot. It is actually a bit more
18015 + complex than that because we have two kinds of caches. We have the standard file
18016 + cache containing opcode arrays, but we also have a user-controlled cache that the
18017 + user can insert whatever they want into via apc_store(). For the user cache we
18018 + obviously don't have a device+inode. The actual identifier is provided by the user
18019 + as a char *. So the key is actually a union that looks like this:
18020 +
18021 + typedef union _apc_cache_key_data_t {
18022 + struct {
18023 + int device; /* the filesystem device */
18024 + int inode; /* the filesystem inode */
18025 + } file;
18026 + struct {
18027 + char *identifier;
18028 + } user;
18029 + } apc_cache_key_data_t;
18030 +
18031 + struct apc_cache_key_t {
18032 + apc_cache_key_data_t data;
18033 + int mtime; /* the mtime of this cached entry */
18034 + };
18035 +
18036 + And we have two sets of functions to do inserts and finds. apc_cache_user_find()
18037 + and apc_cache_user_insert() operate on the user cache.
18038 +
18039 + Ok, on to the actual cache entry. Again, because we have two kinds of caches, we
18040 + also have the corresponding two kinds of cache entries described by this union:
18041 +
18042 + typedef union _apc_cache_entry_value_t {
18043 + struct {
18044 + char *filename; /* absolute path to source file */
18045 + zend_op_array* op_array; /* op_array allocated in shared memory */
18046 + apc_function_t* functions; /* array of apc_function_t's */
18047 + apc_class_t* classes; /* array of apc_class_t's */
18048 + } file;
18049 + struct {
18050 + char *info;
18051 + zval *val;
18052 + unsigned int ttl;
18053 + } user;
18054 + } apc_cache_entry_value_t;
18055 +
18056 + And then the actual cache entry:
18057 +
18058 + struct apc_cache_entry_t {
18059 + apc_cache_entry_value_t data;
18060 + unsigned char type;
18061 + int ref_count;
18062 + };
18063 +
18064 + The user entry is pretty simple and not all that important for now. I will
18065 + concentrate on the file entries since that is what holds the actual compiled
18066 + opcode arrays along with the functions and classes required by the executor.
18067 +
18068 + apc_cache_make_file_entry() in apc_cache.c shows how an entry is constructed.
18069 + The main thing to understand here is that we need more than just the opcode
18070 + array, we also need the functions and classes created by the compiler when it
18071 + created the opcode array. As far as the executor is concerned, it doesn't know
18072 + that it isn't operating in normal mode being called right after the parse/compile
18073 + phase, so we need to recreate everything so it looks exactly like it would at
18074 + that point.
18075 +
18076 +7. my_compile_file() and apc_compile.c
18077 +
18078 + my_compile_file() in apc_main.c controls where we get the opcodes from. If
18079 + the user-specified filters exclude the file from being cached, then we just
18080 + call the original compile function and return. Otherwise we fetch the request
18081 + time from Apache to avoid an extra syscall, create the key so we can look up
18082 + the file in the cache. If we find it we stick it on a local stack which we
18083 + use at cleanup time to make sure we return everything back to normal after a
18084 + request and call cached_compile() which installs the functions and classes
18085 + associated with the op_array in this entry and then copy the op_array down
18086 + into our memory space for execution.
18087 +
18088 + If we didn't find the file in the cache, we need to compile it and insert it.
18089 + To compile it we simply call the original compile function:
18090 +
18091 + op_array = old_compile_file(h, type TSRMLS_CC);
18092 +
18093 + To do the insert we need to copy the functions, classes and the opcode array
18094 + the compile phase created into shared memory. This all happens in apc_compile.c
18095 + in the apc_copy_op_array(), apc_copy_new_functions() and apc_copy_new_classes()
18096 + functions. Then we make the file entry and do the insert. Both of these
18097 + operations were described in the previous section.
18098 +
18099 +8. The Optimizer
18100 +
18101 + The optimizer has been deprecated.
18102 +
18103 +If you made it to the end of this, you should have a pretty good idea of where things are in
18104 +the code. I skimmed over a lot of things, so plan on spending some time reading through the code.
18105 +
18106 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_001.phpt php-5.3.1/ext/apc/tests/apc_001.phpt
18107 --- php-5.3.1.orig/ext/apc/tests/apc_001.phpt 1970-01-01 01:00:00.000000000 +0100
18108 +++ php-5.3.1/ext/apc/tests/apc_001.phpt 1970-01-01 10:14:21.000000000 +0100
18109 @@ -0,0 +1,27 @@
18110 +--TEST--
18111 +APC: apc_store/fetch with strings
18112 +--SKIPIF--
18113 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18114 +--INI--
18115 +apc.enabled=1
18116 +apc.enable_cli=1
18117 +apc.file_update_protection=0
18118 +--FILE--
18119 +<?php
18120 +
18121 +$foo = 'hello world';
18122 +var_dump($foo);
18123 +apc_store('foo',$foo);
18124 +$bar = apc_fetch('foo');
18125 +var_dump($bar);
18126 +$bar = 'nice';
18127 +var_dump($bar);
18128 +
18129 +?>
18130 +===DONE===
18131 +<?php exit(0); ?>
18132 +--EXPECTF--
18133 +string(11) "hello world"
18134 +string(11) "hello world"
18135 +string(4) "nice"
18136 +===DONE===
18137 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_002.phpt php-5.3.1/ext/apc/tests/apc_002.phpt
18138 --- php-5.3.1.orig/ext/apc/tests/apc_002.phpt 1970-01-01 01:00:00.000000000 +0100
18139 +++ php-5.3.1/ext/apc/tests/apc_002.phpt 1970-01-01 10:14:21.000000000 +0100
18140 @@ -0,0 +1,34 @@
18141 +--TEST--
18142 +APC: apc_store/fetch with objects
18143 +--SKIPIF--
18144 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18145 +--INI--
18146 +apc.enabled=1
18147 +apc.enable_cli=1
18148 +apc.file_update_protection=0
18149 +--FILE--
18150 +<?php
18151 +
18152 +class foo { }
18153 +$foo = new foo;
18154 +var_dump($foo);
18155 +apc_store('foo',$foo);
18156 +unset($foo);
18157 +$bar = apc_fetch('foo');
18158 +var_dump($bar);
18159 +$bar->a = true;
18160 +var_dump($bar);
18161 +
18162 +?>
18163 +===DONE===
18164 +<?php exit(0); ?>
18165 +--EXPECTF--
18166 +object(foo)#%d (0) {
18167 +}
18168 +object(foo)#%d (0) {
18169 +}
18170 +object(foo)#%d (1) {
18171 + ["a"]=>
18172 + bool(true)
18173 +}
18174 +===DONE===
18175 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_003b.phpt php-5.3.1/ext/apc/tests/apc_003b.phpt
18176 --- php-5.3.1.orig/ext/apc/tests/apc_003b.phpt 1970-01-01 01:00:00.000000000 +0100
18177 +++ php-5.3.1/ext/apc/tests/apc_003b.phpt 1970-01-01 10:13:08.000000000 +0100
18178 @@ -0,0 +1,117 @@
18179 +--TEST--
18180 +APC: apc_store/fetch with objects (php 5.3)
18181 +--SKIPIF--
18182 +<?php
18183 + require_once(dirname(__FILE__) . '/skipif.inc');
18184 + if(version_compare(zend_version(), '2.3.0') < 0) {
18185 + echo "skip\n";
18186 + }
18187 +?>
18188 +--INI--
18189 +apc.enabled=1
18190 +apc.enable_cli=1
18191 +apc.file_update_protection=0
18192 +--FILE--
18193 +<?php
18194 +
18195 +class foo { }
18196 +$foo = new foo;
18197 +var_dump($foo);
18198 +apc_store('foo',$foo);
18199 +unset($foo);
18200 +$bar = apc_fetch('foo');
18201 +var_dump($bar);
18202 +$bar->a = true;
18203 +var_dump($bar);
18204 +
18205 +class bar extends foo
18206 +{
18207 + public $pub = 'bar';
18208 + protected $pro = 'bar';
18209 + private $pri = 'bar'; // we don't see this, we'd need php 5.1 new serialization
18210 +
18211 + function __construct()
18212 + {
18213 + $this->bar = true;
18214 + }
18215 +
18216 + function change()
18217 + {
18218 + $this->pri = 'mod';
18219 + }
18220 +}
18221 +
18222 +class baz extends bar
18223 +{
18224 + private $pri = 'baz';
18225 +
18226 + function __construct()
18227 + {
18228 + parent::__construct();
18229 + $this->baz = true;
18230 + }
18231 +}
18232 +
18233 +$baz = new baz;
18234 +var_dump($baz);
18235 +$baz->change();
18236 +var_dump($baz);
18237 +apc_store('baz', $baz);
18238 +unset($baz);
18239 +var_dump(apc_fetch('baz'));
18240 +
18241 +?>
18242 +===DONE===
18243 +<?php exit(0); ?>
18244 +--EXPECTF--
18245 +object(foo)#%d (0) {
18246 +}
18247 +object(foo)#%d (0) {
18248 +}
18249 +object(foo)#%d (1) {
18250 + ["a"]=>
18251 + bool(true)
18252 +}
18253 +object(baz)#%d (6) {
18254 + ["pri":"baz":private]=>
18255 + string(3) "baz"
18256 + ["pub"]=>
18257 + string(3) "bar"
18258 + ["pro":protected]=>
18259 + string(3) "bar"
18260 + ["pri":"bar":private]=>
18261 + string(3) "bar"
18262 + ["bar"]=>
18263 + bool(true)
18264 + ["baz"]=>
18265 + bool(true)
18266 +}
18267 +object(baz)#%d (6) {
18268 + ["pri":"baz":private]=>
18269 + string(3) "baz"
18270 + ["pub"]=>
18271 + string(3) "bar"
18272 + ["pro":protected]=>
18273 + string(3) "bar"
18274 + ["pri":"bar":private]=>
18275 + string(3) "mod"
18276 + ["bar"]=>
18277 + bool(true)
18278 + ["baz"]=>
18279 + bool(true)
18280 +}
18281 +object(baz)#%d (6) {
18282 + ["pri":"baz":private]=>
18283 + string(3) "baz"
18284 + ["pub"]=>
18285 + string(3) "bar"
18286 + ["pro":protected]=>
18287 + string(3) "bar"
18288 + ["pri":"bar":private]=>
18289 + string(3) "mod"
18290 + ["bar"]=>
18291 + bool(true)
18292 + ["baz"]=>
18293 + bool(true)
18294 +}
18295 +===DONE===
18296 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_003.phpt php-5.3.1/ext/apc/tests/apc_003.phpt
18297 --- php-5.3.1.orig/ext/apc/tests/apc_003.phpt 1970-01-01 01:00:00.000000000 +0100
18298 +++ php-5.3.1/ext/apc/tests/apc_003.phpt 1970-01-01 10:13:08.000000000 +0100
18299 @@ -0,0 +1,117 @@
18300 +--TEST--
18301 +APC: apc_store/fetch with objects (php pre-5.3)
18302 +--SKIPIF--
18303 +<?php
18304 + require_once(dirname(__FILE__) . '/skipif.inc');
18305 + if(version_compare(zend_version(), '2.3.0') >= 0) {
18306 + echo "skip\n";
18307 + }
18308 +?>
18309 +--INI--
18310 +apc.enabled=1
18311 +apc.enable_cli=1
18312 +apc.file_update_protection=0
18313 +--FILE--
18314 +<?php
18315 +
18316 +class foo { }
18317 +$foo = new foo;
18318 +var_dump($foo);
18319 +apc_store('foo',$foo);
18320 +unset($foo);
18321 +$bar = apc_fetch('foo');
18322 +var_dump($bar);
18323 +$bar->a = true;
18324 +var_dump($bar);
18325 +
18326 +class bar extends foo
18327 +{
18328 + public $pub = 'bar';
18329 + protected $pro = 'bar';
18330 + private $pri = 'bar'; // we don't see this, we'd need php 5.1 new serialization
18331 +
18332 + function __construct()
18333 + {
18334 + $this->bar = true;
18335 + }
18336 +
18337 + function change()
18338 + {
18339 + $this->pri = 'mod';
18340 + }
18341 +}
18342 +
18343 +class baz extends bar
18344 +{
18345 + private $pri = 'baz';
18346 +
18347 + function __construct()
18348 + {
18349 + parent::__construct();
18350 + $this->baz = true;
18351 + }
18352 +}
18353 +
18354 +$baz = new baz;
18355 +var_dump($baz);
18356 +$baz->change();
18357 +var_dump($baz);
18358 +apc_store('baz', $baz);
18359 +unset($baz);
18360 +var_dump(apc_fetch('baz'));
18361 +
18362 +?>
18363 +===DONE===
18364 +<?php exit(0); ?>
18365 +--EXPECTF--
18366 +object(foo)#%d (0) {
18367 +}
18368 +object(foo)#%d (0) {
18369 +}
18370 +object(foo)#%d (1) {
18371 + ["a"]=>
18372 + bool(true)
18373 +}
18374 +object(baz)#%d (6) {
18375 + ["pri:private"]=>
18376 + string(3) "baz"
18377 + ["pub"]=>
18378 + string(3) "bar"
18379 + ["pro:protected"]=>
18380 + string(3) "bar"
18381 + ["pri:private"]=>
18382 + string(3) "bar"
18383 + ["bar"]=>
18384 + bool(true)
18385 + ["baz"]=>
18386 + bool(true)
18387 +}
18388 +object(baz)#%d (6) {
18389 + ["pri:private"]=>
18390 + string(3) "baz"
18391 + ["pub"]=>
18392 + string(3) "bar"
18393 + ["pro:protected"]=>
18394 + string(3) "bar"
18395 + ["pri:private"]=>
18396 + string(3) "mod"
18397 + ["bar"]=>
18398 + bool(true)
18399 + ["baz"]=>
18400 + bool(true)
18401 +}
18402 +object(baz)#%d (6) {
18403 + ["pri:private"]=>
18404 + string(3) "baz"
18405 + ["pub"]=>
18406 + string(3) "bar"
18407 + ["pro:protected"]=>
18408 + string(3) "bar"
18409 + ["pri:private"]=>
18410 + string(3) "mod"
18411 + ["bar"]=>
18412 + bool(true)
18413 + ["baz"]=>
18414 + bool(true)
18415 +}
18416 +===DONE===
18417 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_004.phpt php-5.3.1/ext/apc/tests/apc_004.phpt
18418 --- php-5.3.1.orig/ext/apc/tests/apc_004.phpt 1970-01-01 01:00:00.000000000 +0100
18419 +++ php-5.3.1/ext/apc/tests/apc_004.phpt 1970-01-01 10:13:08.000000000 +0100
18420 @@ -0,0 +1,38 @@
18421 +--TEST--
18422 +APC: apc_store/fetch with bools
18423 +--SKIPIF--
18424 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18425 +--INI--
18426 +apc.enabled=1
18427 +apc.enable_cli=1
18428 +apc.file_update_protection=0
18429 +--FILE--
18430 +<?php
18431 +
18432 +$foo = false;
18433 +var_dump($foo); /* false */
18434 +apc_store('foo',$foo);
18435 +//$success = "some string";
18436 +
18437 +$bar = apc_fetch('foo', $success);
18438 +var_dump($foo); /* false */
18439 +var_dump($bar); /* false */
18440 +var_dump($success); /* true */
18441 +
18442 +$bar = apc_fetch('not foo', $success);
18443 +var_dump($foo); /* false */
18444 +var_dump($bar); /* false */
18445 +var_dump($success); /* false */
18446 +
18447 +?>
18448 +===DONE===
18449 +<?php exit(0); ?>
18450 +--EXPECTF--
18451 +bool(false)
18452 +bool(false)
18453 +bool(false)
18454 +bool(true)
18455 +bool(false)
18456 +bool(false)
18457 +bool(false)
18458 +===DONE===
18459 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_005.phpt php-5.3.1/ext/apc/tests/apc_005.phpt
18460 --- php-5.3.1.orig/ext/apc/tests/apc_005.phpt 1970-01-01 01:00:00.000000000 +0100
18461 +++ php-5.3.1/ext/apc/tests/apc_005.phpt 1970-01-01 10:13:08.000000000 +0100
18462 @@ -0,0 +1,50 @@
18463 +--TEST--
18464 +APC: apc_store/fetch with arrays of objects
18465 +--SKIPIF--
18466 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18467 +--INI--
18468 +apc.enabled=1
18469 +apc.enable_cli=1
18470 +apc.file_update_protection=0
18471 +--FILE--
18472 +<?php
18473 +
18474 +$foo = array(new stdclass(), new stdclass());
18475 +
18476 +var_dump($foo);
18477 +
18478 +apc_store('foo',$foo);
18479 +
18480 +$bar = apc_fetch('foo');
18481 +var_dump($foo);
18482 +var_dump($bar);
18483 +
18484 +?>
18485 +===DONE===
18486 +<?php exit(0); ?>
18487 +--EXPECTF--
18488 +array(2) {
18489 + [0]=>
18490 + object(stdClass)#1 (0) {
18491 + }
18492 + [1]=>
18493 + object(stdClass)#2 (0) {
18494 + }
18495 +}
18496 +array(2) {
18497 + [0]=>
18498 + object(stdClass)#1 (0) {
18499 + }
18500 + [1]=>
18501 + object(stdClass)#2 (0) {
18502 + }
18503 +}
18504 +array(2) {
18505 + [0]=>
18506 + object(stdClass)#3 (0) {
18507 + }
18508 + [1]=>
18509 + object(stdClass)#4 (0) {
18510 + }
18511 +}
18512 +===DONE===
18513 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_006.phpt php-5.3.1/ext/apc/tests/apc_006.phpt
18514 --- php-5.3.1.orig/ext/apc/tests/apc_006.phpt 1970-01-01 01:00:00.000000000 +0100
18515 +++ php-5.3.1/ext/apc/tests/apc_006.phpt 1970-01-01 10:13:08.000000000 +0100
18516 @@ -0,0 +1,72 @@
18517 +--TEST--
18518 +APC: apc_store/fetch reference test
18519 +--SKIPIF--
18520 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18521 +--INI--
18522 +apc.enabled=1
18523 +apc.enable_cli=1
18524 +apc.file_update_protection=0
18525 +report_memleaks=0
18526 +--FILE--
18527 +<?php
18528 +
18529 +$a = 'a';
18530 +$b = array($a);
18531 +$c = array('c');
18532 +$b[] = &$c;
18533 +$b[] = &$c;
18534 +$d = 'd';
18535 +$b[] = &$d;
18536 +$b[] = &$d;
18537 +$b[] = &$d;
18538 +$e = 'e';
18539 +$b[] = $e;
18540 +$b[] = $e;
18541 +$f = array('f');
18542 +$f[] = &$f;
18543 +$b[] = &$f;
18544 +apc_store('test', $b);
18545 +$x = apc_fetch('test');
18546 +debug_zval_dump($x);
18547 +
18548 +?>
18549 +===DONE===
18550 +<?php exit(0); ?>
18551 +--EXPECTF--
18552 +array(9) refcount(2){
18553 + [0]=>
18554 + string(1) "a" refcount(1)
18555 + [1]=>
18556 + &array(1) refcount(2){
18557 + [0]=>
18558 + string(1) "c" refcount(1)
18559 + }
18560 + [2]=>
18561 + &array(1) refcount(2){
18562 + [0]=>
18563 + string(1) "c" refcount(1)
18564 + }
18565 + [3]=>
18566 + &string(1) "d" refcount(3)
18567 + [4]=>
18568 + &string(1) "d" refcount(3)
18569 + [5]=>
18570 + &string(1) "d" refcount(3)
18571 + [6]=>
18572 + string(1) "e" refcount(2)
18573 + [7]=>
18574 + string(1) "e" refcount(2)
18575 + [8]=>
18576 + &array(2) refcount(2){
18577 + [0]=>
18578 + string(1) "f" refcount(1)
18579 + [1]=>
18580 + &array(2) refcount(2){
18581 + [0]=>
18582 + string(1) "f" refcount(1)
18583 + [1]=>
18584 + *RECURSION*
18585 + }
18586 + }
18587 +}
18588 +===DONE===
18589 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_007.phpt php-5.3.1/ext/apc/tests/apc_007.phpt
18590 --- php-5.3.1.orig/ext/apc/tests/apc_007.phpt 1970-01-01 01:00:00.000000000 +0100
18591 +++ php-5.3.1/ext/apc/tests/apc_007.phpt 1970-01-01 10:13:08.000000000 +0100
18592 @@ -0,0 +1,46 @@
18593 +--TEST--
18594 +APC: apc_inc/apc_dec test
18595 +--SKIPIF--
18596 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18597 +--INI--
18598 +apc.enabled=1
18599 +apc.enable_cli=1
18600 +apc.file_update_protection=0
18601 +--FILE--
18602 +<?php
18603 +apc_store('foobar',2);
18604 +echo "\$foobar = 2 \n";
18605 +echo "\$foobar += 1 = ".apc_inc('foobar')."\n";
18606 +echo "\$foobar += 10 = ".apc_inc('foobar', 10)."\n";
18607 +
18608 +echo "\$foobar -= 1 = ".apc_dec('foobar')."\n";
18609 +echo "\$foobar -= 10 = ".apc_dec('foobar',10)."\n";
18610 +
18611 +echo "\$f__bar += 1 = ".(apc_inc('f__bar')?"ok":"fail")."\n";
18612 +
18613 +apc_store('perfection', "xyz");
18614 +echo "\$perfection -= 1 = ".(apc_inc('perfection')?"ok":"epic fail")."\n";
18615 +
18616 +$success = false;
18617 +
18618 +echo "\$foobar += 1 = ".apc_inc('foobar', 1, $success)."\n";
18619 +echo "pass by ref success ". $success . "\n";
18620 +echo "\$foobar -= 1 = ".apc_dec('foobar', 1, $success)."\n";
18621 +echo "pass by ref success ". $success . "\n";
18622 +
18623 +?>
18624 +===DONE===
18625 +<?php exit(0); ?>
18626 +--EXPECTF--
18627 +$foobar = 2
18628 +$foobar += 1 = 3
18629 +$foobar += 10 = 13
18630 +$foobar -= 1 = 12
18631 +$foobar -= 10 = 2
18632 +$f__bar += 1 = fail
18633 +$perfection -= 1 = epic fail
18634 +$foobar += 1 = 3
18635 +pass by ref success 1
18636 +$foobar -= 1 = 2
18637 +pass by ref success 1
18638 +===DONE===
18639 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_008.phpt php-5.3.1/ext/apc/tests/apc_008.phpt
18640 --- php-5.3.1.orig/ext/apc/tests/apc_008.phpt 1970-01-01 01:00:00.000000000 +0100
18641 +++ php-5.3.1/ext/apc/tests/apc_008.phpt 1970-01-01 10:13:08.000000000 +0100
18642 @@ -0,0 +1,34 @@
18643 +--TEST--
18644 +APC: apc_cas test
18645 +--SKIPIF--
18646 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18647 +--INI--
18648 +apc.enabled=1
18649 +apc.enable_cli=1
18650 +apc.file_update_protection=0
18651 +--FILE--
18652 +<?php
18653 +apc_store('foobar',2);
18654 +echo "\$foobar = 2\n";
18655 +echo "\$foobar == 1 ? 2 : 1 = ".(apc_cas('foobar', 1, 2)?"ok":"fail")."\n";
18656 +echo "\$foobar == 2 ? 1 : 2 = ".(apc_cas('foobar', 2, 1)?"ok":"fail")."\n";
18657 +echo "\$foobar = ".apc_fetch("foobar")."\n";
18658 +
18659 +echo "\$f__bar == 1 ? 2 : 1 = ".(apc_cas('f__bar', 1, 2)?"ok":"fail")."\n";
18660 +
18661 +apc_store('perfection', "xyz");
18662 +echo "\$perfection == 2 ? 1 : 2 = ".(apc_cas('perfection', 2, 1)?"ok":"epic fail")."\n";
18663 +
18664 +echo "\$foobar = ".apc_fetch("foobar")."\n";
18665 +?>
18666 +===DONE===
18667 +<?php exit(0); ?>
18668 +--EXPECTF--
18669 +$foobar = 2
18670 +$foobar == 1 ? 2 : 1 = fail
18671 +$foobar == 2 ? 1 : 2 = ok
18672 +$foobar = 1
18673 +$f__bar == 1 ? 2 : 1 = fail
18674 +$perfection == 2 ? 1 : 2 = epic fail
18675 +$foobar = 1
18676 +===DONE===
18677 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_009.phpt php-5.3.1/ext/apc/tests/apc_009.phpt
18678 --- php-5.3.1.orig/ext/apc/tests/apc_009.phpt 1970-01-01 01:00:00.000000000 +0100
18679 +++ php-5.3.1/ext/apc/tests/apc_009.phpt 1970-01-01 10:13:08.000000000 +0100
18680 @@ -0,0 +1,94 @@
18681 +--TEST--
18682 +APC: apc_delete_file test
18683 +--SKIPIF--
18684 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18685 +--INI--
18686 +apc.enabled=1
18687 +apc.enable_cli=1
18688 +apc.file_update_protection=0
18689 +report_memleaks=0
18690 +--FILE--
18691 +<?php
18692 +
18693 +$files = array( 'apc_009.php',
18694 + 'apc_009-1.php',
18695 + 'apc_009-2.php',
18696 + 'nofile.php',
18697 + );
18698 +
18699 +file_put_contents(dirname(__FILE__).'/apc_009-1.php', '<?php echo "test file";');
18700 +file_put_contents(dirname(__FILE__).'/apc_009-2.php', '<?php syntaxerrorhere!');
18701 +
18702 +apc_compile_file($files[0]);
18703 +check_file($files[0]);
18704 +apc_delete_file($files[0]);
18705 +check_file($files[0]);
18706 +
18707 +apc_compile_file($files[0]);
18708 +apc_delete_file(array($files[0]));
18709 +check_file($files[0]);
18710 +
18711 +apc_compile_file($files[0]);
18712 +$it = new APCIterator('file');
18713 +apc_delete_file($it);
18714 +check_file($files[0]);
18715 +
18716 +var_dump(apc_compile_file(array($files[0], $files[1])));
18717 +check_file(array($files[0], $files[1]));
18718 +
18719 +var_dump(apc_compile_file($files));
18720 +check_file($files);
18721 +
18722 +function check_file($files) {
18723 +
18724 + if (!is_array($files)) {
18725 + $files = array($files);
18726 + }
18727 +
18728 + $info = apc_cache_info('file');
18729 +
18730 + foreach ($files as $file) {
18731 + $match = 0;
18732 + foreach($info['cache_list'] as $cached_file) {
18733 + if (stristr($cached_file['filename'], $file)) $match = 1;
18734 + }
18735 + if ($match) {
18736 + echo "$file Found File\n";
18737 + } else {
18738 + echo "$file Not Found\n";
18739 + }
18740 + }
18741 +}
18742 +
18743 +?>
18744 +===DONE===
18745 +<?php exit(0); ?>
18746 +--CLEAN--
18747 +<?php
18748 +unlink('apc_009-1.php');
18749 +unlink('apc_009-2.php');
18750 +?>
18751 +--EXPECTF--
18752 +apc_009.php Found File
18753 +apc_009.php Not Found
18754 +apc_009.php Not Found
18755 +apc_009.php Not Found
18756 +array(0) {
18757 +}
18758 +apc_009.php Found File
18759 +apc_009-1.php Found File
18760 +
18761 +Parse error: syntax error, unexpected '!' in %s/apc_009-2.php on line 1
18762 +[%s] [apc-warning] Error compiling apc_009-2.php in apc_compile_file. %s
18763 +[%s] [apc-warning] Error compiling nofile.php in apc_compile_file. %s
18764 +array(2) {
18765 + ["apc_009-2.php"]=>
18766 + int(-1)
18767 + ["nofile.php"]=>
18768 + int(-1)
18769 +}
18770 +apc_009.php Found File
18771 +apc_009-1.php Found File
18772 +apc_009-2.php Not Found
18773 +nofile.php Not Found
18774 +===DONE===
18775 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_010.phpt php-5.3.1/ext/apc/tests/apc_010.phpt
18776 --- php-5.3.1.orig/ext/apc/tests/apc_010.phpt 1970-01-01 01:00:00.000000000 +0100
18777 +++ php-5.3.1/ext/apc/tests/apc_010.phpt 1970-01-01 10:13:08.000000000 +0100
18778 @@ -0,0 +1,83 @@
18779 +--TEST--
18780 +APC: apc_store/fetch/add with array of key/value pairs.
18781 +--SKIPIF--
18782 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
18783 +--INI--
18784 +apc.enabled=1
18785 +apc.enable_cli=1
18786 +apc.file_update_protection=0
18787 +--FILE--
18788 +<?php
18789 +
18790 +$entries = array();
18791 +$entries['key1'] = 'value1';
18792 +$entries['key2'] = 'value2';
18793 +$entries['key3'] = array('value3a','value3b');
18794 +$entries['key4'] = 4;
18795 +
18796 +var_dump(apc_store($entries));
18797 +$cached_values = apc_fetch(array_keys($entries));
18798 +var_dump($cached_values);
18799 +
18800 +apc_delete('key2');
18801 +apc_delete('key4');
18802 +$cached_values = apc_fetch(array_keys($entries));
18803 +var_dump($cached_values);
18804 +var_dump(apc_add($entries));
18805 +$cached_values = apc_fetch(array_keys($entries));
18806 +var_dump($cached_values);
18807 +
18808 +?>
18809 +===DONE===
18810 +<?php exit(0); ?>
18811 +--EXPECTF--
18812 +array(0) {
18813 +}
18814 +array(4) {
18815 + ["key1"]=>
18816 + string(6) "value1"
18817 + ["key2"]=>
18818 + string(6) "value2"
18819 + ["key3"]=>
18820 + array(2) {
18821 + [0]=>
18822 + string(7) "value3a"
18823 + [1]=>
18824 + string(7) "value3b"
18825 + }
18826 + ["key4"]=>
18827 + int(4)
18828 +}
18829 +array(2) {
18830 + ["key1"]=>
18831 + string(6) "value1"
18832 + ["key3"]=>
18833 + array(2) {
18834 + [0]=>
18835 + string(7) "value3a"
18836 + [1]=>
18837 + string(7) "value3b"
18838 + }
18839 +}
18840 +array(2) {
18841 + ["key1"]=>
18842 + int(-1)
18843 + ["key3"]=>
18844 + int(-1)
18845 +}
18846 +array(4) {
18847 + ["key1"]=>
18848 + string(6) "value1"
18849 + ["key2"]=>
18850 + string(6) "value2"
18851 + ["key3"]=>
18852 + array(2) {
18853 + [0]=>
18854 + string(7) "value3a"
18855 + [1]=>
18856 + string(7) "value3b"
18857 + }
18858 + ["key4"]=>
18859 + int(4)
18860 +}
18861 +===DONE===
18862 diff -Naur php-5.3.1.orig/ext/apc/tests/apc53_001.phpt php-5.3.1/ext/apc/tests/apc53_001.phpt
18863 --- php-5.3.1.orig/ext/apc/tests/apc53_001.phpt 1970-01-01 01:00:00.000000000 +0100
18864 +++ php-5.3.1/ext/apc/tests/apc53_001.phpt 1970-01-01 10:13:08.000000000 +0100
18865 @@ -0,0 +1,33 @@
18866 +--TEST--
18867 +APC: classes with namespaces (php 5.3)
18868 +--SKIPIF--
18869 +<?php
18870 + require_once(dirname(__FILE__) . '/skipif.inc');
18871 + if(version_compare(zend_version(), '2.3.0') < 0) {
18872 + echo "skip\n";
18873 + }
18874 +?>
18875 +--INI--
18876 +apc.enabled=1
18877 +apc.enable_cli=1
18878 +apc.file_update_protection=0
18879 +--FILE--
18880 +<?php
18881 +
18882 +require_once(dirname(__FILE__) . '/php_5_3_ns.inc');
18883 +
18884 +$a = new Foo\Bar\Baz();
18885 +var_dump($a);
18886 +?>
18887 +===DONE===
18888 +<?php exit(0); ?>
18889 +--EXPECTF--
18890 +object(Foo\Bar\Baz)#1 (3) {
18891 + ["i"]=>
18892 + int(1)
18893 + ["f":protected]=>
18894 + float(3.14)
18895 + ["s":"Foo\Bar\Baz":private]=>
18896 + string(11) "hello world"
18897 +}
18898 +===DONE===
18899 diff -Naur php-5.3.1.orig/ext/apc/tests/apc53_002.phpt php-5.3.1/ext/apc/tests/apc53_002.phpt
18900 --- php-5.3.1.orig/ext/apc/tests/apc53_002.phpt 1970-01-01 01:00:00.000000000 +0100
18901 +++ php-5.3.1/ext/apc/tests/apc53_002.phpt 1970-01-01 10:13:08.000000000 +0100
18902 @@ -0,0 +1,47 @@
18903 +--TEST--
18904 +APC: global spaces (php 5.3)
18905 +--SKIPIF--
18906 +<?php
18907 + require_once(dirname(__FILE__) . '/skipif.inc');
18908 + if(version_compare(zend_version(), '2.3.0') < 0) {
18909 + echo "skip\n";
18910 + }
18911 +?>
18912 +--INI--
18913 +apc.enabled=1
18914 +apc.enable_cli=1
18915 +apc.file_update_protection=0
18916 +--FILE--
18917 +<?php
18918 +
18919 +require_once(dirname(__FILE__) . '/php_5_3_ns.inc');
18920 +
18921 +$a = new Foo\Bar\Baz();
18922 +$a->foo();
18923 +var_dump(Foo\Bar\sort());
18924 +?>
18925 +===DONE===
18926 +<?php exit(0); ?>
18927 +--EXPECTF--
18928 +array(4) {
18929 + [0]=>
18930 + int(1)
18931 + [1]=>
18932 + int(2)
18933 + [2]=>
18934 + int(3)
18935 + [3]=>
18936 + int(4)
18937 +}
18938 +array(4) {
18939 + [0]=>
18940 + int(1)
18941 + [1]=>
18942 + int(2)
18943 + [2]=>
18944 + int(3)
18945 + [3]=>
18946 + int(4)
18947 +}
18948 +string(8) "IT WORKS"
18949 +===DONE===
18950 diff -Naur php-5.3.1.orig/ext/apc/tests/apc53_003.phpt php-5.3.1/ext/apc/tests/apc53_003.phpt
18951 --- php-5.3.1.orig/ext/apc/tests/apc53_003.phpt 1970-01-01 01:00:00.000000000 +0100
18952 +++ php-5.3.1/ext/apc/tests/apc53_003.phpt 1970-01-01 10:13:08.000000000 +0100
18953 @@ -0,0 +1,31 @@
18954 +--TEST--
18955 +APC: anonymous functions (php 5.3)
18956 +--SKIPIF--
18957 +<?php
18958 + require_once(dirname(__FILE__) . '/skipif.inc');
18959 + if(version_compare(zend_version(), '2.3.0') < 0) {
18960 + echo "skip\n";
18961 + }
18962 +?>
18963 +--INI--
18964 +apc.enabled=1
18965 +apc.enable_cli=1
18966 +apc.file_update_protection=0
18967 +--FILE--
18968 +<?php
18969 +
18970 +$greet = function($name)
18971 +{
18972 + printf("Hello %s\r\n", $name);
18973 +};
18974 +
18975 +$greet('World');
18976 +$greet('PHP');
18977 +
18978 +?>
18979 +===DONE===
18980 +<?php exit(0); ?>
18981 +--EXPECTF--
18982 +Hello World
18983 +Hello PHP
18984 +===DONE===
18985 diff -Naur php-5.3.1.orig/ext/apc/tests/apc53_004.phpt php-5.3.1/ext/apc/tests/apc53_004.phpt
18986 --- php-5.3.1.orig/ext/apc/tests/apc53_004.phpt 1970-01-01 01:00:00.000000000 +0100
18987 +++ php-5.3.1/ext/apc/tests/apc53_004.phpt 1970-01-01 10:13:08.000000000 +0100
18988 @@ -0,0 +1,33 @@
18989 +--TEST--
18990 +APC: closures (php 5.3)
18991 +--SKIPIF--
18992 +<?php
18993 + require_once(dirname(__FILE__) . '/skipif.inc');
18994 + if(version_compare(zend_version(), '2.3.0') < 0) {
18995 + echo "skip\n";
18996 + }
18997 +?>
18998 +--INI--
18999 +apc.enabled=1
19000 +apc.enable_cli=1
19001 +apc.file_update_protection=0
19002 +--FILE--
19003 +<?php
19004 +function multiplier($n) {
19005 + return function($i) use ($n) {
19006 + return $n * $i;
19007 + };
19008 +}
19009 +
19010 +$doubler = multiplier(2);
19011 +$tripler = multiplier(3);
19012 +
19013 +echo "double of 9 is ".$doubler(9)."\n";
19014 +echo "triple of 4 is ".$tripler(4)."\n";
19015 +?>
19016 +===DONE===
19017 +<?php exit(0); ?>
19018 +--EXPECTF--
19019 +double of 9 is 18
19020 +triple of 4 is 12
19021 +===DONE===
19022 diff -Naur php-5.3.1.orig/ext/apc/tests/apc53_005.phpt php-5.3.1/ext/apc/tests/apc53_005.phpt
19023 --- php-5.3.1.orig/ext/apc/tests/apc53_005.phpt 1970-01-01 01:00:00.000000000 +0100
19024 +++ php-5.3.1/ext/apc/tests/apc53_005.phpt 1970-01-01 10:13:08.000000000 +0100
19025 @@ -0,0 +1,35 @@
19026 +--TEST--
19027 +APC: goto (php 5.3)
19028 +--SKIPIF--
19029 +<?php
19030 + require_once(dirname(__FILE__) . '/skipif.inc');
19031 + if(version_compare(zend_version(), '2.3.0') < 0) {
19032 + echo "skip\n";
19033 + }
19034 +?>
19035 +--INI--
19036 +apc.enabled=1
19037 +apc.enable_cli=1
19038 +apc.file_update_protection=0
19039 +--FILE--
19040 +<?php
19041 +
19042 +$i = 0;
19043 +a:
19044 +$i++;
19045 +if($i % 3 == 0) goto b;
19046 +echo "$i\n";
19047 +b:
19048 +if($i < 10) goto a;
19049 +?>
19050 +===DONE===
19051 +<?php exit(0); ?>
19052 +--EXPECTF--
19053 +1
19054 +2
19055 +4
19056 +5
19057 +7
19058 +8
19059 +10
19060 +===DONE===
19061 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_bin_001.phpt php-5.3.1/ext/apc/tests/apc_bin_001.phpt
19062 --- php-5.3.1.orig/ext/apc/tests/apc_bin_001.phpt 1970-01-01 01:00:00.000000000 +0100
19063 +++ php-5.3.1/ext/apc/tests/apc_bin_001.phpt 1970-01-01 10:13:08.000000000 +0100
19064 @@ -0,0 +1,23 @@
19065 +--TEST--
19066 +APC: bindump user cache
19067 +--SKIPIF--
19068 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19069 +--INI--
19070 +apc.enabled=1
19071 +apc.enable_cli=1
19072 +--FILE--
19073 +<?php
19074 +apc_clear_cache('file');
19075 +apc_store('testkey','testvalue');
19076 +$dump = apc_bin_dump(array(), NULL);
19077 +apc_clear_cache('user');
19078 +var_dump(apc_fetch('testkey'));
19079 +apc_bin_load($dump, APC_BIN_VERIFY_MD5 | APC_BIN_VERIFY_CRC32);
19080 +var_dump(apc_fetch('testkey'));
19081 +?>
19082 +===DONE===
19083 +<?php exit(0); ?>
19084 +--EXPECTF--
19085 +bool(false)
19086 +string(9) "testvalue"
19087 +===DONE===
19088 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_bin_002-1.inc php-5.3.1/ext/apc/tests/apc_bin_002-1.inc
19089 --- php-5.3.1.orig/ext/apc/tests/apc_bin_002-1.inc 1970-01-01 01:00:00.000000000 +0100
19090 +++ php-5.3.1/ext/apc/tests/apc_bin_002-1.inc 1970-01-01 10:13:08.000000000 +0100
19091 @@ -0,0 +1,42 @@
19092 +<?php
19093 +
19094 +$my_class = New my_class();
19095 +$my_i_class = New my_i_class();
19096 +
19097 +echo "apc bindump 002 test\n";
19098 +echo "\n";
19099 +echo "global scope execution: Success\n";
19100 +echo "\n";
19101 +echo "function execution: ".my_function()."\n";
19102 +echo "\n";
19103 +
19104 +echo "class static method: ".my_class::my_static_method()."\n";
19105 +echo "class dynamic method: ".$my_class->my_method()."\n";
19106 +echo "class static property: ".my_class::$my_static_property."\n";
19107 +echo "class dynamic property: ".$my_class->my_property."\n";
19108 +echo "class constant: ".my_class::my_constant."\n";
19109 +echo "\n";
19110 +echo "inherited class static method: ".my_i_class::my_static_method()."\n";
19111 +echo "inherited class dynamic method: ".$my_i_class->my_method()."\n";
19112 +echo "inherited class static property: ".my_i_class::$my_static_property."\n";
19113 +echo "inherited class dynamic property: ".$my_i_class->my_property."\n";
19114 +echo "inherited class constant: ".my_i_class::my_constant."\n";
19115 +echo "\n";
19116 +
19117 +
19118 +
19119 +function my_function() { return "Success"; }
19120 +
19121 +
19122 +class my_class {
19123 + static $my_static_property = "Success";
19124 + var $my_property = "Success";
19125 + const my_constant = "Success";
19126 + static function my_static_method() { return "Success"; }
19127 + function my_method() { return "Success"; }
19128 +}
19129 +
19130 +class my_i_class extends my_class {
19131 + function dummy() { return 1; }
19132 +}
19133 +
19134 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_bin_002-2.inc php-5.3.1/ext/apc/tests/apc_bin_002-2.inc
19135 --- php-5.3.1.orig/ext/apc/tests/apc_bin_002-2.inc 1970-01-01 01:00:00.000000000 +0100
19136 +++ php-5.3.1/ext/apc/tests/apc_bin_002-2.inc 1970-01-01 10:13:08.000000000 +0100
19137 @@ -0,0 +1,5 @@
19138 +<?php
19139 +
19140 +echo "Failed to use cached version!\n";
19141 +
19142 +?>
19143 diff -Naur php-5.3.1.orig/ext/apc/tests/apc_bin_002.phpt php-5.3.1/ext/apc/tests/apc_bin_002.phpt
19144 --- php-5.3.1.orig/ext/apc/tests/apc_bin_002.phpt 1970-01-01 01:00:00.000000000 +0100
19145 +++ php-5.3.1/ext/apc/tests/apc_bin_002.phpt 1970-01-01 10:13:08.000000000 +0100
19146 @@ -0,0 +1,53 @@
19147 +--TEST--
19148 +APC: bindump file cache part 1
19149 +--SKIPIF--
19150 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19151 +--INI--
19152 +apc.enabled=1
19153 +apc.enable_cli=1
19154 +apc.stat=0
19155 +apc.cache_by_default=1
19156 +apc.filters=
19157 +report_memleaks = Off
19158 +--FILE--
19159 +<?php
19160 +
19161 +define('filename',dirname(__FILE__).'/apc_bin_002.inc');
19162 +define('filename1',dirname(__FILE__).'/apc_bin_002-1.inc');
19163 +define('filename2',dirname(__FILE__).'/apc_bin_002-2.inc');
19164 +
19165 +copy(filename1, filename);
19166 +apc_compile_file(filename);
19167 +$data = apc_bin_dump(NULL, NULL);
19168 +
19169 +apc_clear_cache();
19170 +
19171 +copy(filename2, filename);
19172 +apc_bin_load($data, APC_BIN_VERIFY_MD5 | APC_BIN_VERIFY_CRC32);
19173 +include(filename);
19174 +
19175 +unlink(filename);
19176 +
19177 +?>
19178 +===DONE===
19179 +<? php exit(0); ?>
19180 +--EXPECTF--
19181 +apc bindump 002 test
19182 +
19183 +global scope execution: Success
19184 +
19185 +function execution: Success
19186 +
19187 +class static method: Success
19188 +class dynamic method: Success
19189 +class static property: Success
19190 +class dynamic property: Success
19191 +class constant: Success
19192 +
19193 +inherited class static method: Success
19194 +inherited class dynamic method: Success
19195 +inherited class static property: Success
19196 +inherited class dynamic property: Success
19197 +inherited class constant: Success
19198 +
19199 +===DONE===
19200 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_001.phpt php-5.3.1/ext/apc/tests/iterator_001.phpt
19201 --- php-5.3.1.orig/ext/apc/tests/iterator_001.phpt 1970-01-01 01:00:00.000000000 +0100
19202 +++ php-5.3.1/ext/apc/tests/iterator_001.phpt 1970-01-01 10:13:08.000000000 +0100
19203 @@ -0,0 +1,110 @@
19204 +--TEST--
19205 +APC: APCIterator general
19206 +--SKIPIF--
19207 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19208 +--INI--
19209 +apc.enabled=1
19210 +apc.enable_cli=1
19211 +apc.file_update_protection=0
19212 +--FILE--
19213 +<?php
19214 +
19215 +$it = new APCIterator('user');
19216 +for($i = 0; $i < 41; $i++) {
19217 + apc_store("key$i", "value$i");
19218 +}
19219 +foreach($it as $key=>$value) {
19220 + $vals[$key] = $value['key'];
19221 +}
19222 +ksort($vals);
19223 +var_dump($vals);
19224 +
19225 +?>
19226 +===DONE===
19227 +<?php exit(0); ?>
19228 +--EXPECT--
19229 +array(41) {
19230 + ["key0"]=>
19231 + string(4) "key0"
19232 + ["key1"]=>
19233 + string(4) "key1"
19234 + ["key10"]=>
19235 + string(5) "key10"
19236 + ["key11"]=>
19237 + string(5) "key11"
19238 + ["key12"]=>
19239 + string(5) "key12"
19240 + ["key13"]=>
19241 + string(5) "key13"
19242 + ["key14"]=>
19243 + string(5) "key14"
19244 + ["key15"]=>
19245 + string(5) "key15"
19246 + ["key16"]=>
19247 + string(5) "key16"
19248 + ["key17"]=>
19249 + string(5) "key17"
19250 + ["key18"]=>
19251 + string(5) "key18"
19252 + ["key19"]=>
19253 + string(5) "key19"
19254 + ["key2"]=>
19255 + string(4) "key2"
19256 + ["key20"]=>
19257 + string(5) "key20"
19258 + ["key21"]=>
19259 + string(5) "key21"
19260 + ["key22"]=>
19261 + string(5) "key22"
19262 + ["key23"]=>
19263 + string(5) "key23"
19264 + ["key24"]=>
19265 + string(5) "key24"
19266 + ["key25"]=>
19267 + string(5) "key25"
19268 + ["key26"]=>
19269 + string(5) "key26"
19270 + ["key27"]=>
19271 + string(5) "key27"
19272 + ["key28"]=>
19273 + string(5) "key28"
19274 + ["key29"]=>
19275 + string(5) "key29"
19276 + ["key3"]=>
19277 + string(4) "key3"
19278 + ["key30"]=>
19279 + string(5) "key30"
19280 + ["key31"]=>
19281 + string(5) "key31"
19282 + ["key32"]=>
19283 + string(5) "key32"
19284 + ["key33"]=>
19285 + string(5) "key33"
19286 + ["key34"]=>
19287 + string(5) "key34"
19288 + ["key35"]=>
19289 + string(5) "key35"
19290 + ["key36"]=>
19291 + string(5) "key36"
19292 + ["key37"]=>
19293 + string(5) "key37"
19294 + ["key38"]=>
19295 + string(5) "key38"
19296 + ["key39"]=>
19297 + string(5) "key39"
19298 + ["key4"]=>
19299 + string(4) "key4"
19300 + ["key40"]=>
19301 + string(5) "key40"
19302 + ["key5"]=>
19303 + string(4) "key5"
19304 + ["key6"]=>
19305 + string(4) "key6"
19306 + ["key7"]=>
19307 + string(4) "key7"
19308 + ["key8"]=>
19309 + string(4) "key8"
19310 + ["key9"]=>
19311 + string(4) "key9"
19312 +}
19313 +===DONE===
19314 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_002.phpt php-5.3.1/ext/apc/tests/iterator_002.phpt
19315 --- php-5.3.1.orig/ext/apc/tests/iterator_002.phpt 1970-01-01 01:00:00.000000000 +0100
19316 +++ php-5.3.1/ext/apc/tests/iterator_002.phpt 1970-01-01 10:13:08.000000000 +0100
19317 @@ -0,0 +1,36 @@
19318 +--TEST--
19319 +APC: APCIterator regex
19320 +--SKIPIF--
19321 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19322 +--INI--
19323 +apc.enabled=1
19324 +apc.enable_cli=1
19325 +apc.file_update_protection=0
19326 +--FILE--
19327 +<?php
19328 +
19329 +$it = new APCIterator('user', '/key[0-9]0/');
19330 +for($i = 0; $i < 41; $i++) {
19331 + apc_store("key$i", "value$i");
19332 +}
19333 +foreach($it as $key=>$value) {
19334 + $vals[$key] = $value['key'];
19335 +}
19336 +ksort($vals);
19337 +var_dump($vals);
19338 +
19339 +?>
19340 +===DONE===
19341 +<?php exit(0); ?>
19342 +--EXPECT--
19343 +array(4) {
19344 + ["key10"]=>
19345 + string(5) "key10"
19346 + ["key20"]=>
19347 + string(5) "key20"
19348 + ["key30"]=>
19349 + string(5) "key30"
19350 + ["key40"]=>
19351 + string(5) "key40"
19352 +}
19353 +===DONE===
19354 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_003.phpt php-5.3.1/ext/apc/tests/iterator_003.phpt
19355 --- php-5.3.1.orig/ext/apc/tests/iterator_003.phpt 1970-01-01 01:00:00.000000000 +0100
19356 +++ php-5.3.1/ext/apc/tests/iterator_003.phpt 1970-01-01 10:13:08.000000000 +0100
19357 @@ -0,0 +1,110 @@
19358 +--TEST--
19359 +APC: APCIterator chunk size
19360 +--SKIPIF--
19361 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19362 +--INI--
19363 +apc.enabled=1
19364 +apc.enable_cli=1
19365 +apc.file_update_protection=0
19366 +--FILE--
19367 +<?php
19368 +
19369 +$it = new APCIterator('user', NULL, APC_ITER_ALL, 10);
19370 +for($i = 0; $i < 41; $i++) {
19371 + apc_store("key$i", "value$i");
19372 +}
19373 +foreach($it as $key=>$value) {
19374 + $vals[$key] = $value['key'];
19375 +}
19376 +ksort($vals);
19377 +var_dump($vals);
19378 +
19379 +?>
19380 +===DONE===
19381 +<?php exit(0); ?>
19382 +--EXPECT--
19383 +array(41) {
19384 + ["key0"]=>
19385 + string(4) "key0"
19386 + ["key1"]=>
19387 + string(4) "key1"
19388 + ["key10"]=>
19389 + string(5) "key10"
19390 + ["key11"]=>
19391 + string(5) "key11"
19392 + ["key12"]=>
19393 + string(5) "key12"
19394 + ["key13"]=>
19395 + string(5) "key13"
19396 + ["key14"]=>
19397 + string(5) "key14"
19398 + ["key15"]=>
19399 + string(5) "key15"
19400 + ["key16"]=>
19401 + string(5) "key16"
19402 + ["key17"]=>
19403 + string(5) "key17"
19404 + ["key18"]=>
19405 + string(5) "key18"
19406 + ["key19"]=>
19407 + string(5) "key19"
19408 + ["key2"]=>
19409 + string(4) "key2"
19410 + ["key20"]=>
19411 + string(5) "key20"
19412 + ["key21"]=>
19413 + string(5) "key21"
19414 + ["key22"]=>
19415 + string(5) "key22"
19416 + ["key23"]=>
19417 + string(5) "key23"
19418 + ["key24"]=>
19419 + string(5) "key24"
19420 + ["key25"]=>
19421 + string(5) "key25"
19422 + ["key26"]=>
19423 + string(5) "key26"
19424 + ["key27"]=>
19425 + string(5) "key27"
19426 + ["key28"]=>
19427 + string(5) "key28"
19428 + ["key29"]=>
19429 + string(5) "key29"
19430 + ["key3"]=>
19431 + string(4) "key3"
19432 + ["key30"]=>
19433 + string(5) "key30"
19434 + ["key31"]=>
19435 + string(5) "key31"
19436 + ["key32"]=>
19437 + string(5) "key32"
19438 + ["key33"]=>
19439 + string(5) "key33"
19440 + ["key34"]=>
19441 + string(5) "key34"
19442 + ["key35"]=>
19443 + string(5) "key35"
19444 + ["key36"]=>
19445 + string(5) "key36"
19446 + ["key37"]=>
19447 + string(5) "key37"
19448 + ["key38"]=>
19449 + string(5) "key38"
19450 + ["key39"]=>
19451 + string(5) "key39"
19452 + ["key4"]=>
19453 + string(4) "key4"
19454 + ["key40"]=>
19455 + string(5) "key40"
19456 + ["key5"]=>
19457 + string(4) "key5"
19458 + ["key6"]=>
19459 + string(4) "key6"
19460 + ["key7"]=>
19461 + string(4) "key7"
19462 + ["key8"]=>
19463 + string(4) "key8"
19464 + ["key9"]=>
19465 + string(4) "key9"
19466 +}
19467 +===DONE===
19468 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_004.phpt php-5.3.1/ext/apc/tests/iterator_004.phpt
19469 --- php-5.3.1.orig/ext/apc/tests/iterator_004.phpt 1970-01-01 01:00:00.000000000 +0100
19470 +++ php-5.3.1/ext/apc/tests/iterator_004.phpt 1970-01-01 10:13:08.000000000 +0100
19471 @@ -0,0 +1,36 @@
19472 +--TEST--
19473 +APC: APCIterator regex & chunk size & list
19474 +--SKIPIF--
19475 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19476 +--INI--
19477 +apc.enabled=1
19478 +apc.enable_cli=1
19479 +apc.file_update_protection=0
19480 +--FILE--
19481 +<?php
19482 +
19483 +$it = new APCIterator('user', '/key[0-9]0/', APC_ITER_ALL, 1, APC_LIST_ACTIVE);
19484 +for($i = 0; $i < 41; $i++) {
19485 + apc_store("key$i", "value$i");
19486 +}
19487 +foreach($it as $key=>$value) {
19488 + $vals[$key] = $value['key'];
19489 +}
19490 +ksort($vals);
19491 +var_dump($vals);
19492 +
19493 +?>
19494 +===DONE===
19495 +<?php exit(0); ?>
19496 +--EXPECT--
19497 +array(4) {
19498 + ["key10"]=>
19499 + string(5) "key10"
19500 + ["key20"]=>
19501 + string(5) "key20"
19502 + ["key30"]=>
19503 + string(5) "key30"
19504 + ["key40"]=>
19505 + string(5) "key40"
19506 +}
19507 +===DONE===
19508 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_005.phpt php-5.3.1/ext/apc/tests/iterator_005.phpt
19509 --- php-5.3.1.orig/ext/apc/tests/iterator_005.phpt 1970-01-01 01:00:00.000000000 +0100
19510 +++ php-5.3.1/ext/apc/tests/iterator_005.phpt 1970-01-01 10:13:08.000000000 +0100
19511 @@ -0,0 +1,112 @@
19512 +--TEST--
19513 +APC: APCIterator delete
19514 +--SKIPIF--
19515 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19516 +--INI--
19517 +apc.enabled=1
19518 +apc.enable_cli=1
19519 +apc.file_update_protection=0
19520 +--FILE--
19521 +<?php
19522 +
19523 +$vals = array();
19524 +$vals2 = array();
19525 +$it = new APCIterator('user', '/key[0-9]0/');
19526 +for($i = 0; $i < 41; $i++) {
19527 + apc_store("key$i", "value$i");
19528 +}
19529 +apc_delete($it);
19530 +$it2 = new APCIterator('user');
19531 +foreach($it as $key=>$value) {
19532 + $vals[$key] = $value['key'];
19533 +}
19534 +foreach($it2 as $key=>$value) {
19535 + $vals2[$key] = $value['key'];
19536 +}
19537 +ksort($vals2);
19538 +var_dump($vals);
19539 +var_dump($vals2);
19540 +
19541 +?>
19542 +===DONE===
19543 +<?php exit(0); ?>
19544 +--EXPECT--
19545 +array(0) {
19546 +}
19547 +array(37) {
19548 + ["key0"]=>
19549 + string(4) "key0"
19550 + ["key1"]=>
19551 + string(4) "key1"
19552 + ["key11"]=>
19553 + string(5) "key11"
19554 + ["key12"]=>
19555 + string(5) "key12"
19556 + ["key13"]=>
19557 + string(5) "key13"
19558 + ["key14"]=>
19559 + string(5) "key14"
19560 + ["key15"]=>
19561 + string(5) "key15"
19562 + ["key16"]=>
19563 + string(5) "key16"
19564 + ["key17"]=>
19565 + string(5) "key17"
19566 + ["key18"]=>
19567 + string(5) "key18"
19568 + ["key19"]=>
19569 + string(5) "key19"
19570 + ["key2"]=>
19571 + string(4) "key2"
19572 + ["key21"]=>
19573 + string(5) "key21"
19574 + ["key22"]=>
19575 + string(5) "key22"
19576 + ["key23"]=>
19577 + string(5) "key23"
19578 + ["key24"]=>
19579 + string(5) "key24"
19580 + ["key25"]=>
19581 + string(5) "key25"
19582 + ["key26"]=>
19583 + string(5) "key26"
19584 + ["key27"]=>
19585 + string(5) "key27"
19586 + ["key28"]=>
19587 + string(5) "key28"
19588 + ["key29"]=>
19589 + string(5) "key29"
19590 + ["key3"]=>
19591 + string(4) "key3"
19592 + ["key31"]=>
19593 + string(5) "key31"
19594 + ["key32"]=>
19595 + string(5) "key32"
19596 + ["key33"]=>
19597 + string(5) "key33"
19598 + ["key34"]=>
19599 + string(5) "key34"
19600 + ["key35"]=>
19601 + string(5) "key35"
19602 + ["key36"]=>
19603 + string(5) "key36"
19604 + ["key37"]=>
19605 + string(5) "key37"
19606 + ["key38"]=>
19607 + string(5) "key38"
19608 + ["key39"]=>
19609 + string(5) "key39"
19610 + ["key4"]=>
19611 + string(4) "key4"
19612 + ["key5"]=>
19613 + string(4) "key5"
19614 + ["key6"]=>
19615 + string(4) "key6"
19616 + ["key7"]=>
19617 + string(4) "key7"
19618 + ["key8"]=>
19619 + string(4) "key8"
19620 + ["key9"]=>
19621 + string(4) "key9"
19622 +}
19623 +===DONE===
19624 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_006.phpt php-5.3.1/ext/apc/tests/iterator_006.phpt
19625 --- php-5.3.1.orig/ext/apc/tests/iterator_006.phpt 1970-01-01 01:00:00.000000000 +0100
19626 +++ php-5.3.1/ext/apc/tests/iterator_006.phpt 1970-01-01 10:13:08.000000000 +0100
19627 @@ -0,0 +1,1535 @@
19628 +--TEST--
19629 +APC: APCIterator formats
19630 +--SKIPIF--
19631 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
19632 +--INI--
19633 +apc.enabled=1
19634 +apc.enable_cli=1
19635 +apc.file_update_protection=0
19636 +--FILE--
19637 +<?php
19638 +
19639 +$formats = array(
19640 + APC_ITER_TYPE,
19641 + APC_ITER_KEY,
19642 + APC_ITER_FILENAME,
19643 + APC_ITER_DEVICE,
19644 + APC_ITER_INODE,
19645 + APC_ITER_VALUE,
19646 + APC_ITER_MD5,
19647 + APC_ITER_NUM_HITS,
19648 + APC_ITER_MTIME,
19649 + APC_ITER_CTIME,
19650 + APC_ITER_DTIME,
19651 + APC_ITER_ATIME,
19652 + APC_ITER_REFCOUNT,
19653 + APC_ITER_MEM_SIZE,
19654 + APC_ITER_TTL,
19655 + APC_ITER_NONE,
19656 + APC_ITER_ALL,
19657 + APC_ITER_ALL & ~APC_ITER_TTL,
19658 + APC_ITER_KEY | APC_ITER_NUM_HITS | APC_ITER_MEM_SIZE,
19659 + );
19660 +
19661 +$it_array = array();
19662 +
19663 +foreach ($formats as $idx => $format) {
19664 + $it_array[$idx] = new APCIterator('user', NULL, $format);
19665 +}
19666 +
19667 +for($i = 0; $i < 11; $i++) {
19668 + apc_store("key$i", "value$i");
19669 +}
19670 +
19671 +foreach ($it_array as $idx => $it) {
19672 + print_it($it, $idx);
19673 +}
19674 +
19675 +function print_it($it, $idx) {
19676 + echo "IT #$idx\n";
19677 + echo "============================\n";
19678 + foreach ($it as $key=>$value) {
19679 + var_dump($key);
19680 + var_dump($value);
19681 + }
19682 + echo "============================\n\n";
19683 +}
19684 +
19685 +?>
19686 +===DONE===
19687 +<?php exit(0); ?>
19688 +--EXPECTF--
19689 +IT #0
19690 +============================
19691 +string(4) "key0"
19692 +array(1) {
19693 + ["type"]=>
19694 + string(4) "user"
19695 +}
19696 +string(4) "key1"
19697 +array(1) {
19698 + ["type"]=>
19699 + string(4) "user"
19700 +}
19701 +string(4) "key2"
19702 +array(1) {
19703 + ["type"]=>
19704 + string(4) "user"
19705 +}
19706 +string(4) "key3"
19707 +array(1) {
19708 + ["type"]=>
19709 + string(4) "user"
19710 +}
19711 +string(4) "key4"
19712 +array(1) {
19713 + ["type"]=>
19714 + string(4) "user"
19715 +}
19716 +string(4) "key5"
19717 +array(1) {
19718 + ["type"]=>
19719 + string(4) "user"
19720 +}
19721 +string(4) "key6"
19722 +array(1) {
19723 + ["type"]=>
19724 + string(4) "user"
19725 +}
19726 +string(4) "key7"
19727 +array(1) {
19728 + ["type"]=>
19729 + string(4) "user"
19730 +}
19731 +string(4) "key8"
19732 +array(1) {
19733 + ["type"]=>
19734 + string(4) "user"
19735 +}
19736 +string(4) "key9"
19737 +array(1) {
19738 + ["type"]=>
19739 + string(4) "user"
19740 +}
19741 +string(5) "key10"
19742 +array(1) {
19743 + ["type"]=>
19744 + string(4) "user"
19745 +}
19746 +============================
19747 +
19748 +IT #1
19749 +============================
19750 +string(4) "key0"
19751 +array(1) {
19752 + ["key"]=>
19753 + string(4) "key0"
19754 +}
19755 +string(4) "key1"
19756 +array(1) {
19757 + ["key"]=>
19758 + string(4) "key1"
19759 +}
19760 +string(4) "key2"
19761 +array(1) {
19762 + ["key"]=>
19763 + string(4) "key2"
19764 +}
19765 +string(4) "key3"
19766 +array(1) {
19767 + ["key"]=>
19768 + string(4) "key3"
19769 +}
19770 +string(4) "key4"
19771 +array(1) {
19772 + ["key"]=>
19773 + string(4) "key4"
19774 +}
19775 +string(4) "key5"
19776 +array(1) {
19777 + ["key"]=>
19778 + string(4) "key5"
19779 +}
19780 +string(4) "key6"
19781 +array(1) {
19782 + ["key"]=>
19783 + string(4) "key6"
19784 +}
19785 +string(4) "key7"
19786 +array(1) {
19787 + ["key"]=>
19788 + string(4) "key7"
19789 +}
19790 +string(4) "key8"
19791 +array(1) {
19792 + ["key"]=>
19793 + string(4) "key8"
19794 +}
19795 +string(4) "key9"
19796 +array(1) {
19797 + ["key"]=>
19798 + string(4) "key9"
19799 +}
19800 +string(5) "key10"
19801 +array(1) {
19802 + ["key"]=>
19803 + string(5) "key10"
19804 +}
19805 +============================
19806 +
19807 +IT #2
19808 +============================
19809 +string(4) "key0"
19810 +array(0) {
19811 +}
19812 +string(4) "key1"
19813 +array(0) {
19814 +}
19815 +string(4) "key2"
19816 +array(0) {
19817 +}
19818 +string(4) "key3"
19819 +array(0) {
19820 +}
19821 +string(4) "key4"
19822 +array(0) {
19823 +}
19824 +string(4) "key5"
19825 +array(0) {
19826 +}
19827 +string(4) "key6"
19828 +array(0) {
19829 +}
19830 +string(4) "key7"
19831 +array(0) {
19832 +}
19833 +string(4) "key8"
19834 +array(0) {
19835 +}
19836 +string(4) "key9"
19837 +array(0) {
19838 +}
19839 +string(5) "key10"
19840 +array(0) {
19841 +}
19842 +============================
19843 +
19844 +IT #3
19845 +============================
19846 +string(4) "key0"
19847 +array(0) {
19848 +}
19849 +string(4) "key1"
19850 +array(0) {
19851 +}
19852 +string(4) "key2"
19853 +array(0) {
19854 +}
19855 +string(4) "key3"
19856 +array(0) {
19857 +}
19858 +string(4) "key4"
19859 +array(0) {
19860 +}
19861 +string(4) "key5"
19862 +array(0) {
19863 +}
19864 +string(4) "key6"
19865 +array(0) {
19866 +}
19867 +string(4) "key7"
19868 +array(0) {
19869 +}
19870 +string(4) "key8"
19871 +array(0) {
19872 +}
19873 +string(4) "key9"
19874 +array(0) {
19875 +}
19876 +string(5) "key10"
19877 +array(0) {
19878 +}
19879 +============================
19880 +
19881 +IT #4
19882 +============================
19883 +string(4) "key0"
19884 +array(0) {
19885 +}
19886 +string(4) "key1"
19887 +array(0) {
19888 +}
19889 +string(4) "key2"
19890 +array(0) {
19891 +}
19892 +string(4) "key3"
19893 +array(0) {
19894 +}
19895 +string(4) "key4"
19896 +array(0) {
19897 +}
19898 +string(4) "key5"
19899 +array(0) {
19900 +}
19901 +string(4) "key6"
19902 +array(0) {
19903 +}
19904 +string(4) "key7"
19905 +array(0) {
19906 +}
19907 +string(4) "key8"
19908 +array(0) {
19909 +}
19910 +string(4) "key9"
19911 +array(0) {
19912 +}
19913 +string(5) "key10"
19914 +array(0) {
19915 +}
19916 +============================
19917 +
19918 +IT #5
19919 +============================
19920 +string(4) "key0"
19921 +array(1) {
19922 + ["value"]=>
19923 + string(6) "value0"
19924 +}
19925 +string(4) "key1"
19926 +array(1) {
19927 + ["value"]=>
19928 + string(6) "value1"
19929 +}
19930 +string(4) "key2"
19931 +array(1) {
19932 + ["value"]=>
19933 + string(6) "value2"
19934 +}
19935 +string(4) "key3"
19936 +array(1) {
19937 + ["value"]=>
19938 + string(6) "value3"
19939 +}
19940 +string(4) "key4"
19941 +array(1) {
19942 + ["value"]=>
19943 + string(6) "value4"
19944 +}
19945 +string(4) "key5"
19946 +array(1) {
19947 + ["value"]=>
19948 + string(6) "value5"
19949 +}
19950 +string(4) "key6"
19951 +array(1) {
19952 + ["value"]=>
19953 + string(6) "value6"
19954 +}
19955 +string(4) "key7"
19956 +array(1) {
19957 + ["value"]=>
19958 + string(6) "value7"
19959 +}
19960 +string(4) "key8"
19961 +array(1) {
19962 + ["value"]=>
19963 + string(6) "value8"
19964 +}
19965 +string(4) "key9"
19966 +array(1) {
19967 + ["value"]=>
19968 + string(6) "value9"
19969 +}
19970 +string(5) "key10"
19971 +array(1) {
19972 + ["value"]=>
19973 + string(7) "value10"
19974 +}
19975 +============================
19976 +
19977 +IT #6
19978 +============================
19979 +string(4) "key0"
19980 +array(0) {
19981 +}
19982 +string(4) "key1"
19983 +array(0) {
19984 +}
19985 +string(4) "key2"
19986 +array(0) {
19987 +}
19988 +string(4) "key3"
19989 +array(0) {
19990 +}
19991 +string(4) "key4"
19992 +array(0) {
19993 +}
19994 +string(4) "key5"
19995 +array(0) {
19996 +}
19997 +string(4) "key6"
19998 +array(0) {
19999 +}
20000 +string(4) "key7"
20001 +array(0) {
20002 +}
20003 +string(4) "key8"
20004 +array(0) {
20005 +}
20006 +string(4) "key9"
20007 +array(0) {
20008 +}
20009 +string(5) "key10"
20010 +array(0) {
20011 +}
20012 +============================
20013 +
20014 +IT #7
20015 +============================
20016 +string(4) "key0"
20017 +array(1) {
20018 + ["num_hits"]=>
20019 + int(0)
20020 +}
20021 +string(4) "key1"
20022 +array(1) {
20023 + ["num_hits"]=>
20024 + int(0)
20025 +}
20026 +string(4) "key2"
20027 +array(1) {
20028 + ["num_hits"]=>
20029 + int(0)
20030 +}
20031 +string(4) "key3"
20032 +array(1) {
20033 + ["num_hits"]=>
20034 + int(0)
20035 +}
20036 +string(4) "key4"
20037 +array(1) {
20038 + ["num_hits"]=>
20039 + int(0)
20040 +}
20041 +string(4) "key5"
20042 +array(1) {
20043 + ["num_hits"]=>
20044 + int(0)
20045 +}
20046 +string(4) "key6"
20047 +array(1) {
20048 + ["num_hits"]=>
20049 + int(0)
20050 +}
20051 +string(4) "key7"
20052 +array(1) {
20053 + ["num_hits"]=>
20054 + int(0)
20055 +}
20056 +string(4) "key8"
20057 +array(1) {
20058 + ["num_hits"]=>
20059 + int(0)
20060 +}
20061 +string(4) "key9"
20062 +array(1) {
20063 + ["num_hits"]=>
20064 + int(0)
20065 +}
20066 +string(5) "key10"
20067 +array(1) {
20068 + ["num_hits"]=>
20069 + int(0)
20070 +}
20071 +============================
20072 +
20073 +IT #8
20074 +============================
20075 +string(4) "key0"
20076 +array(1) {
20077 + ["mtime"]=>
20078 + int(%d)
20079 +}
20080 +string(4) "key1"
20081 +array(1) {
20082 + ["mtime"]=>
20083 + int(%d)
20084 +}
20085 +string(4) "key2"
20086 +array(1) {
20087 + ["mtime"]=>
20088 + int(%d)
20089 +}
20090 +string(4) "key3"
20091 +array(1) {
20092 + ["mtime"]=>
20093 + int(%d)
20094 +}
20095 +string(4) "key4"
20096 +array(1) {
20097 + ["mtime"]=>
20098 + int(%d)
20099 +}
20100 +string(4) "key5"
20101 +array(1) {
20102 + ["mtime"]=>
20103 + int(%d)
20104 +}
20105 +string(4) "key6"
20106 +array(1) {
20107 + ["mtime"]=>
20108 + int(%d)
20109 +}
20110 +string(4) "key7"
20111 +array(1) {
20112 + ["mtime"]=>
20113 + int(%d)
20114 +}
20115 +string(4) "key8"
20116 +array(1) {
20117 + ["mtime"]=>
20118 + int(%d)
20119 +}
20120 +string(4) "key9"
20121 +array(1) {
20122 + ["mtime"]=>
20123 + int(%d)
20124 +}
20125 +string(5) "key10"
20126 +array(1) {
20127 + ["mtime"]=>
20128 + int(%d)
20129 +}
20130 +============================
20131 +
20132 +IT #9
20133 +============================
20134 +string(4) "key0"
20135 +array(1) {
20136 + ["creation_time"]=>
20137 + int(%d)
20138 +}
20139 +string(4) "key1"
20140 +array(1) {
20141 + ["creation_time"]=>
20142 + int(%d)
20143 +}
20144 +string(4) "key2"
20145 +array(1) {
20146 + ["creation_time"]=>
20147 + int(%d)
20148 +}
20149 +string(4) "key3"
20150 +array(1) {
20151 + ["creation_time"]=>
20152 + int(%d)
20153 +}
20154 +string(4) "key4"
20155 +array(1) {
20156 + ["creation_time"]=>
20157 + int(%d)
20158 +}
20159 +string(4) "key5"
20160 +array(1) {
20161 + ["creation_time"]=>
20162 + int(%d)
20163 +}
20164 +string(4) "key6"
20165 +array(1) {
20166 + ["creation_time"]=>
20167 + int(%d)
20168 +}
20169 +string(4) "key7"
20170 +array(1) {
20171 + ["creation_time"]=>
20172 + int(%d)
20173 +}
20174 +string(4) "key8"
20175 +array(1) {
20176 + ["creation_time"]=>
20177 + int(%d)
20178 +}
20179 +string(4) "key9"
20180 +array(1) {
20181 + ["creation_time"]=>
20182 + int(%d)
20183 +}
20184 +string(5) "key10"
20185 +array(1) {
20186 + ["creation_time"]=>
20187 + int(%d)
20188 +}
20189 +============================
20190 +
20191 +IT #10
20192 +============================
20193 +string(4) "key0"
20194 +array(1) {
20195 + ["deletion_time"]=>
20196 + int(0)
20197 +}
20198 +string(4) "key1"
20199 +array(1) {
20200 + ["deletion_time"]=>
20201 + int(0)
20202 +}
20203 +string(4) "key2"
20204 +array(1) {
20205 + ["deletion_time"]=>
20206 + int(0)
20207 +}
20208 +string(4) "key3"
20209 +array(1) {
20210 + ["deletion_time"]=>
20211 + int(0)
20212 +}
20213 +string(4) "key4"
20214 +array(1) {
20215 + ["deletion_time"]=>
20216 + int(0)
20217 +}
20218 +string(4) "key5"
20219 +array(1) {
20220 + ["deletion_time"]=>
20221 + int(0)
20222 +}
20223 +string(4) "key6"
20224 +array(1) {
20225 + ["deletion_time"]=>
20226 + int(0)
20227 +}
20228 +string(4) "key7"
20229 +array(1) {
20230 + ["deletion_time"]=>
20231 + int(0)
20232 +}
20233 +string(4) "key8"
20234 +array(1) {
20235 + ["deletion_time"]=>
20236 + int(0)
20237 +}
20238 +string(4) "key9"
20239 +array(1) {
20240 + ["deletion_time"]=>
20241 + int(0)
20242 +}
20243 +string(5) "key10"
20244 +array(1) {
20245 + ["deletion_time"]=>
20246 + int(0)
20247 +}
20248 +============================
20249 +
20250 +IT #11
20251 +============================
20252 +string(4) "key0"
20253 +array(1) {
20254 + ["access_time"]=>
20255 + int(%d)
20256 +}
20257 +string(4) "key1"
20258 +array(1) {
20259 + ["access_time"]=>
20260 + int(%d)
20261 +}
20262 +string(4) "key2"
20263 +array(1) {
20264 + ["access_time"]=>
20265 + int(%d)
20266 +}
20267 +string(4) "key3"
20268 +array(1) {
20269 + ["access_time"]=>
20270 + int(%d)
20271 +}
20272 +string(4) "key4"
20273 +array(1) {
20274 + ["access_time"]=>
20275 + int(%d)
20276 +}
20277 +string(4) "key5"
20278 +array(1) {
20279 + ["access_time"]=>
20280 + int(%d)
20281 +}
20282 +string(4) "key6"
20283 +array(1) {
20284 + ["access_time"]=>
20285 + int(%d)
20286 +}
20287 +string(4) "key7"
20288 +array(1) {
20289 + ["access_time"]=>
20290 + int(%d)
20291 +}
20292 +string(4) "key8"
20293 +array(1) {
20294 + ["access_time"]=>
20295 + int(%d)
20296 +}
20297 +string(4) "key9"
20298 +array(1) {
20299 + ["access_time"]=>
20300 + int(%d)
20301 +}
20302 +string(5) "key10"
20303 +array(1) {
20304 + ["access_time"]=>
20305 + int(%d)
20306 +}
20307 +============================
20308 +
20309 +IT #12
20310 +============================
20311 +string(4) "key0"
20312 +array(1) {
20313 + ["ref_count"]=>
20314 + int(0)
20315 +}
20316 +string(4) "key1"
20317 +array(1) {
20318 + ["ref_count"]=>
20319 + int(0)
20320 +}
20321 +string(4) "key2"
20322 +array(1) {
20323 + ["ref_count"]=>
20324 + int(0)
20325 +}
20326 +string(4) "key3"
20327 +array(1) {
20328 + ["ref_count"]=>
20329 + int(0)
20330 +}
20331 +string(4) "key4"
20332 +array(1) {
20333 + ["ref_count"]=>
20334 + int(0)
20335 +}
20336 +string(4) "key5"
20337 +array(1) {
20338 + ["ref_count"]=>
20339 + int(0)
20340 +}
20341 +string(4) "key6"
20342 +array(1) {
20343 + ["ref_count"]=>
20344 + int(0)
20345 +}
20346 +string(4) "key7"
20347 +array(1) {
20348 + ["ref_count"]=>
20349 + int(0)
20350 +}
20351 +string(4) "key8"
20352 +array(1) {
20353 + ["ref_count"]=>
20354 + int(0)
20355 +}
20356 +string(4) "key9"
20357 +array(1) {
20358 + ["ref_count"]=>
20359 + int(0)
20360 +}
20361 +string(5) "key10"
20362 +array(1) {
20363 + ["ref_count"]=>
20364 + int(0)
20365 +}
20366 +============================
20367 +
20368 +IT #13
20369 +============================
20370 +string(4) "key0"
20371 +array(1) {
20372 + ["mem_size"]=>
20373 + int(%d)
20374 +}
20375 +string(4) "key1"
20376 +array(1) {
20377 + ["mem_size"]=>
20378 + int(%d)
20379 +}
20380 +string(4) "key2"
20381 +array(1) {
20382 + ["mem_size"]=>
20383 + int(%d)
20384 +}
20385 +string(4) "key3"
20386 +array(1) {
20387 + ["mem_size"]=>
20388 + int(%d)
20389 +}
20390 +string(4) "key4"
20391 +array(1) {
20392 + ["mem_size"]=>
20393 + int(580)
20394 +}
20395 +string(4) "key5"
20396 +array(1) {
20397 + ["mem_size"]=>
20398 + int(%d)
20399 +}
20400 +string(4) "key6"
20401 +array(1) {
20402 + ["mem_size"]=>
20403 + int(%d)
20404 +}
20405 +string(4) "key7"
20406 +array(1) {
20407 + ["mem_size"]=>
20408 + int(%d)
20409 +}
20410 +string(4) "key8"
20411 +array(1) {
20412 + ["mem_size"]=>
20413 + int(%d)
20414 +}
20415 +string(4) "key9"
20416 +array(1) {
20417 + ["mem_size"]=>
20418 + int(%d)
20419 +}
20420 +string(5) "key10"
20421 +array(1) {
20422 + ["mem_size"]=>
20423 + int(%d)
20424 +}
20425 +============================
20426 +
20427 +IT #14
20428 +============================
20429 +string(4) "key0"
20430 +array(1) {
20431 + ["ttl"]=>
20432 + int(0)
20433 +}
20434 +string(4) "key1"
20435 +array(1) {
20436 + ["ttl"]=>
20437 + int(0)
20438 +}
20439 +string(4) "key2"
20440 +array(1) {
20441 + ["ttl"]=>
20442 + int(0)
20443 +}
20444 +string(4) "key3"
20445 +array(1) {
20446 + ["ttl"]=>
20447 + int(0)
20448 +}
20449 +string(4) "key4"
20450 +array(1) {
20451 + ["ttl"]=>
20452 + int(0)
20453 +}
20454 +string(4) "key5"
20455 +array(1) {
20456 + ["ttl"]=>
20457 + int(0)
20458 +}
20459 +string(4) "key6"
20460 +array(1) {
20461 + ["ttl"]=>
20462 + int(0)
20463 +}
20464 +string(4) "key7"
20465 +array(1) {
20466 + ["ttl"]=>
20467 + int(0)
20468 +}
20469 +string(4) "key8"
20470 +array(1) {
20471 + ["ttl"]=>
20472 + int(0)
20473 +}
20474 +string(4) "key9"
20475 +array(1) {
20476 + ["ttl"]=>
20477 + int(0)
20478 +}
20479 +string(5) "key10"
20480 +array(1) {
20481 + ["ttl"]=>
20482 + int(0)
20483 +}
20484 +============================
20485 +
20486 +IT #15
20487 +============================
20488 +string(4) "key0"
20489 +array(0) {
20490 +}
20491 +string(4) "key1"
20492 +array(0) {
20493 +}
20494 +string(4) "key2"
20495 +array(0) {
20496 +}
20497 +string(4) "key3"
20498 +array(0) {
20499 +}
20500 +string(4) "key4"
20501 +array(0) {
20502 +}
20503 +string(4) "key5"
20504 +array(0) {
20505 +}
20506 +string(4) "key6"
20507 +array(0) {
20508 +}
20509 +string(4) "key7"
20510 +array(0) {
20511 +}
20512 +string(4) "key8"
20513 +array(0) {
20514 +}
20515 +string(4) "key9"
20516 +array(0) {
20517 +}
20518 +string(5) "key10"
20519 +array(0) {
20520 +}
20521 +============================
20522 +
20523 +IT #16
20524 +============================
20525 +string(4) "key0"
20526 +array(11) {
20527 + ["type"]=>
20528 + string(4) "user"
20529 + ["key"]=>
20530 + string(4) "key0"
20531 + ["value"]=>
20532 + string(6) "value0"
20533 + ["num_hits"]=>
20534 + int(0)
20535 + ["mtime"]=>
20536 + int(%d)
20537 + ["creation_time"]=>
20538 + int(%d)
20539 + ["deletion_time"]=>
20540 + int(0)
20541 + ["access_time"]=>
20542 + int(%d)
20543 + ["ref_count"]=>
20544 + int(0)
20545 + ["mem_size"]=>
20546 + int(%d)
20547 + ["ttl"]=>
20548 + int(0)
20549 +}
20550 +string(4) "key1"
20551 +array(11) {
20552 + ["type"]=>
20553 + string(4) "user"
20554 + ["key"]=>
20555 + string(4) "key1"
20556 + ["value"]=>
20557 + string(6) "value1"
20558 + ["num_hits"]=>
20559 + int(0)
20560 + ["mtime"]=>
20561 + int(%d)
20562 + ["creation_time"]=>
20563 + int(%d)
20564 + ["deletion_time"]=>
20565 + int(0)
20566 + ["access_time"]=>
20567 + int(%d)
20568 + ["ref_count"]=>
20569 + int(0)
20570 + ["mem_size"]=>
20571 + int(%d)
20572 + ["ttl"]=>
20573 + int(0)
20574 +}
20575 +string(4) "key2"
20576 +array(11) {
20577 + ["type"]=>
20578 + string(4) "user"
20579 + ["key"]=>
20580 + string(4) "key2"
20581 + ["value"]=>
20582 + string(6) "value2"
20583 + ["num_hits"]=>
20584 + int(0)
20585 + ["mtime"]=>
20586 + int(%d)
20587 + ["creation_time"]=>
20588 + int(%d)
20589 + ["deletion_time"]=>
20590 + int(0)
20591 + ["access_time"]=>
20592 + int(%d)
20593 + ["ref_count"]=>
20594 + int(0)
20595 + ["mem_size"]=>
20596 + int(%d)
20597 + ["ttl"]=>
20598 + int(0)
20599 +}
20600 +string(4) "key3"
20601 +array(11) {
20602 + ["type"]=>
20603 + string(4) "user"
20604 + ["key"]=>
20605 + string(4) "key3"
20606 + ["value"]=>
20607 + string(6) "value3"
20608 + ["num_hits"]=>
20609 + int(0)
20610 + ["mtime"]=>
20611 + int(%d)
20612 + ["creation_time"]=>
20613 + int(%d)
20614 + ["deletion_time"]=>
20615 + int(0)
20616 + ["access_time"]=>
20617 + int(%d)
20618 + ["ref_count"]=>
20619 + int(0)
20620 + ["mem_size"]=>
20621 + int(%d)
20622 + ["ttl"]=>
20623 + int(0)
20624 +}
20625 +string(4) "key4"
20626 +array(11) {
20627 + ["type"]=>
20628 + string(4) "user"
20629 + ["key"]=>
20630 + string(4) "key4"
20631 + ["value"]=>
20632 + string(6) "value4"
20633 + ["num_hits"]=>
20634 + int(0)
20635 + ["mtime"]=>
20636 + int(%d)
20637 + ["creation_time"]=>
20638 + int(%d)
20639 + ["deletion_time"]=>
20640 + int(0)
20641 + ["access_time"]=>
20642 + int(%d)
20643 + ["ref_count"]=>
20644 + int(0)
20645 + ["mem_size"]=>
20646 + int(%d)
20647 + ["ttl"]=>
20648 + int(0)
20649 +}
20650 +string(4) "key5"
20651 +array(11) {
20652 + ["type"]=>
20653 + string(4) "user"
20654 + ["key"]=>
20655 + string(4) "key5"
20656 + ["value"]=>
20657 + string(6) "value5"
20658 + ["num_hits"]=>
20659 + int(0)
20660 + ["mtime"]=>
20661 + int(%d)
20662 + ["creation_time"]=>
20663 + int(%d)
20664 + ["deletion_time"]=>
20665 + int(0)
20666 + ["access_time"]=>
20667 + int(%d)
20668 + ["ref_count"]=>
20669 + int(0)
20670 + ["mem_size"]=>
20671 + int(%d)
20672 + ["ttl"]=>
20673 + int(0)
20674 +}
20675 +string(4) "key6"
20676 +array(11) {
20677 + ["type"]=>
20678 + string(4) "user"
20679 + ["key"]=>
20680 + string(4) "key6"
20681 + ["value"]=>
20682 + string(6) "value6"
20683 + ["num_hits"]=>
20684 + int(0)
20685 + ["mtime"]=>
20686 + int(%d)
20687 + ["creation_time"]=>
20688 + int(%d)
20689 + ["deletion_time"]=>
20690 + int(0)
20691 + ["access_time"]=>
20692 + int(%d)
20693 + ["ref_count"]=>
20694 + int(0)
20695 + ["mem_size"]=>
20696 + int(%d)
20697 + ["ttl"]=>
20698 + int(0)
20699 +}
20700 +string(4) "key7"
20701 +array(11) {
20702 + ["type"]=>
20703 + string(4) "user"
20704 + ["key"]=>
20705 + string(4) "key7"
20706 + ["value"]=>
20707 + string(6) "value7"
20708 + ["num_hits"]=>
20709 + int(0)
20710 + ["mtime"]=>
20711 + int(%d)
20712 + ["creation_time"]=>
20713 + int(%d)
20714 + ["deletion_time"]=>
20715 + int(0)
20716 + ["access_time"]=>
20717 + int(%d)
20718 + ["ref_count"]=>
20719 + int(0)
20720 + ["mem_size"]=>
20721 + int(%d)
20722 + ["ttl"]=>
20723 + int(0)
20724 +}
20725 +string(4) "key8"
20726 +array(11) {
20727 + ["type"]=>
20728 + string(4) "user"
20729 + ["key"]=>
20730 + string(4) "key8"
20731 + ["value"]=>
20732 + string(6) "value8"
20733 + ["num_hits"]=>
20734 + int(0)
20735 + ["mtime"]=>
20736 + int(%d)
20737 + ["creation_time"]=>
20738 + int(%d)
20739 + ["deletion_time"]=>
20740 + int(0)
20741 + ["access_time"]=>
20742 + int(%d)
20743 + ["ref_count"]=>
20744 + int(0)
20745 + ["mem_size"]=>
20746 + int(%d)
20747 + ["ttl"]=>
20748 + int(0)
20749 +}
20750 +string(4) "key9"
20751 +array(11) {
20752 + ["type"]=>
20753 + string(4) "user"
20754 + ["key"]=>
20755 + string(4) "key9"
20756 + ["value"]=>
20757 + string(6) "value9"
20758 + ["num_hits"]=>
20759 + int(0)
20760 + ["mtime"]=>
20761 + int(%d)
20762 + ["creation_time"]=>
20763 + int(%d)
20764 + ["deletion_time"]=>
20765 + int(0)
20766 + ["access_time"]=>
20767 + int(%d)
20768 + ["ref_count"]=>
20769 + int(0)
20770 + ["mem_size"]=>
20771 + int(%d)
20772 + ["ttl"]=>
20773 + int(0)
20774 +}
20775 +string(5) "key10"
20776 +array(11) {
20777 + ["type"]=>
20778 + string(4) "user"
20779 + ["key"]=>
20780 + string(5) "key10"
20781 + ["value"]=>
20782 + string(7) "value10"
20783 + ["num_hits"]=>
20784 + int(0)
20785 + ["mtime"]=>
20786 + int(%d)
20787 + ["creation_time"]=>
20788 + int(%d)
20789 + ["deletion_time"]=>
20790 + int(0)
20791 + ["access_time"]=>
20792 + int(%d)
20793 + ["ref_count"]=>
20794 + int(0)
20795 + ["mem_size"]=>
20796 + int(%d)
20797 + ["ttl"]=>
20798 + int(0)
20799 +}
20800 +============================
20801 +
20802 +IT #17
20803 +============================
20804 +string(4) "key0"
20805 +array(10) {
20806 + ["type"]=>
20807 + string(4) "user"
20808 + ["key"]=>
20809 + string(4) "key0"
20810 + ["value"]=>
20811 + string(6) "value0"
20812 + ["num_hits"]=>
20813 + int(0)
20814 + ["mtime"]=>
20815 + int(%d)
20816 + ["creation_time"]=>
20817 + int(%d)
20818 + ["deletion_time"]=>
20819 + int(0)
20820 + ["access_time"]=>
20821 + int(%d)
20822 + ["ref_count"]=>
20823 + int(0)
20824 + ["mem_size"]=>
20825 + int(%d)
20826 +}
20827 +string(4) "key1"
20828 +array(10) {
20829 + ["type"]=>
20830 + string(4) "user"
20831 + ["key"]=>
20832 + string(4) "key1"
20833 + ["value"]=>
20834 + string(6) "value1"
20835 + ["num_hits"]=>
20836 + int(0)
20837 + ["mtime"]=>
20838 + int(%d)
20839 + ["creation_time"]=>
20840 + int(%d)
20841 + ["deletion_time"]=>
20842 + int(0)
20843 + ["access_time"]=>
20844 + int(%d)
20845 + ["ref_count"]=>
20846 + int(0)
20847 + ["mem_size"]=>
20848 + int(%d)
20849 +}
20850 +string(4) "key2"
20851 +array(10) {
20852 + ["type"]=>
20853 + string(4) "user"
20854 + ["key"]=>
20855 + string(4) "key2"
20856 + ["value"]=>
20857 + string(6) "value2"
20858 + ["num_hits"]=>
20859 + int(0)
20860 + ["mtime"]=>
20861 + int(%d)
20862 + ["creation_time"]=>
20863 + int(%d)
20864 + ["deletion_time"]=>
20865 + int(0)
20866 + ["access_time"]=>
20867 + int(%d)
20868 + ["ref_count"]=>
20869 + int(0)
20870 + ["mem_size"]=>
20871 + int(%d)
20872 +}
20873 +string(4) "key3"
20874 +array(10) {
20875 + ["type"]=>
20876 + string(4) "user"
20877 + ["key"]=>
20878 + string(4) "key3"
20879 + ["value"]=>
20880 + string(6) "value3"
20881 + ["num_hits"]=>
20882 + int(0)
20883 + ["mtime"]=>
20884 + int(%d)
20885 + ["creation_time"]=>
20886 + int(%d)
20887 + ["deletion_time"]=>
20888 + int(0)
20889 + ["access_time"]=>
20890 + int(%d)
20891 + ["ref_count"]=>
20892 + int(0)
20893 + ["mem_size"]=>
20894 + int(%d)
20895 +}
20896 +string(4) "key4"
20897 +array(10) {
20898 + ["type"]=>
20899 + string(4) "user"
20900 + ["key"]=>
20901 + string(4) "key4"
20902 + ["value"]=>
20903 + string(6) "value4"
20904 + ["num_hits"]=>
20905 + int(0)
20906 + ["mtime"]=>
20907 + int(%d)
20908 + ["creation_time"]=>
20909 + int(%d)
20910 + ["deletion_time"]=>
20911 + int(0)
20912 + ["access_time"]=>
20913 + int(%d)
20914 + ["ref_count"]=>
20915 + int(0)
20916 + ["mem_size"]=>
20917 + int(%d)
20918 +}
20919 +string(4) "key5"
20920 +array(10) {
20921 + ["type"]=>
20922 + string(4) "user"
20923 + ["key"]=>
20924 + string(4) "key5"
20925 + ["value"]=>
20926 + string(6) "value5"
20927 + ["num_hits"]=>
20928 + int(0)
20929 + ["mtime"]=>
20930 + int(%d)
20931 + ["creation_time"]=>
20932 + int(%d)
20933 + ["deletion_time"]=>
20934 + int(0)
20935 + ["access_time"]=>
20936 + int(%d)
20937 + ["ref_count"]=>
20938 + int(0)
20939 + ["mem_size"]=>
20940 + int(%d)
20941 +}
20942 +string(4) "key6"
20943 +array(10) {
20944 + ["type"]=>
20945 + string(4) "user"
20946 + ["key"]=>
20947 + string(4) "key6"
20948 + ["value"]=>
20949 + string(6) "value6"
20950 + ["num_hits"]=>
20951 + int(0)
20952 + ["mtime"]=>
20953 + int(%d)
20954 + ["creation_time"]=>
20955 + int(%d)
20956 + ["deletion_time"]=>
20957 + int(0)
20958 + ["access_time"]=>
20959 + int(%d)
20960 + ["ref_count"]=>
20961 + int(0)
20962 + ["mem_size"]=>
20963 + int(%d)
20964 +}
20965 +string(4) "key7"
20966 +array(10) {
20967 + ["type"]=>
20968 + string(4) "user"
20969 + ["key"]=>
20970 + string(4) "key7"
20971 + ["value"]=>
20972 + string(6) "value7"
20973 + ["num_hits"]=>
20974 + int(0)
20975 + ["mtime"]=>
20976 + int(%d)
20977 + ["creation_time"]=>
20978 + int(%d)
20979 + ["deletion_time"]=>
20980 + int(0)
20981 + ["access_time"]=>
20982 + int(%d)
20983 + ["ref_count"]=>
20984 + int(0)
20985 + ["mem_size"]=>
20986 + int(%d)
20987 +}
20988 +string(4) "key8"
20989 +array(10) {
20990 + ["type"]=>
20991 + string(4) "user"
20992 + ["key"]=>
20993 + string(4) "key8"
20994 + ["value"]=>
20995 + string(6) "value8"
20996 + ["num_hits"]=>
20997 + int(0)
20998 + ["mtime"]=>
20999 + int(%d)
21000 + ["creation_time"]=>
21001 + int(%d)
21002 + ["deletion_time"]=>
21003 + int(0)
21004 + ["access_time"]=>
21005 + int(%d)
21006 + ["ref_count"]=>
21007 + int(0)
21008 + ["mem_size"]=>
21009 + int(%d)
21010 +}
21011 +string(4) "key9"
21012 +array(10) {
21013 + ["type"]=>
21014 + string(4) "user"
21015 + ["key"]=>
21016 + string(4) "key9"
21017 + ["value"]=>
21018 + string(6) "value9"
21019 + ["num_hits"]=>
21020 + int(0)
21021 + ["mtime"]=>
21022 + int(%d)
21023 + ["creation_time"]=>
21024 + int(%d)
21025 + ["deletion_time"]=>
21026 + int(0)
21027 + ["access_time"]=>
21028 + int(%d)
21029 + ["ref_count"]=>
21030 + int(0)
21031 + ["mem_size"]=>
21032 + int(%d)
21033 +}
21034 +string(5) "key10"
21035 +array(10) {
21036 + ["type"]=>
21037 + string(4) "user"
21038 + ["key"]=>
21039 + string(5) "key10"
21040 + ["value"]=>
21041 + string(7) "value10"
21042 + ["num_hits"]=>
21043 + int(0)
21044 + ["mtime"]=>
21045 + int(%d)
21046 + ["creation_time"]=>
21047 + int(%d)
21048 + ["deletion_time"]=>
21049 + int(0)
21050 + ["access_time"]=>
21051 + int(%d)
21052 + ["ref_count"]=>
21053 + int(0)
21054 + ["mem_size"]=>
21055 + int(%d)
21056 +}
21057 +============================
21058 +
21059 +IT #18
21060 +============================
21061 +string(4) "key0"
21062 +array(3) {
21063 + ["key"]=>
21064 + string(4) "key0"
21065 + ["num_hits"]=>
21066 + int(0)
21067 + ["mem_size"]=>
21068 + int(%d)
21069 +}
21070 +string(4) "key1"
21071 +array(3) {
21072 + ["key"]=>
21073 + string(4) "key1"
21074 + ["num_hits"]=>
21075 + int(0)
21076 + ["mem_size"]=>
21077 + int(%d)
21078 +}
21079 +string(4) "key2"
21080 +array(3) {
21081 + ["key"]=>
21082 + string(4) "key2"
21083 + ["num_hits"]=>
21084 + int(0)
21085 + ["mem_size"]=>
21086 + int(%d)
21087 +}
21088 +string(4) "key3"
21089 +array(3) {
21090 + ["key"]=>
21091 + string(4) "key3"
21092 + ["num_hits"]=>
21093 + int(0)
21094 + ["mem_size"]=>
21095 + int(%d)
21096 +}
21097 +string(4) "key4"
21098 +array(3) {
21099 + ["key"]=>
21100 + string(4) "key4"
21101 + ["num_hits"]=>
21102 + int(0)
21103 + ["mem_size"]=>
21104 + int(%d)
21105 +}
21106 +string(4) "key5"
21107 +array(3) {
21108 + ["key"]=>
21109 + string(4) "key5"
21110 + ["num_hits"]=>
21111 + int(0)
21112 + ["mem_size"]=>
21113 + int(%d)
21114 +}
21115 +string(4) "key6"
21116 +array(3) {
21117 + ["key"]=>
21118 + string(4) "key6"
21119 + ["num_hits"]=>
21120 + int(0)
21121 + ["mem_size"]=>
21122 + int(%d)
21123 +}
21124 +string(4) "key7"
21125 +array(3) {
21126 + ["key"]=>
21127 + string(4) "key7"
21128 + ["num_hits"]=>
21129 + int(0)
21130 + ["mem_size"]=>
21131 + int(%d)
21132 +}
21133 +string(4) "key8"
21134 +array(3) {
21135 + ["key"]=>
21136 + string(4) "key8"
21137 + ["num_hits"]=>
21138 + int(0)
21139 + ["mem_size"]=>
21140 + int(%d)
21141 +}
21142 +string(4) "key9"
21143 +array(3) {
21144 + ["key"]=>
21145 + string(4) "key9"
21146 + ["num_hits"]=>
21147 + int(0)
21148 + ["mem_size"]=>
21149 + int(%d)
21150 +}
21151 +string(5) "key10"
21152 +array(3) {
21153 + ["key"]=>
21154 + string(5) "key10"
21155 + ["num_hits"]=>
21156 + int(0)
21157 + ["mem_size"]=>
21158 + int(%d)
21159 +}
21160 +============================
21161 +
21162 +===DONE===
21163 diff -Naur php-5.3.1.orig/ext/apc/tests/iterator_007.phpt php-5.3.1/ext/apc/tests/iterator_007.phpt
21164 --- php-5.3.1.orig/ext/apc/tests/iterator_007.phpt 1970-01-01 01:00:00.000000000 +0100
21165 +++ php-5.3.1/ext/apc/tests/iterator_007.phpt 1970-01-01 10:13:08.000000000 +0100
21166 @@ -0,0 +1,36 @@
21167 +--TEST--
21168 +APC: APCIterator Overwriting the ctor
21169 +--SKIPIF--
21170 +<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
21171 +--INI--
21172 +apc.enabled=1
21173 +apc.enable_cli=1
21174 +--FILE--
21175 +<?php
21176 +class foobar extends APCIterator {
21177 + public function __construct() {}
21178 +}
21179 +$obj = new foobar;
21180 +var_dump(
21181 + $obj->rewind(),
21182 + $obj->current(),
21183 + $obj->key(),
21184 + $obj->next(),
21185 + $obj->valid(),
21186 + $obj->getTotalHits(),
21187 + $obj->getTotalSize(),
21188 + $obj->getTotalCount(),
21189 + apc_delete($obj)
21190 +);
21191 +?>
21192 +--EXPECTF--
21193 +bool(false)
21194 +bool(false)
21195 +bool(false)
21196 +bool(false)
21197 +bool(false)
21198 +bool(false)
21199 +bool(false)
21200 +bool(false)
21201 +bool(false)
21202 +
21203 diff -Naur php-5.3.1.orig/ext/apc/tests/php_5_3_ns.inc php-5.3.1/ext/apc/tests/php_5_3_ns.inc
21204 --- php-5.3.1.orig/ext/apc/tests/php_5_3_ns.inc 1970-01-01 01:00:00.000000000 +0100
21205 +++ php-5.3.1/ext/apc/tests/php_5_3_ns.inc 1970-01-01 10:13:08.000000000 +0100
21206 @@ -0,0 +1,18 @@
21207 +<?php
21208 +namespace Foo\Bar;
21209 +
21210 +function sort() {
21211 + $a = array(3,2,1,4);
21212 + \sort($a); // global scoping
21213 + var_dump($a);
21214 + return "IT WORKS";
21215 +}
21216 +class Baz {
21217 + public $i = 1;
21218 + protected $f = 3.14;
21219 + private $s = "hello world";
21220 +
21221 + public function foo() {
21222 + sort();
21223 + }
21224 +}
21225 diff -Naur php-5.3.1.orig/ext/apc/tests/skipif.inc php-5.3.1/ext/apc/tests/skipif.inc
21226 --- php-5.3.1.orig/ext/apc/tests/skipif.inc 1970-01-01 01:00:00.000000000 +0100
21227 +++ php-5.3.1/ext/apc/tests/skipif.inc 1970-01-01 10:14:21.000000000 +0100
21228 @@ -0,0 +1,6 @@
21229 +<?php
21230 +
21231 +if (!extension_loaded("apc")) die("skip");
21232 +//if (!ini_get('apc.enabled')) die("skip apc not enabled");
21233 +
21234 +?>
21235 diff -Naur php-5.3.1.orig/ext/apc/TODO php-5.3.1/ext/apc/TODO
21236 --- php-5.3.1.orig/ext/apc/TODO 1970-01-01 01:00:00.000000000 +0100
21237 +++ php-5.3.1/ext/apc/TODO 1970-01-01 10:13:08.000000000 +0100
21238 @@ -0,0 +1,30 @@
21239 +Known Bugs
21240 +
21241 +1. Gallery2 doesn't work with PHP5+APC. There is something wrong
21242 + with the way methods are restored in some edge case I haven't
21243 + been able to figure out yet.
21244 + To reproduce install gallery2 and click down to an individual photo.
21245 +
21246 +2. apc_store() probably needs some checks to skip trying to store
21247 + internal classes. Something along the lines of:
21248 +
21249 + if(Z_TYPE_P(val) == IS_OBJECT) {
21250 + zend_class_entry *ce = Z_OBJCE_P(val);
21251 + if(ce->type == ZEND_INTERNAL_CLASS) {
21252 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot cache internal objects");
21253 + RETURN_FALSE;
21254 + }
21255 + }
21256 +
21257 + in the apc_store() function in php_apc.c but I am wondering if it needs to do more
21258 + than that.
21259 +
21260 +Enhancements
21261 +
21262 +1. Some faster platform-specific locking mechanisms wouldd be nice. futex support
21263 + for the 2.6 Linux kernels, and/or x86-specific spinlock support.
21264 +
21265 +2. The optimizer needs a lot of work.
21266 +
21267 +3. Assert() elimination in the optimizer when some debug flag somewhere isn't set.
21268 +