diff -p -r -u ../APC-3.1.3p1-old/apc_globals.h ./apc_globals.h --- ../APC-3.1.3p1-old/apc_globals.h 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_globals.h 2010-06-16 00:28:19.000000000 +0200 @@ -70,6 +70,7 @@ ZEND_BEGIN_MODULE_GLOBALS(apc) long user_ttl; #if APC_MMAP char *mmap_file_mask; /* mktemp-style file-mask to pass to mmap */ + char *mmap_address; /* mmap address (optional, 0=NULL) */ #endif char** filters; /* array of regex filters that prevent caching */ void* compiled_filters; /* compiled regex filters */ diff -p -r -u ../APC-3.1.3p1-old/apc_main.c ./apc_main.c --- ../APC-3.1.3p1-old/apc_main.c 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_main.c 2010-06-16 01:16:32.000000000 +0200 @@ -752,11 +752,14 @@ void apc_data_preload(TSRMLS_D) int apc_module_init(int module_number TSRMLS_DC) { + intptr_t mmap_address; + /* apc initialization */ #if APC_MMAP - apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, APCG(mmap_file_mask)); + mmap_address = atoll(APCG(mmap_address)); + apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, mmap_address, APCG(mmap_file_mask)); #else - apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, NULL); + apc_sma_init(APCG(shm_segments), APCG(shm_size)*1024*1024, 0, 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)); diff -p -r -u ../APC-3.1.3p1-old/apc_mmap.c ./apc_mmap.c --- ../APC-3.1.3p1-old/apc_mmap.c 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_mmap.c 2010-06-16 01:16:32.000000000 +0200 @@ -37,6 +37,8 @@ #include #include +static unsigned nseg = 0; + /* * Some operating systems (like FreeBSD) have a MAP_NOSYNC flag that * tells whatever update daemons might be running to not flush dirty @@ -53,7 +55,7 @@ # define MAP_ANON MAP_ANONYMOUS #endif -apc_segment_t apc_mmap(char *file_mask, size_t size) +apc_segment_t apc_mmap(char *file_mask, intptr_t address, size_t size) { apc_segment_t segment; @@ -105,24 +107,45 @@ apc_segment_t apc_mmap(char *file_mask, } shm_unlink(file_mask); } else { - /* - * Otherwise we do a normal filesystem mmap - */ - fd = mkstemp(file_mask); - if(fd == -1) { - apc_eprint("apc_mmap: mkstemp on %s failed:", file_mask); - goto error; - } - if (ftruncate(fd, size) < 0) { - close(fd); + if (address == 0) { + /* Do a mmap on a new / separate temp file */ + fd = mkstemp(file_mask); + if (fd == -1) { + apc_eprint("apc_mmap: mkstemp on %s failed:", file_mask); + goto error; + } + if (ftruncate(fd, size) < 0) { + close(fd); + unlink(file_mask); + apc_eprint("apc_mmap: ftruncate failed:"); + goto error; + } unlink(file_mask); - apc_eprint("apc_mmap: ftruncate failed:"); - goto error; + } else { + /* Always mmap the same file */ + if (++nseg != 1) { + apc_eprint("apc_mmap: only one shm segment supported"); + goto error; + } + fd = open(file_mask, O_RDWR | O_CREAT, 0600); + if (fd == -1) { + apc_eprint("apc_mmap: cannot open file: %s", file_mask); + goto error; + } + if (ftruncate(fd, size) < 0) { + close (fd); + unlink(file_mask); + apc_eprint("apc_mmap: ftruncate failed:"); + goto error; + } } - unlink(file_mask); } - segment.shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0); + segment.shmaddr = (void *)mmap((void*)address, size, PROT_READ | PROT_WRITE, flags, fd, 0); + if (segment.shmaddr == MAP_FAILED) { + apc_eprint("apc_mmap: mmap_failed:"); + goto error; + } #ifdef APC_MEMPROTECT if(remap) { diff -p -r -u ../APC-3.1.3p1-old/apc_mmap.h ./apc_mmap.h --- ../APC-3.1.3p1-old/apc_mmap.h 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_mmap.h 2010-06-16 00:28:19.000000000 +0200 @@ -38,7 +38,7 @@ /* Wrapper functions for shared memory mapped files */ #if APC_MMAP -apc_segment_t apc_mmap(char *file_mask, size_t size); +apc_segment_t apc_mmap(char *file_mask, intptr_t address, size_t size); void apc_unmap(apc_segment_t* segment); #endif diff -p -r -u ../APC-3.1.3p1-old/apc_sma.c ./apc_sma.c --- ../APC-3.1.3p1-old/apc_sma.c 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_sma.c 2010-06-16 01:16:32.000000000 +0200 @@ -333,7 +333,7 @@ static size_t sma_deallocate(void* shmad /* {{{ apc_sma_init */ -void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask) +void apc_sma_init(int numseg, size_t segsize, intptr_t mmap_address, char *mmap_file_mask) { uint i; @@ -368,7 +368,7 @@ void apc_sma_init(int numseg, size_t seg void* shmaddr; #if APC_MMAP - sma_segments[i] = apc_mmap(mmap_file_mask, sma_segsize); + sma_segments[i] = apc_mmap(mmap_file_mask, mmap_address, sma_segsize); if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6); #else sma_segments[i] = apc_shm_attach(apc_shm_create(NULL, i, sma_segsize)); diff -p -r -u ../APC-3.1.3p1-old/apc_sma.h ./apc_sma.h --- ../APC-3.1.3p1-old/apc_sma.h 1970-01-01 10:13:08.000000000 +0100 +++ ./apc_sma.h 2010-06-16 00:28:19.000000000 +0200 @@ -46,7 +46,7 @@ struct _apc_segment_t { #endif }; -extern void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask); +extern void apc_sma_init(int numseg, size_t segsize, intptr_t mmap_address, char *mmap_file_mask); extern void apc_sma_cleanup(); extern void* apc_sma_malloc(size_t size); extern void* apc_sma_malloc_ex(size_t size, size_t fragment, size_t* allocated); Only in .: config.h diff -p -r -u ../APC-3.1.3p1-old/php_apc.c ./php_apc.c --- ../APC-3.1.3p1-old/php_apc.c 1970-01-01 10:13:08.000000000 +0100 +++ ./php_apc.c 2010-06-16 01:16:32.000000000 +0200 @@ -189,6 +189,7 @@ STD_PHP_INI_ENTRY("apc.ttl", STD_PHP_INI_ENTRY("apc.user_ttl", "0", PHP_INI_SYSTEM, OnUpdateInt, user_ttl, zend_apc_globals, apc_globals) #if APC_MMAP STD_PHP_INI_ENTRY("apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apc_globals, apc_globals) +STD_PHP_INI_ENTRY("apc.mmap_address", "0", PHP_INI_SYSTEM, OnUpdateString, mmap_address, zend_apc_globals, apc_globals) #endif PHP_INI_ENTRY("apc.filters", NULL, PHP_INI_SYSTEM, OnUpdate_filters) STD_PHP_INI_BOOLEAN("apc.cache_by_default", "1", PHP_INI_ALL, OnUpdateBool, cache_by_default, zend_apc_globals, apc_globals) @@ -220,12 +221,22 @@ PHP_INI_END() /* {{{ PHP_MINFO_FUNCTION(apc) */ static PHP_MINFO_FUNCTION(apc) { + intptr_t iaddr; + char saddr[25]; + php_info_print_table_start(); php_info_print_table_header(2, "APC Support", APCG(enabled) ? "enabled" : "disabled"); php_info_print_table_row(2, "Version", PHP_APC_VERSION); #if APC_MMAP php_info_print_table_row(2, "MMAP Support", "Enabled"); php_info_print_table_row(2, "MMAP File Mask", APCG(mmap_file_mask)); +/* php_info_print_table_row(2, "raw MMAP Address", APCG(mmap_address));*/ + iaddr = atoll(APCG(mmap_address)); + if (iaddr != 0) + sprintf(saddr, "0x%lx", iaddr); + else + sprintf(saddr, "NULL"); + php_info_print_table_row(2, "MMAP Address", saddr); #else php_info_print_table_row(2, "MMAP Support", "Disabled"); #endif