1
0
Fork 0

closes #287: namespace support

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1146 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 2012-08-23 08:27:54 +00:00
parent 6e865a75e6
commit d2e943a191
8 changed files with 408 additions and 58 deletions

View File

@ -3,6 +3,8 @@ API Changes
========
* chg: proto array xcache_clear_cache(int type, [ int id = -1 ]). -1 means all cache splits
* new: proto array xcache_enable_cache(int type, [ int id = -1, [ bool enable = true ] ])
* new: proto array xcache_admin_namespace()
* new: proto array xcache_set_namespace(string namespace)
Ini Settings Changes
========
@ -17,6 +19,7 @@ ChangeLog
* closes #73: warn for improper PHP_FCGI_CHILDREN setting fcgi mode (>=PHP_5_3)
* closes #174: updates api to support "clear all cache"
* closes #198: support for caching protocol url
* closes #287: namespace support
* fixes #39: ini_set never work for xcache.coverager setting. use API instead
* code refactor
* uses extension= to load XCache. loading via zend_extension= is unsupported

1
NEWS
View File

@ -5,6 +5,7 @@
* updates api, adds a few ini
* uses extension= to load XCache. loading via zend_extension= is unsupported
* updates XCache admin page
* namespace support
* professional helpers
* adds an diagnosis module to give advise @ htdocs
* auto disable caching on crash @ runtime

View File

