void apc_interned_strings_init(TSRMLS_D) { int count = APCG(shm_strings_buffer) / (sizeof(Bucket) + sizeof(Bucket*) * 2); apc_interned_strings_data = (apc_interned_strings_data_t*) apc_sma_malloc(APCG(shm_strings_buffer) TSRMLS_CC); if (apc_interned_strings_data) { memset((void *)apc_interned_strings_data, 0, APCG(shm_strings_buffer)); CREATE_LOCK(APCSG(lock)); zend_hash_init(&APCSG(interned_strings), count, NULL, NULL, 1); APCSG(interned_strings).nTableMask = APCSG(interned_strings).nTableSize - 1; APCSG(interned_strings).arBuckets = (Bucket**)((char*)apc_interned_strings_data + sizeof(apc_interned_strings_data_t)); APCSG(interned_strings_start) = (char*)APCSG(interned_strings).arBuckets + APCSG(interned_strings).nTableSize * sizeof(Bucket *); APCSG(interned_strings_end) = (char*)apc_interned_strings_data + APCG(shm_strings_buffer); APCSG(interned_strings_top) = APCSG(interned_strings_start); old_interned_strings_start = CG(interned_strings_start); old_interned_strings_end = CG(interned_strings_end); old_new_interned_string = zend_new_interned_string; old_interned_strings_snapshot = zend_interned_strings_snapshot; old_interned_strings_restore = zend_interned_strings_restore; CG(interned_strings_start) = APCSG(interned_strings_start); CG(interned_strings_end) = APCSG(interned_strings_end); zend_new_interned_string = apc_dummy_new_interned_string_for_php; zend_interned_strings_snapshot = apc_dummy_interned_strings_snapshot_for_php; zend_interned_strings_restore = apc_dummy_interned_strings_restore_for_php; apc_copy_internal_strings(TSRMLS_C); } }
/* {{{ apc_lookup_class_hook */ int apc_lookup_class_hook(char *name, int len, ulong hash, zend_class_entry ***ce) { apc_class_t *cl; apc_context_t ctxt = {0,}; TSRMLS_FETCH(); if(zend_is_compiling(TSRMLS_C)) { return FAILURE; } if(zend_hash_quick_find(APCG(lazy_class_table), name, len, hash, (void**)&cl) == FAILURE) { return FAILURE; } ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC); ctxt.copy = APC_COPY_OUT_OPCODE; if(install_class(*cl, &ctxt, 0 TSRMLS_CC) == FAILURE) { apc_warning("apc_lookup_class_hook: could not install %s" TSRMLS_CC, name); return FAILURE; } if(zend_hash_quick_find(EG(class_table), name, len, hash, (void**)ce) == FAILURE) { apc_warning("apc_lookup_class_hook: known error trying to fetch class %s" TSRMLS_CC, name); return FAILURE; } return SUCCESS; }
/* {{{ apc_set_signals * Install our signal handlers */ void apc_set_signals() { if (apc_signal_info.installed == 0) { #if defined(SIGUSR1) && defined(APC_SIGNAL_CLEAR) apc_register_signal(SIGUSR1, apc_clear_cache); #endif if (APCG(coredump_unmap)) { /* ISO C standard signals that coredump */ apc_register_signal(SIGSEGV, apc_core_unmap); apc_register_signal(SIGABRT, apc_core_unmap); apc_register_signal(SIGFPE, apc_core_unmap); apc_register_signal(SIGILL, apc_core_unmap); /* extended signals that coredump */ #ifdef SIGBUS apc_register_signal(SIGBUS, apc_core_unmap); #endif #ifdef SIGABORT apc_register_signal(SIGABORT, apc_core_unmap); #endif #ifdef SIGEMT apc_register_signal(SIGEMT, apc_core_unmap); #endif #ifdef SIGIOT apc_register_signal(SIGIOT, apc_core_unmap); #endif #ifdef SIGQUIT apc_register_signal(SIGQUIT, apc_core_unmap); #endif #ifdef SIGSYS apc_register_signal(SIGSYS, apc_core_unmap); #endif #ifdef SIGTRAP apc_register_signal(SIGTRAP, apc_core_unmap); #endif #ifdef SIGXCPU apc_register_signal(SIGXCPU, apc_core_unmap); #endif #ifdef SIGXFSZ apc_register_signal(SIGXFSZ, apc_core_unmap); #endif } } } /* }}} */
PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zval *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zval *return_value) { apc_cache_entry_t *entry = NULL; if(!cache || apc_cache_busy(cache)) { return; } if (!key || Z_TYPE_P(key) != IS_STRING) { /* only strings, for now */ return; } #ifndef APC_LOCK_RECURSIVE if (APCG(recursion)++ == 0) { APC_LOCK(cache->header); } #else APC_LOCK(cache->header); #endif entry = apc_cache_find_internal( cache, Z_STR_P(key), ttl, 0); if (!entry) { int result = 0; fci->retval = return_value; zend_fcall_info_argn(fci, 1, key); zend_try { result = zend_call_function(fci, fcc); } zend_end_try (); if (result == SUCCESS) { zend_fcall_info_args_clear(fci, 1); if (!EG(exception)) { apc_cache_store_internal( cache, Z_STR_P(key), return_value, (uint32_t) ttl, 1); } } } else apc_cache_fetch_internal(cache, Z_STR_P(key), entry, ttl, &return_value);
/* {{{ apc_lookup_function_hook */ int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) { apc_function_t *fn; int status = FAILURE; apc_context_t ctxt = {0,}; TSRMLS_FETCH(); ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC); ctxt.copy = APC_COPY_OUT_OPCODE; if(zend_hash_quick_find(APCG(lazy_function_table), name, len, hash, (void**)&fn) == SUCCESS) { *fe = apc_copy_function_for_execution(fn->function, &ctxt TSRMLS_CC); if (fe == NULL) return FAILURE; status = zend_hash_add(EG(function_table), fn->name, fn->name_len+1, *fe, sizeof(zend_function), NULL); } return status; }
} static double my_time() { struct timeval a; double t; gettimeofday(&a, NULL); t = a.tv_sec + (a.tv_usec/1000000.00); return t; } #define RFC1867_DATA(name) \ ((request_data)->name) int apc_rfc1867_progress(uint event, void *event_data, void **extra TSRMLS_DC) { apc_rfc1867_data *request_data = &APCG(rfc1867_data); zval *track = NULL; switch (event) { case MULTIPART_EVENT_START: { multipart_event_start *data = (multipart_event_start *) event_data; RFC1867_DATA(content_length) = data->content_length; RFC1867_DATA(tracking_key)[0] = '\0'; RFC1867_DATA(name)[0] = '\0'; RFC1867_DATA(cancel_upload) = 0; RFC1867_DATA(temp_filename) = NULL; RFC1867_DATA(filename)[0] = '\0'; RFC1867_DATA(key_length) = 0; RFC1867_DATA(start_time) = my_time();
/* {{{ install_class */ static int install_class(apc_class_t cl, apc_context_t* ctxt, int lazy TSRMLS_DC) { zend_class_entry* class_entry = cl.class_entry; zend_class_entry* parent = NULL; int status; /* Special case for mangled names. Mangled names are unique to a file. * There is no way two classes with the same mangled name will occur, * unless a file is included twice. And if in case, a file is included * twice, all mangled name conflicts can be ignored and the class redeclaration * error may be deferred till runtime of the corresponding DECLARE_CLASS * calls. */ if(cl.name_len != 0 && cl.name[0] == '\0') { if(zend_hash_exists(CG(class_table), cl.name, cl.name_len+1)) { return SUCCESS; } } if(lazy && cl.name_len != 0 && cl.name[0] != '\0') { status = zend_hash_add(APCG(lazy_class_table), cl.name, cl.name_len+1, &cl, sizeof(apc_class_t), NULL); if(status == FAILURE) { zend_error(E_ERROR, "Cannot redeclare class %s", cl.name); } return status; } class_entry = apc_copy_class_entry_for_execution(cl.class_entry, ctxt TSRMLS_CC); if (class_entry == NULL) return FAILURE; /* restore parent class pointer for compile-time inheritance */ if (cl.parent_name != NULL) { zend_class_entry** parent_ptr = NULL; /* * __autoload brings in the old issues with mixed inheritance. * When a statically inherited class triggers autoload, it runs * afoul of a potential require_once "parent.php" in the previous * line, which when executed provides the parent class, but right * now goes and hits __autoload which could fail. * * missing parent == re-compile. * * whether __autoload is enabled or not, because __autoload errors * cause php to die. * * Aside: Do NOT pass *strlen(cl.parent_name)+1* because * zend_lookup_class_ex does it internally anyway! */ status = zend_lookup_class_ex(cl.parent_name, strlen(cl.parent_name), #ifdef ZEND_ENGINE_2_4 NULL, #endif 0, &parent_ptr TSRMLS_CC); if (status == FAILURE) { if(APCG(report_autofilter)) { apc_warning("Dynamic inheritance detected for class %s" TSRMLS_CC, cl.name); } class_entry->parent = NULL; return status; } else { parent = *parent_ptr; class_entry->parent = parent; zend_do_inheritance(class_entry, parent TSRMLS_CC); } } status = zend_hash_add(EG(class_table), cl.name, cl.name_len+1, &class_entry, sizeof(zend_class_entry*), NULL); if (status == FAILURE) { apc_error("Cannot redeclare class %s" TSRMLS_CC, cl.name); } return status; }