예제 #1
0
파일: apc_main.c 프로젝트: nickl-/pecl-apc
/* {{{ 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;

}
예제 #2
0
파일: apc_mmap.c 프로젝트: krakjoe/apcu
void apc_unmap(apc_segment_t *segment)
{
	if (munmap(segment->shmaddr, segment->size) < 0) {
		apc_warning("apc_unmap: munmap failed");
	}

#ifdef APC_MEMPROTECT
	if (segment->roaddr && munmap(segment->roaddr, segment->size) < 0) {
		apc_warning("apc_unmap: munmap failed");
	}
#endif

}
예제 #3
0
파일: apc_cache.c 프로젝트: Cum6upck/apcu
/* {{{ apc_cache_make_context_ex */
PHP_APCU_API zend_bool apc_cache_make_context_ex(apc_context_t* context,
                                                 apc_serializer_t* serializer,
                                                 apc_malloc_t _malloc, 
                                                 apc_free_t _free, 
                                                 apc_protect_t _protect, 
                                                 apc_unprotect_t _unprotect, 
                                                 apc_pool_type pool_type, 
                                                 apc_copy_type copy_type, 
                                                 uint force_update) {
	/* attempt to create the pool */
	context->pool = apc_pool_create(
		pool_type, _malloc, _free, _protect, _unprotect
	);

	if (!context->pool) {
		apc_warning("Unable to allocate memory for pool.");
		return 0;
	}

	/* set context information */
	context->serializer = serializer;
	context->copy = copy_type;
	context->force_update = force_update;

	/* set this to avoid memory errors */
	memset(&context->copied, 0, sizeof(HashTable));

	return 1;
} /* }}} */
예제 #4
0
/* {{{ sma_debug_state(apc_sma_segment_t *segment, int canary_check, int verbose)
 *        useful for debuging state of memory blocks and free list, and sanity checking
 */
static void sma_debug_state(void* shmaddr, int canary_check, int verbose TSRMLS_DC) {
    sma_header_t *header = (sma_header_t*)shmaddr;
    block_t *cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
    block_t *prv = NULL;
    size_t avail;

    /* Verify free list */
    if (verbose) apc_warning("Free List: " TSRMLS_CC);
    while(1) {
        if (verbose) apc_warning(" 0x%x[%d] (s%d)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
        if (canary_check) CHECK_CANARY(cur);
        if (!cur->fnext) break;
        cur = BLOCKAT(cur->fnext);
        avail += cur->size;
        if (prv == cur) {
            apc_warning("Circular list detected!" TSRMLS_CC);
            assert(0);
        }
        if (prv && cur->fprev != OFFSET(prv)) {
            apc_warning("Previous pointer does not point to previous!" TSRMLS_CC);
            assert(0);
        }
        prv = cur;
    }
    assert(avail == header->avail);

    /* Verify each block */
    if (verbose) apc_warning("Block List: " TSRMLS_CC);
    cur = BLOCKAT(ALIGNWORD(sizeof(sma_header_t)));
    while(1) {
        if(!cur->fnext) {
            if (verbose) apc_warning(" 0x%x[%d] (s%d) (u)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
        } else {
            if (verbose) apc_warning(" 0x%x[%d] (s%d) (f)" TSRMLS_CC, cur, OFFSET(cur), cur->size);
        }
        if (canary_check) CHECK_CANARY(cur);
        if (!cur->size && !cur->fnext) break;
        if (!cur->size) {
            cur = BLOCKAT(OFFSET(cur) + ALIGNWORD(sizeof(block_t)));
        } else {
            cur = NEXT_SBLOCK(cur);
        }
        if (prv == cur) {
            apc_warning("Circular list detected!" TSRMLS_CC);
            assert(0);
        }
        prv = cur;
    }
}
예제 #5
0
파일: apc_signal.c 프로젝트: Cum6upck/apcu
/* {{{ apc_register_signal
 *  Set a handler for a previously installed signal and save so we can 
 *  callback when handled 
 */
static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*))
{
    struct sigaction sa = {{0}};
    apc_signal_entry_t p_sig = {0};

    if (sigaction(signo, NULL, &sa) == 0) {
        if ((void*)sa.sa_handler == (void*)handler) {
            return SUCCESS;
        }

        if (sa.sa_handler != SIG_ERR && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) {
            p_sig.signo = signo;
            p_sig.siginfo = ((sa.sa_flags & SA_SIGINFO) == SA_SIGINFO);
            p_sig.handler = (void *)sa.sa_handler;

            apc_signal_info.prev = (apc_signal_entry_t **)apc_erealloc(apc_signal_info.prev, (apc_signal_info.installed+1)*sizeof(apc_signal_entry_t *));
            apc_signal_info.prev[apc_signal_info.installed] = (apc_signal_entry_t *)apc_emalloc(sizeof(apc_signal_entry_t));
            *apc_signal_info.prev[apc_signal_info.installed++] = p_sig;
        } else {
            /* inherit flags and mask if already set */
            sigemptyset(&sa.sa_mask);
            sa.sa_flags = 0;
            sa.sa_flags |= SA_SIGINFO; /* we'll use a siginfo handler */
#if defined(SA_ONESHOT)
            sa.sa_flags = SA_ONESHOT;
#elif defined(SA_RESETHAND)
            sa.sa_flags = SA_RESETHAND;
#endif
        }
        sa.sa_handler = (void*)handler;

        if (sigaction(signo, &sa, NULL) < 0) {
            apc_warning("Error installing apc signal handler for %d", signo);
        }

        return SUCCESS;
    }
    return FAILURE;
} /* }}} */
예제 #6
0
파일: apc_main.c 프로젝트: nickl-/pecl-apc
/* {{{ 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;
}