@ -6,9 +6,14 @@ if (!isset($_GET['name'])) {
die("missing name");
}
$name = $_GET['name'];
// trigger auth
$vcnt = xcache_count(XC_TYPE_VAR);
xcache_admin_namespace();
$name = $_GET['name'];
if (!empty($config['enable_eval'])) {
eval('$name = ' . $name . ';');
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($config['enable_eval'])) {

View File

@ -1,6 +1,6 @@
<?php include "../common/header.tpl.php"; ?>
<?php
$h_name = htmlspecialchars($name);
$h_name = htmlspecialchars(var_export($name, true));
$h_value = htmlspecialchars($value);
?>
<form method="post" action="">

View File

@ -257,6 +257,7 @@ if (!extension_loaded('XCache')) {
}
xcache_count(XC_TYPE_PHP); // trigger auth
xcache_admin_namespace();
$doTypes = array(
'' => _T('Summary'),

View File

@ -60,7 +60,6 @@ foreach ($entries as $i => $entry) {
<tr $class>
TR;
$name = htmlspecialchars($entry['name']);
$hits = number_format($entry['hits']);
$size = size($entry['size']);
if ($isphp) {
@ -80,19 +79,25 @@ TR;
}
if ($isphp) {
$namelink = $name;
$hname = htmlspecialchars($entry['name']);
$namelink = $hname;
echo <<<ENTRY
<td>{$entry['cache_name']} {$i}</td>
ENTRY;
}
else {
$name = $entry['name'];
if (!empty($config['enable_eval'])) {
$name = var_export($name, true);
}
$uname = urlencode($name);
$hname = htmlspecialchars(str_replace("\0", "\\0", $entry['name']));
echo <<<ENTRY
<td><label><input type="checkbox" name="remove[]" value="{$name}"/>{$entry['cache_name']} {$i}</label></td>
<td><label><input type="checkbox" name="remove[]" value="{$hname}"/>{$entry['cache_name']} {$i}</label></td>
ENTRY;
$uname = urlencode($entry['name']);
$namelink = "<a href=\"edit.php?name=$uname\">$name</a>";
$namelink = "<a href=\"edit.php?name=$uname\">$hname</a>";
}
echo <<<ENTRY

View File

@ -144,6 +144,10 @@ static zend_compile_file_t *old_compile_file = NULL;
static zend_bool xc_readonly_protection = 0;
static zend_ulong xc_var_namespace_mode = 0;
static char *xc_var_namespace = NULL;
zend_bool xc_have_op_array_ctor = 0;
/* }}} */
@ -256,7 +260,7 @@ static inline int xc_entry_equal_unlocked(xc_entry_type_t type, const xc_entry_t
if (entry1->name_type == IS_UNICODE) {
return entry1->name.ustr.len == entry2->name.ustr.len
&& memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0;
&& memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(entry1->name.ustr.val[0])) == 0;
}
#endif
return entry1->name.str.len == entry2->name.str.len
@ -269,33 +273,6 @@ static inline int xc_entry_equal_unlocked(xc_entry_type_t type, const xc_entry_t
return 0;
}
/* }}} */
static inline int xc_entry_has_prefix_unlocked(xc_entry_type_t type, xc_entry_t *entry, zval *prefix) /* {{{ */
{
/* this function isn't required but can be in unlocked */
#ifdef IS_UNICODE
if (entry->name_type != prefix->type) {
return 0;
}
if (entry->name_type == IS_UNICODE) {
if (entry->name.ustr.len < Z_USTRLEN_P(prefix)) {
return 0;
}
return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefix), Z_USTRLEN_P(prefix) * sizeof(UChar)) == 0;
}
#endif
if (prefix->type != IS_STRING) {
return 0;
}
if (entry->name.str.len < Z_STRLEN_P(prefix)) {
return 0;
}
return memcmp(entry->name.str.val, Z_STRVAL_P(prefix), Z_STRLEN_P(prefix)) == 0;
}
/* }}} */
static void xc_entry_add_unlocked(xc_cached_t *cached, xc_hash_value_t entryslotid, xc_entry_t *entry) /* {{{ */
{
xc_entry_t **head = &(cached->entries[entryslotid]);
@ -2306,6 +2283,308 @@ static void xc_gc_op_array(void *pDest) /* {{{ */
}
/* }}} */
/* variable namespace */
#ifdef IS_UNICODE
void xc_var_namespace_init_from_unicodel(const UChar *string, int len TSRMLS_DC) /* {{{ */
{
if (!len) {
#ifdef IS_UNICODE
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_hard));
#endif
ZVAL_EMPTY_STRING(&XG(var_namespace_hard));
}
else {
ZVAL_UNICODE_L(&XG(uvar_namespace_hard), string, len, 1);
/* TODO: copy to var */
}
}
/* }}} */
#endif
void xc_var_namespace_init_from_stringl(const char *string, int len TSRMLS_DC) /* {{{ */
{
if (!len) {
#ifdef IS_UNICODE
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_hard));
#endif
ZVAL_EMPTY_STRING(&XG(var_namespace_hard));
}
else {
ZVAL_STRINGL(&XG(var_namespace_hard), string, len, 1);
#ifdef IS_UNICODE
/* TODO: copy to uvar */
#endif
}
}
/* }}} */
void xc_var_namespace_init_from_long(long value TSRMLS_DC) /* {{{ */
{
ZVAL_LONG(&XG(var_namespace_hard), value);
#ifdef IS_UNICODE
/* TODO: copy to uvar_namespace */
#endif
}
/* }}} */
#ifdef IS_UNICODE
void xc_var_namespace_set_unicodel(const UChar *unicode, int len TSRMLS_DC) /* {{{ */
{
zval_dtor(&XG(uvar_namespace_soft));
zval_dtor(&XG(var_namespace_soft));
if (len) {
if (!Z_USTRLEN_P(&XG(uvar_namespace_soft))) {
ZVAL_UNICODEL(&XG(uvar_namespace_soft), unicode, len, 1);
}
else {
int buffer_len = Z_USTRLEN_P(&XG(var_namespace_hard)) + 1 + len;
char *buffer = emalloc((buffer_len + 1) * sizeof(unicode[0]));
char *p = buffer;
memcpy(p, Z_USTRVAL_P(&XG(var_namespace_hard)), (Z_USTRLEN_P(&XG(var_namespace_hard)) + 1));
p += (Z_USTRLEN_P(&XG(var_namespace_hard)) + 1) * sizeof(unicode[0]);
memcpy(p, unicode, (len + 1) * sizeof(unicode[0]));
ZVAL_UNICODEL(&XG(uvar_namespace_soft), buffer, buffer_len, 0);
}
/* TODO: copy to var */
}
else {
#ifdef IS_UNICODE
XG(uvar_namespace_soft) = XG(uvar_namespace_hard);
zval_copy_ctor(&XG(uvar_namespace_soft));
#endif
XG(var_namespace_soft) = XG(var_namespace_hard);
zval_copy_ctor(&XG(var_namespace_soft));
}
}
/* }}} */
#endif
void xc_var_namespace_set_stringl(const char *string, int len TSRMLS_DC) /* {{{ */
{
#ifdef IS_UNICODE
zval_dtor(&XG(uvar_namespace_soft));
#endif
zval_dtor(&XG(var_namespace_soft));
if (len) {
if (!Z_STRLEN_P(&XG(var_namespace_soft))) {
ZVAL_STRINGL(&XG(var_namespace_soft), string, len, 1);
}
else {
int buffer_len = Z_STRLEN_P(&XG(var_namespace_hard)) + 1 + len;
char *buffer = emalloc(buffer_len + 1);
char *p = buffer;
memcpy(p, Z_STRVAL_P(&XG(var_namespace_hard)), Z_STRLEN_P(&XG(var_namespace_hard)) + 1);
p += Z_STRLEN_P(&XG(var_namespace_hard)) + 1;
memcpy(p, string, len + 1);
ZVAL_STRINGL(&XG(var_namespace_soft), buffer, buffer_len, 0);
}
#ifdef IS_UNICODE
/* TODO: copy to uvar */
#endif
}
else {
#ifdef IS_UNICODE
XG(uvar_namespace_soft) = XG(uvar_namespace_hard);
zval_copy_ctor(&XG(uvar_namespace_soft));
#endif
XG(var_namespace_soft) = XG(var_namespace_hard);
zval_copy_ctor(&XG(var_namespace_soft));
}
}
/* }}} */
static void xc_var_namespace_break(TSRMLS_D) /* {{{ */
{
#ifdef IS_UNICODE
zval_dtor(&XG(uvar_namespace_soft));
#endif
zval_dtor(&XG(var_namespace_soft));
#ifdef IS_UNICODE
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_soft));
#endif
ZVAL_EMPTY_STRING(&XG(var_namespace_soft));
}
/* }}} */
static void xc_var_namespace_init(TSRMLS_D) /* {{{ */
{
uid_t id = (uid_t) -1;
switch (xc_var_namespace_mode) {
case 1:
{
zval **server;
HashTable *ht;
zval **val;
#ifdef ZEND_ENGINE_2_1
zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC);
#endif
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void**)&server) == FAILURE
|| Z_TYPE_PP(server) != IS_ARRAY
|| !(ht = Z_ARRVAL_P(*server))
|| zend_hash_find(ht, xc_var_namespace, strlen(xc_var_namespace) + 1, (void**)&val) == FAILURE) {
xc_var_namespace_init_from_stringl(NULL, 0 TSRMLS_CC);
}
else {
#ifdef IS_UNICODE
if (Z_TYPE_PP(val) == IS_UNICODE) {
xc_var_namespace_init_from_unicodel(Z_USTRVAL_PP(val), Z_USTRLEN_PP(val) TSRMLS_CC);
}
else
#endif
{
xc_var_namespace_init_from_stringl(Z_STRVAL_PP(val), Z_STRLEN_PP(val) TSRMLS_CC);
}
}
}
break;
case 2:
if (strncmp(xc_var_namespace, "uid", 3) == 0) {
id = getuid();
}
else if (strncmp(xc_var_namespace, "gid", 3) == 0) {
id = getgid();
}
if (id == (uid_t) -1){
xc_var_namespace_init_from_stringl(NULL, 0 TSRMLS_CC);
}
else {
xc_var_namespace_init_from_long((long) id TSRMLS_CC);
}
break;
case 0:
default:
xc_var_namespace_init_from_stringl(xc_var_namespace, strlen(xc_var_namespace) TSRMLS_CC);
break;
}
#ifdef IS_UNICODE
INIT_ZVAL(XG(uvar_namespace_soft));
#endif
INIT_ZVAL(XG(var_namespace_soft));
xc_var_namespace_set_stringl("", 0 TSRMLS_CC);
}
/* }}} */
static void xc_var_namespace_destroy(TSRMLS_D) /* {{{ */
{
#ifdef IS_UNICODE
zval_dtor(&XG(uvar_namespace_hard));
zval_dtor(&XG(uvar_namespace_soft));
#endif
zval_dtor(&XG(var_namespace_hard));
zval_dtor(&XG(var_namespace_soft));
}
/* }}} */
static int xc_var_buffer_prepare(zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */
{
int namespace_len;
switch (name->type) {
#ifdef IS_UNICODE
case IS_UNICODE:
do_unicode:
namespace_len = Z_USTRLEN_P(&XG(uvar_namespace_soft));
return (namespace_len ? namespace_len + 1 : 0) + Z_USTRLEN_P(name);
#endif
case IS_STRING:
do_string:
namespace_len = Z_STRLEN_P(&XG(var_namespace_soft));
return (namespace_len ? namespace_len + 1 : 0) + Z_STRLEN_P(name);
default:
#ifdef IS_UNICODE
convert_to_unicode(name);
goto do_unicode;
#else
convert_to_string(name);
goto do_string;
#endif
}
}
/* }}} */
static int xc_var_buffer_alloca_size(zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */
{
int namespace_len;
switch (name->type) {
#ifdef IS_UNICODE
case IS_UNICODE:
namespace_len = Z_USTRLEN_P(&XG(uvar_namespace_soft));
return !namespace_len ? 0 : (namespace_len + 1 + Z_USTRLEN_P(name) + 1) * sizeof(Z_USTRVAL_P(&XG(uvar_namespace_soft))[0]);
#endif
case IS_STRING:
namespace_len = Z_STRLEN_P(&XG(var_namespace_soft));
return !namespace_len ? 0 : (namespace_len + 1 + Z_STRLEN_P(name) + 1);
}
assert(0);
return 0;
}
/* }}} */
static void xc_var_buffer_init(char *buffer, zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */
{
#ifdef IS_UNICODE
if (Z_TYPE(name) == IS_UNICODE) {
memcpy(buffer, Z_USTRVAL_P(&XG(uvar_namespace_soft)), (Z_USTRLEN_P(&XG(uvar_namespace_soft)) + 1) * sizeof(Z_USTRVAL_P(name)[0]));
buffer += (Z_USTRLEN_P(&XG(uvar_namespace_soft)) + 1) * sizeof(Z_USTRVAL_P(name)[0]);
memcpy(buffer, Z_USTRVAL_P(name), (Z_USTRLEN_P(name) + 1) * sizeof(Z_USTRVAL_P(name)[0]));
}
#endif
memcpy(buffer, Z_STRVAL_P(&XG(var_namespace_soft)), (Z_STRLEN_P(&XG(var_namespace_soft)) + 1));
buffer += (Z_STRLEN_P(&XG(var_namespace_soft)) + 1);
memcpy(buffer, Z_STRVAL_P(name), (Z_STRLEN_P(name) + 1));
}
/* }}} */
typedef struct xc_namebuffer_t_ { /* {{{ */
ALLOCA_FLAG(useheap);
void *buffer;
int alloca_size;
int len;
} xc_namebuffer_t;
/* }}} */
#define VAR_BUFFER_FLAGS(name) \
xc_namebuffer_t name##_buffer;
#define VAR_BUFFER_INIT(name) \
name##_buffer.len = xc_var_buffer_prepare(name TSRMLS_CC); \
name##_buffer.alloca_size = xc_var_buffer_alloca_size(name TSRMLS_CC); \
name##_buffer.buffer = name##_buffer.alloca_size \
? do_alloca(name##_buffer.alloca_size, name##_buffer.useheap) \
: UNISW(Z_STRVAL_P(name), Z_TYPE(name) == IS_UNICODE ? Z_USTRVAL_P(name) : Z_STRVAL_P(name)); \
if (name##_buffer.alloca_size) xc_var_buffer_init(name##_buffer.buffer, name TSRMLS_CC);
#define VAR_BUFFER_FREE(name) \
if (name##_buffer.alloca_size) { \
free_alloca(name##_buffer.buffer, name##_buffer.useheap); \
}
static inline int xc_var_has_prefix(xc_entry_t *entry, zval *prefix TSRMLS_DC) /* {{{ */
{
zend_bool result = 0;
VAR_BUFFER_FLAGS(prefix);
if (UNISW(IS_STRING, entry->name_type) != prefix->type) {
return 0;
}
VAR_BUFFER_INIT(prefix);
#ifdef IS_UNICODE
if (Z_TYPE(prefix) == IS_UNICODE) {
result = entry->name.ustr.len >= prefix_buffer.len
&& memcmp(entry->name.ustr.val, prefix_buffer.buffer, prefix_buffer.len * sizeof(Z_USTRVAL_P(prefix)[0])) == 0;
goto finish;
}
#endif
result = entry->name.str.len >= prefix_buffer.len
&& memcmp(entry->name.str.val, prefix_buffer.buffer, prefix_buffer.len) == 0;
goto finish;
finish:
VAR_BUFFER_FREE(prefix);
return result;
}
/* }}} */
/* module helper function */
static int xc_init_constant(int module_number TSRMLS_DC) /* {{{ */
{
@ -2501,7 +2780,7 @@ static void xc_request_init(TSRMLS_D) /* {{{ */
xc_stack_init(&XG(var_holds[i]));
}
}
xc_var_namespace_init(TSRMLS_C);
#ifdef ZEND_ENGINE_2
zend_llist_init(&XG(gc_op_arrays), sizeof(xc_gc_op_array_t), xc_gc_op_array, 0);
#endif
@ -2519,6 +2798,7 @@ static void xc_request_shutdown(TSRMLS_D) /* {{{ */
xc_gc_expires_php(TSRMLS_C);
xc_gc_expires_var(TSRMLS_C);
xc_gc_deletes(TSRMLS_C);
xc_var_namespace_destroy(TSRMLS_C);
#ifdef ZEND_ENGINE_2
zend_llist_destroy(&XG(gc_op_arrays));
#endif
@ -2565,7 +2845,7 @@ static int xcache_admin_auth_check(TSRMLS_D) /* {{{ */
php_error_docref(NULL TSRMLS_CC, E_ERROR, "_SERVER is corrupted");
zend_bailout();
}
ht = HASH_OF((*server));
ht = Z_ARRVAL_P((*server));
if (zend_hash_find(ht, "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &user) == FAILURE) {
user = NULL;
@ -2798,32 +3078,28 @@ PHP_FUNCTION(xcache_enable_cache)
xcache_admin_operate(XC_OP_ENABLE, INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto mixed xcache_admin_namespace()
Break out of namespace limitation */
PHP_FUNCTION(xcache_admin_namespace)
{
xcache_admin_auth_check(TSRMLS_C);
xc_var_namespace_break(TSRMLS_C);
}
/* }}} */
#define VAR_CACHE_NOT_INITIALIZED() do { \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "XCache var cache was not initialized properly. Check php log for actual reason"); \
} while (0)
static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, zval *name TSRMLS_DC) /* {{{ */
static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, xc_namebuffer_t *name_buffer TSRMLS_DC) /* {{{ */
{
xc_hash_value_t hv;
switch (name->type) {
#ifdef IS_UNICODE
case IS_UNICODE:
case IS_STRING:
#endif
default:
#ifdef IS_UNICODE
convert_to_unicode(name);
#else
convert_to_string(name);
#endif
}
#ifdef IS_UNICODE
entry_var->name_type = name->type;
#endif
entry_var->entry.name = name->value;
entry_var->entry.name.str.val = name_buffer->buffer;
entry_var->entry.name.str.len = name_buffer->len;
hv = xc_entry_hash_var((xc_entry_t *) entry_var TSRMLS_CC);
@ -2833,6 +3109,31 @@ static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *ent
return SUCCESS;
}
/* }}} */
/* {{{ proto mixed xcache_set_namespace(string namespace)
Switch to user defined namespace */
PHP_FUNCTION(xcache_set_namespace)
{
zval *namespace;
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
RETURN_NULL();
}
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &namespace) == FAILURE) {
return;
}
if (Z_TYPE_P(namespace) == IS_STRING) {
xc_var_namespace_set_stringl(Z_STRVAL_P(namespace), Z_STRLEN_P(namespace) TSRMLS_CC);
}
#ifdef IS_UNICODE
else if (Z_TYPE_P(namespace) == IS_UNICODE) {
xc_var_namespace_set_unicodel(Z_USTRVAL_P(namespace), Z_USTRLEN_P(namespace) TSRMLS_CC);
}
#endif
}
/* }}} */
/* {{{ proto mixed xcache_get(string name)
Get cached data by specified name */
PHP_FUNCTION(xcache_get)
@ -2841,6 +3142,7 @@ PHP_FUNCTION(xcache_get)
xc_cache_t *cache;
xc_entry_var_t entry_var, *stored_entry_var;
zval *name;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
@ -2850,10 +3152,12 @@ PHP_FUNCTION(xcache_get)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
return;
}
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC);
VAR_BUFFER_INIT(name);
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC);
cache = &xc_var_caches[entry_hash.cacheid];
if (cache->cached->disabled) {
VAR_BUFFER_FREE(name);
RETURN_NULL();
}
@ -2868,6 +3172,7 @@ PHP_FUNCTION(xcache_get)
RETVAL_NULL();
}
} LEAVE_LOCK(cache);
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto bool xcache_set(string name, mixed value [, int ttl])
@ -2879,6 +3184,7 @@ PHP_FUNCTION(xcache_set)
xc_entry_var_t entry_var, *stored_entry_var;
zval *name;
zval *value;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
@ -2900,10 +3206,12 @@ PHP_FUNCTION(xcache_set)
entry_var.entry.ttl = xc_var_maxttl;
}
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC);
VAR_BUFFER_INIT(name);
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC);
cache = &xc_var_caches[entry_hash.cacheid];
if (cache->cached->disabled) {
VAR_BUFFER_FREE(name);
RETURN_NULL();
}
@ -2915,6 +3223,7 @@ PHP_FUNCTION(xcache_set)
entry_var.value = value;
RETVAL_BOOL(xc_entry_var_store_unlocked(cache, entry_hash.entryslotid, &entry_var TSRMLS_CC) != NULL ? 1 : 0);
} LEAVE_LOCK(cache);
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto bool xcache_isset(string name)
@ -2925,6 +3234,7 @@ PHP_FUNCTION(xcache_isset)
xc_cache_t *cache;
xc_entry_var_t entry_var, *stored_entry_var;
zval *name;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
@ -2934,10 +3244,12 @@ PHP_FUNCTION(xcache_isset)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
return;
}
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC);
VAR_BUFFER_INIT(name);
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC);
cache = &xc_var_caches[entry_hash.cacheid];
if (cache->cached->disabled) {
VAR_BUFFER_FREE(name);
RETURN_FALSE;
}
@ -2953,6 +3265,7 @@ PHP_FUNCTION(xcache_isset)
}
} LEAVE_LOCK(cache);
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto bool xcache_unset(string name)
@ -2963,6 +3276,7 @@ PHP_FUNCTION(xcache_unset)
xc_cache_t *cache;
xc_entry_var_t entry_var, *stored_entry_var;
zval *name;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
@ -2972,10 +3286,12 @@ PHP_FUNCTION(xcache_unset)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
return;
}
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC);
VAR_BUFFER_INIT(name);
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC);
cache = &xc_var_caches[entry_hash.cacheid];
if (cache->cached->disabled) {
VAR_BUFFER_FREE(name);
RETURN_FALSE;
}
@ -2989,6 +3305,7 @@ PHP_FUNCTION(xcache_unset)
RETVAL_FALSE;
}
} LEAVE_LOCK(cache);
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto bool xcache_unset_by_prefix(string prefix)
@ -3019,7 +3336,7 @@ PHP_FUNCTION(xcache_unset_by_prefix)
xc_entry_t *entry, *next;
for (entry = cache->cached->entries[entryslotid]; entry; entry = next) {
next = entry->next;
if (xc_entry_has_prefix_unlocked(XC_TYPE_VAR, entry, prefix)) {
if (xc_var_has_prefix(entry, prefix TSRMLS_CC)) {
xc_entry_remove_unlocked(XC_TYPE_VAR, cache, entryslotid, entry TSRMLS_CC);
}
}
@ -3037,6 +3354,7 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
long count = 1;
long value = 0;
zval oldzval;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
VAR_CACHE_NOT_INITIALIZED();
@ -3053,10 +3371,12 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
entry_var.entry.ttl = xc_var_maxttl;
}
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC);
VAR_BUFFER_INIT(name);
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC);
cache = &xc_var_caches[entry_hash.cacheid];
if (cache->cached->disabled) {
VAR_BUFFER_FREE(name);
RETURN_NULL();
}
@ -3102,6 +3422,7 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
}
xc_entry_var_store_unlocked(cache, entry_hash.entryslotid, &entry_var TSRMLS_CC);
} LEAVE_LOCK(cache);
VAR_BUFFER_FREE(name);
}
/* }}} */
/* {{{ proto int xcache_inc(string name [, int value [, int ttl]])
@ -3125,6 +3446,8 @@ static zend_function_entry xcache_cacher_functions[] = /* {{{ */
PHP_FE(xcache_list, NULL)
PHP_FE(xcache_clear_cache, NULL)
PHP_FE(xcache_enable_cache, NULL)
PHP_FE(xcache_admin_namespace, NULL)
PHP_FE(xcache_set_namespace, NULL)
PHP_FE(xcache_get, NULL)
PHP_FE(xcache_set, NULL)
PHP_FE(xcache_isset, NULL)
@ -3220,6 +3543,8 @@ PHP_INI_BEGIN()
PHP_INI_ENTRY1 ("xcache.var_gc_interval", "120", PHP_INI_SYSTEM, xcache_OnUpdateULong, &xc_var_gc_interval)
PHP_INI_ENTRY1 ("xcache.var_allocator", "bestfit", PHP_INI_SYSTEM, xcache_OnUpdateString, &xc_var_allocator)
STD_PHP_INI_ENTRY ("xcache.var_ttl", "0", PHP_INI_ALL, OnUpdateLong, var_ttl, zend_xcache_globals, xcache_globals)
PHP_INI_ENTRY1 ("xcache.var_namespace_mode", "0", PHP_INI_SYSTEM, xcache_OnUpdateULong, &xc_var_namespace_mode)
PHP_INI_ENTRY1 ("xcache.var_namespace", "", PHP_INI_SYSTEM, xcache_OnUpdateString, &xc_var_namespace)
PHP_INI_END()
/* }}} */
static PHP_MINFO_FUNCTION(xcache_cacher) /* {{{ */
@ -3394,6 +3719,10 @@ static PHP_MSHUTDOWN_FUNCTION(xcache_cacher) /* {{{ */
pefree(xc_var_allocator, 1);
xc_var_allocator = NULL;
}
if (xc_var_namespace) {
pefree(xc_var_namespace, 1);
xc_var_namespace = NULL;
}
return SUCCESS;
}

View File

@ -20,6 +20,12 @@ ZEND_BEGIN_MODULE_GLOBALS(xcache)
zend_uint var_holds_size;
time_t request_time;
long var_ttl;
#ifdef IS_UNCODE
zval uvar_namespace_hard;
zval uvar_namespace_soft;
#endif
zval var_namespace_hard;
zval var_namespace_soft;
zend_llist gc_op_arrays;