php5-apc retained as dummy package.
[php5-apc.git] / apc_main.c
diff --git a/apc_main.c b/apc_main.c
deleted file mode 100644 (file)
index 3825399..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
-  +----------------------------------------------------------------------+
-  | APC                                                                  |
-  +----------------------------------------------------------------------+
-  | Copyright (c) 2008 The PHP Group                                     |
-  +----------------------------------------------------------------------+
-  | This source file is subject to version 3.01 of the PHP license,      |
-  | that is bundled with this package in the file LICENSE, and is        |
-  | available through the world-wide-web at the following url:           |
-  | http://www.php.net/license/3_01.txt                                  |
-  | If you did not receive a copy of the PHP license and are unable to   |
-  | obtain it through the world-wide-web, please send a note to          |
-  | license@php.net so we can mail you a copy immediately.               |
-  +----------------------------------------------------------------------+
-  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
-  |          Rasmus Lerdorf <rasmus@php.net>                             |
-  |          Arun C. Murthy <arunc@yahoo-inc.com>                        |
-  |          Gopal Vijayaraghavan <gopalv@yahoo-inc.com>                 |
-  +----------------------------------------------------------------------+
-
-   This software was contributed to PHP by Community Connect Inc. in 2002
-   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
-   Future revisions and derivatives of this source code must acknowledge
-   Community Connect Inc. as the original contributor of this module by
-   leaving this note intact in the source code.
-
-   All other licensing and usage conditions are those of the PHP Group.
-
- */
-
-/* $Id: apc_main.c,v 3.103.2.7 2008/05/11 18:57:00 rasmus Exp $ */
-
-#include "apc_php.h"
-#include "apc_main.h"
-#include "apc.h"
-#include "apc_lock.h"
-#include "apc_cache.h"
-#include "apc_compile.h"
-#include "apc_globals.h"
-#include "apc_sma.h"
-#include "apc_stack.h"
-#include "apc_zend.h"
-#include "SAPI.h"
-#if PHP_API_VERSION <= 20020918
-#if HAVE_APACHE
-#ifdef APC_PHP4_STAT
-#undef XtOffsetOf
-#include "httpd.h"
-#endif
-#endif
-#endif
-
-/* {{{ module variables */
-
-/* pointer to the original Zend engine compile_file function */
-typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC);
-static zend_compile_t *old_compile_file;
-
-/* }}} */
-
-/* {{{ get/set old_compile_file (to interact with other extensions that need the compile hook) */
-static zend_compile_t* set_compile_hook(zend_compile_t *ptr)
-{
-    zend_compile_t *retval = old_compile_file;
-
-    if (ptr != NULL) old_compile_file = ptr;
-    return retval;
-}
-/* }}} */
-
-/* {{{ install_function */
-static int install_function(apc_function_t fn TSRMLS_DC)
-{
-    zend_function *func;
-    int status;
-    
-    func = apc_copy_function_for_execution(fn.function);
-    
-    status =  zend_hash_add(EG(function_table),
-                      fn.name,
-                      fn.name_len+1,
-                      func, 
-                      sizeof(fn.function[0]),
-                      NULL);
-
-    efree(func);
-
-    if (status == FAILURE) {
-        /* apc_eprint("Cannot redeclare %s()", fn.name); */
-    }
-
-    return status;
-}
-/* }}} */
-
-/* {{{ install_class */
-static int install_class(apc_class_t cl TSRMLS_DC)
-{
-    zend_class_entry* class_entry = cl.class_entry;
-    zend_class_entry* parent = NULL;
-    int status;
-#ifdef ZEND_ENGINE_2
-    zend_class_entry** allocated_ce = NULL;
-#endif
-
-
-    /* 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;
-        }
-    }
-    
-#ifdef ZEND_ENGINE_2    
-    /*
-     * XXX: We need to free this somewhere...
-     */
-    allocated_ce = apc_php_malloc(sizeof(zend_class_entry*));    
-
-    if(!allocated_ce) {
-        return FAILURE;
-    }
-
-    *allocated_ce = 
-#endif        
-    class_entry =
-        apc_copy_class_entry_for_execution(cl.class_entry,
-                                           cl.is_derived);
-
-
-    /* restore parent class pointer for compile-time inheritance */
-    if (cl.parent_name != NULL) {
-#ifdef ZEND_ENGINE_2    
-        zend_class_entry** parent_ptr = NULL;
-        /*
-         * zend_lookup_class has to be due to presence of __autoload, 
-         * just looking up the EG(class_table) is not enough in php5!
-         * Even more dangerously, thanks to __autoload and people using
-         * class names as filepaths for inclusion, this has to be case
-         * sensitive. zend_lookup_class automatically does a case_fold
-         * internally, but passes the case preserved version to __autoload.
-         * Aside: Do NOT pass *strlen(cl.parent_name)+1* because 
-         * zend_lookup_class does it internally anyway!
-         */
-        status = zend_lookup_class(cl.parent_name,
-                                    strlen(cl.parent_name),
-                                    &parent_ptr TSRMLS_CC);
-#else
-        status = zend_hash_find(EG(class_table),
-                                cl.parent_name,
-                                strlen(cl.parent_name)+1,
-                                (void**) &parent);
-#endif
-        if (status == FAILURE) {
-            if(APCG(report_autofilter)) {
-                apc_wprint("Dynamic inheritance detected for class %s", cl.name);
-            }
-            class_entry->parent = NULL;
-            return status;
-        }
-        else {
-#ifdef ZEND_ENGINE_2            
-            parent = *parent_ptr;
-#endif 
-            class_entry->parent = parent;
-#ifdef ZEND_ENGINE_2
-            zend_do_inheritance(class_entry, parent TSRMLS_CC);
-#else
-            zend_do_inheritance(class_entry, parent);
-#endif
-        }
-
-
-    }
-
-#ifdef ZEND_ENGINE_2                           
-    status = zend_hash_add(EG(class_table),
-                           cl.name,
-                           cl.name_len+1,
-                           allocated_ce,
-                           sizeof(zend_class_entry*),
-                           NULL);
-#else                           
-    status = zend_hash_add(EG(class_table),
-                           cl.name,
-                           cl.name_len+1,
-                           class_entry,
-                           sizeof(zend_class_entry),
-                           NULL);
-#endif                           
-
-    if (status == FAILURE) {
-        apc_eprint("Cannot redeclare class %s", cl.name);
-    } 
-    return status;
-}
-/* }}} */
-
-/* {{{ uninstall_class */
-static int uninstall_class(apc_class_t cl TSRMLS_DC)
-{
-    int status;
-
-#ifdef ZEND_ENGINE_2                           
-    status = zend_hash_del(EG(class_table),
-                           cl.name,
-                           cl.name_len+1);
-#else                           
-    status = zend_hash_del(EG(class_table),
-                           cl.name,
-                           cl.name_len+1);
-#endif                           
-    if (status == FAILURE) {
-        apc_eprint("Cannot delete class %s", cl.name);
-    } 
-    return status;
-}
-/* }}} */
-
-/* {{{ compare_file_handles */
-static int compare_file_handles(void* a, void* b)
-{
-    zend_file_handle* fh1 = (zend_file_handle*)a;
-    zend_file_handle* fh2 = (zend_file_handle*)b;
-    return (fh1->type == fh2->type && 
-            fh1->filename == fh2->filename &&
-            fh1->opened_path == fh2->opened_path);
-}
-/* }}} */
-
-/* {{{ cached_compile */
-static zend_op_array* cached_compile(zend_file_handle* h,
-                                        int type TSRMLS_DC)
-{
-    apc_cache_entry_t* cache_entry;
-    int i, ii;
-
-    cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack));
-    assert(cache_entry != NULL);
-
-    if (cache_entry->data.file.classes) {
-        for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-            if(install_class(cache_entry->data.file.classes[i] TSRMLS_CC) == FAILURE) {
-                goto default_compile;
-            }
-        }
-    }
-
-    if (cache_entry->data.file.functions) {
-        for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
-            install_function(cache_entry->data.file.functions[i] TSRMLS_CC);
-        }
-    }
-
-
-    return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array TSRMLS_CC);
-
-default_compile:
-
-    if(APCG(report_autofilter)) {
-        apc_wprint("Autofiltering %s", h->opened_path);
-    }
-
-    if(cache_entry->data.file.classes) {
-        for(ii = 0; ii < i ; ii++) {
-            uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC);
-        }
-    }
-    
-    apc_stack_pop(APCG(cache_stack)); /* pop out cache_entry */
-    
-    apc_cache_release(apc_cache, cache_entry);
-
-    /* cannot free up cache data yet, it maybe in use */
-   
-    zend_llist_del_element(&CG(open_files), h, compare_file_handles); /* We leak fds without this hack */
-
-    h->type = ZEND_HANDLE_FILENAME;
-
-    return NULL;
-}
-/* }}} */
-
-/* {{{ my_compile_file
-   Overrides zend_compile_file */
-static zend_op_array* my_compile_file(zend_file_handle* h,
-                                               int type TSRMLS_DC)
-{
-    apc_cache_key_t key;
-    apc_cache_entry_t* cache_entry;
-    zend_op_array* op_array;
-    int num_functions, num_classes, ret;
-    zend_op_array* alloc_op_array;
-    apc_function_t* alloc_functions;
-    apc_class_t* alloc_classes;
-    time_t t;
-    char *path;
-    size_t mem_size;
-
-    if (!APCG(enabled) || apc_cache_busy(apc_cache)) { 
-        return old_compile_file(h, type TSRMLS_CC);
-    }
-
-    /* check our regular expression filters */
-    if (APCG(filters) && apc_compiled_filters) {
-        int ret = apc_regex_match_array(apc_compiled_filters, h->filename);
-        if(ret == APC_NEGATIVE_MATCH || (ret != APC_POSITIVE_MATCH && !APCG(cache_by_default))) {
-            return old_compile_file(h, type TSRMLS_CC);
-        }
-    } else if(!APCG(cache_by_default)) {
-        return old_compile_file(h, type TSRMLS_CC);
-    }
-
-#if PHP_API_VERSION < 20041225
-#if HAVE_APACHE && defined(APC_PHP4_STAT)
-    t = ((request_rec *)SG(server_context))->request_time;
-#else 
-    t = time(0);
-#endif
-#else 
-    t = sapi_get_request_time(TSRMLS_C);
-#endif
-
-#ifdef __DEBUG_APC__
-    fprintf(stderr,"1. h->opened_path=[%s]  h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename);
-#endif
-
-    /* try to create a cache key; if we fail, give up on caching */
-    if (!apc_cache_make_file_key(&key, h->filename, PG(include_path), t TSRMLS_CC)) {
-        return old_compile_file(h, type TSRMLS_CC);
-    }
-
-
-    if(!APCG(force_file_update)) {
-        /* search for the file in the cache */
-        cache_entry = apc_cache_find(apc_cache, key, t);
-    } else {
-        cache_entry = NULL;
-    }
-
-    if (cache_entry != NULL) {
-        int dummy = 1;
-        if (h->opened_path == NULL) {
-            h->opened_path = estrdup(cache_entry->data.file.filename);
-        }
-        zend_hash_add(&EG(included_files), h->opened_path, strlen(h->opened_path)+1, (void *)&dummy, sizeof(int), NULL);
-
-        zend_llist_add_element(&CG(open_files), h); /* We leak fds without this hack */
-
-        apc_stack_push(APCG(cache_stack), cache_entry);
-        op_array = cached_compile(h, type TSRMLS_CC);
-        if(op_array) {
-#ifdef APC_FILEHITS
-            /* If the file comes from the cache, add it to the global request file list */
-            add_next_index_string(APCG(filehits), h->filename, 1);
-#endif
-            return op_array;
-        }
-        if(APCG(report_autofilter)) {
-            apc_wprint("Recompiling %s", h->opened_path);
-        }
-        /* TODO: check what happens with EG(included_files) */
-    }
-    
-    /* remember how many functions and classes existed before compilation */
-    num_functions = zend_hash_num_elements(CG(function_table));
-    num_classes   = zend_hash_num_elements(CG(class_table));
-    
-    /* compile the file using the default compile function */
-    op_array = old_compile_file(h, type TSRMLS_CC);
-    if (op_array == NULL) {
-        return NULL;
-    }
-    /*
-     * Basically this will cause a file only to be cached on a percentage 
-     * of the attempts.  This is to avoid cache slams when starting up a
-     * very busy server or when modifying files on a very busy live server.
-     * There is no point having many processes all trying to cache the same
-     * file at the same time.  By introducing a chance of being cached
-     * we theoretically cut the cache slam problem by the given percentage.
-     * For example if apc.slam_defense is set to 66 then 2/3 of the attempts
-     * to cache an uncached file will be ignored.
-     */
-    if(APCG(slam_defense)) {
-        if(APCG(slam_rand)==-1) {
-            APCG(slam_rand) = (int)(100.0*rand()/(RAND_MAX+1.0));
-        }
-        if(APCG(slam_rand) < APCG(slam_defense)) {
-            return op_array;
-        }
-    }
-
-    /* Make sure the mtime reflects the files last known mtime in the case of fpstat==0 */
-    if(key.type == APC_CACHE_KEY_FPFILE) {
-        apc_fileinfo_t fileinfo;
-        struct stat *tmp_buf = NULL;
-        if(!strcmp(SG(request_info).path_translated, h->filename)) {
-            tmp_buf = sapi_get_stat(TSRMLS_C);  /* Apache has already done this stat() for us */
-        }
-        if(tmp_buf) { 
-            fileinfo.st_buf.sb = *tmp_buf;
-        } else {
-            if (apc_search_paths(h->filename, PG(include_path), &fileinfo) != 0) {
-#ifdef __DEBUG_APC__
-                fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",filename,SG(request_info).path_translated);
-#endif
-                return op_array;
-            }
-        }
-        key.mtime = fileinfo.st_buf.sb.st_mtime;
-    }
-
-    HANDLE_BLOCK_INTERRUPTIONS();
-
-#if NONBLOCKING_LOCK_AVAILABLE
-    if(APCG(write_lock)) {
-        if(!apc_cache_write_lock(apc_cache)) {
-            HANDLE_UNBLOCK_INTERRUPTIONS();
-            return op_array;
-        }
-    }
-#endif
-
-    mem_size = 0;
-    APCG(mem_size_ptr) = &mem_size;
-    if(!(alloc_op_array = apc_copy_op_array(NULL, op_array, apc_sma_malloc, apc_sma_free TSRMLS_CC))) {
-        apc_cache_expunge(apc_cache,t);
-        apc_cache_expunge(apc_user_cache,t);
-        APCG(mem_size_ptr) = NULL;
-#if NONBLOCKING_LOCK_AVAILABLE
-        if(APCG(write_lock)) {
-            apc_cache_write_unlock(apc_cache);
-        }
-#endif
-        HANDLE_UNBLOCK_INTERRUPTIONS();
-        return op_array;
-    }
-    
-    if(!(alloc_functions = apc_copy_new_functions(num_functions, apc_sma_malloc, apc_sma_free TSRMLS_CC))) {
-        apc_free_op_array(alloc_op_array, apc_sma_free);
-        apc_cache_expunge(apc_cache,t);
-        apc_cache_expunge(apc_user_cache,t);
-        APCG(mem_size_ptr) = NULL;
-#if NONBLOCKING_LOCK_AVAILABLE
-        if(APCG(write_lock)) {
-            apc_cache_write_unlock(apc_cache);
-        }
-#endif
-        HANDLE_UNBLOCK_INTERRUPTIONS();
-        return op_array;
-    }
-    if(!(alloc_classes = apc_copy_new_classes(op_array, num_classes, apc_sma_malloc, apc_sma_free TSRMLS_CC))) {
-        apc_free_op_array(alloc_op_array, apc_sma_free);
-        apc_free_functions(alloc_functions, apc_sma_free);
-        apc_cache_expunge(apc_cache,t);
-        apc_cache_expunge(apc_user_cache,t);
-        APCG(mem_size_ptr) = NULL;
-#if NONBLOCKING_LOCK_AVAILABLE
-        if(APCG(write_lock)) {
-            apc_cache_write_unlock(apc_cache);
-        }
-#endif
-        HANDLE_UNBLOCK_INTERRUPTIONS();
-        return op_array;
-    }
-
-    path = h->opened_path;
-    if(!path) path=h->filename;
-
-#ifdef __DEBUG_APC__
-    fprintf(stderr,"2. h->opened_path=[%s]  h->filename=[%s]\n", h->opened_path?h->opened_path:"null",h->filename);
-#endif
-
-    if(!(cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes))) {
-        apc_free_op_array(alloc_op_array, apc_sma_free);
-        apc_free_functions(alloc_functions, apc_sma_free);
-        apc_free_classes(alloc_classes, apc_sma_free);
-        apc_cache_expunge(apc_cache,t);
-        apc_cache_expunge(apc_user_cache,t);
-        APCG(mem_size_ptr) = NULL;
-#if NONBLOCKING_LOCK_AVAILABLE
-        if(APCG(write_lock)) {
-            apc_cache_write_unlock(apc_cache);
-        }
-#endif
-        HANDLE_UNBLOCK_INTERRUPTIONS();
-        return op_array;
-    }
-    APCG(mem_size_ptr) = NULL;
-    cache_entry->mem_size = mem_size;
-
-    if ((ret = apc_cache_insert(apc_cache, key, cache_entry, t)) != 1) {
-        apc_cache_free_entry(cache_entry);
-        if(ret==-1) {
-            apc_cache_expunge(apc_cache,t);
-            apc_cache_expunge(apc_user_cache,t);
-        }
-    }
-
-#if NONBLOCKING_LOCK_AVAILABLE
-    if(APCG(write_lock)) {
-        apc_cache_write_unlock(apc_cache);
-    }
-#endif
-    HANDLE_UNBLOCK_INTERRUPTIONS();
-
-    return op_array;
-}
-/* }}} */
-
-/* {{{ module init and shutdown */
-
-int apc_module_init(int module_number TSRMLS_DC)
-{
-    /* apc initialization */
-#if APC_MMAP
-    apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, APCG(mmap_file_mask));
-#else
-    apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, NULL);
-#endif
-    apc_cache = apc_cache_create(APCG(num_files_hint), APCG(gc_ttl), APCG(ttl));
-    apc_user_cache = apc_cache_create(APCG(user_entries_hint), APCG(gc_ttl), APCG(user_ttl));
-
-    apc_compiled_filters = apc_regex_compile_array(APCG(filters));
-
-    /* override compilation */
-    old_compile_file = zend_compile_file;
-    zend_compile_file = my_compile_file;
-    REGISTER_LONG_CONSTANT("\000apc_magic", (long)&set_compile_hook, CONST_PERSISTENT | CONST_CS);
-
-    APCG(initialized) = 1;
-    return 0;
-}
-
-int apc_module_shutdown(TSRMLS_D)
-{
-    if (!APCG(initialized))
-        return 0;
-
-    /* restore compilation */
-    zend_compile_file = old_compile_file;
-
-    /* 
-     * In case we got interrupted by a SIGTERM or something else during execution
-     * we may have cache entries left on the stack that we need to check to make
-     * sure that any functions or classes these may have added to the global function
-     * and class tables are removed before we blow away the memory that hold them.
-     * 
-     * This is merely to remove memory leak warnings - as the process is terminated
-     * immediately after shutdown. The following while loop can be removed without
-     * affecting anything else.
-     */
-    while (apc_stack_size(APCG(cache_stack)) > 0) {
-        int i;
-        apc_cache_entry_t* cache_entry = (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
-        if (cache_entry->data.file.functions) {
-            for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
-                zend_hash_del(EG(function_table),
-                    cache_entry->data.file.functions[i].name,
-                    cache_entry->data.file.functions[i].name_len+1);
-            }
-        }
-        if (cache_entry->data.file.classes) {
-            for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-                zend_hash_del(EG(class_table),
-                    cache_entry->data.file.classes[i].name,
-                    cache_entry->data.file.classes[i].name_len+1);
-            }
-        }
-        apc_cache_release(apc_cache, cache_entry);
-    }
-
-    apc_cache_destroy(apc_cache);
-    apc_cache_destroy(apc_user_cache);
-    apc_sma_cleanup();
-
-    APCG(initialized) = 0;
-    return 0;
-}
-
-/* }}} */
-
-/* {{{ process init and shutdown */
-int apc_process_init(int module_number TSRMLS_DC)
-{
-    return 0;
-}
-
-int apc_process_shutdown(TSRMLS_D)
-{
-    return 0;
-}
-/* }}} */
-
-/* {{{ apc_deactivate */
-static void apc_deactivate(TSRMLS_D)
-{
-    /* The execution stack was unwound, which prevented us from decrementing
-     * the reference counts on active cache entries in `my_execute`.
-     */
-    while (apc_stack_size(APCG(cache_stack)) > 0) {
-        int i;
-        zend_class_entry* zce = NULL;
-        void ** centry = (void*)(&zce);
-#ifdef ZEND_ENGINE_2
-        zend_class_entry** pzce = NULL;
-#endif
-        
-        apc_cache_entry_t* cache_entry =
-            (apc_cache_entry_t*) apc_stack_pop(APCG(cache_stack));
-
-        if (cache_entry->data.file.classes) {
-            for (i = 0; cache_entry->data.file.classes[i].class_entry != NULL; i++) {
-#ifdef ZEND_ENGINE_2
-                centry = (void**)&pzce; /* a triple indirection to get zend_class_entry*** */
-#endif
-                if(zend_hash_find(EG(class_table), 
-                    cache_entry->data.file.classes[i].name,
-                    cache_entry->data.file.classes[i].name_len+1,
-                    (void**)centry) == FAILURE)
-                {
-                    /* double inclusion of conditional classes ends up failing 
-                     * this lookup the second time around.
-                     */
-                    continue;
-                }
-
-#ifdef ZEND_ENGINE_2
-                zce = *pzce;
-#endif
-                zend_hash_del(EG(class_table),
-                    cache_entry->data.file.classes[i].name,
-                    cache_entry->data.file.classes[i].name_len+1);
-                
-                apc_free_class_entry_after_execution(zce);
-            }
-        }
-        apc_cache_release(apc_cache, cache_entry);
-    }
-
-}
-/* }}} */
-
-/* {{{ request init and shutdown */
-
-int apc_request_init(TSRMLS_D)
-{
-    apc_stack_clear(APCG(cache_stack));
-    APCG(slam_rand) = -1;
-    APCG(copied_zvals) = NULL;
-
-#ifdef APC_FILEHITS
-    ALLOC_INIT_ZVAL(APCG(filehits));
-    array_init(APCG(filehits));
-#endif
-
-    return 0;
-}
-
-int apc_request_shutdown(TSRMLS_D)
-{
-    apc_deactivate(TSRMLS_C);
-
-#ifdef APC_FILEHITS
-    zval_ptr_dtor(&APCG(filehits));
-#endif
-
-    return 0;
-}
-
-/* }}} */
-
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker
- * vim<600: expandtab sw=4 ts=4 sts=4
- */