summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXuefer <xuefer@gmail.com>2014-11-12 07:03:46 +0000
committerXuefer <xuefer@gmail.com>2014-11-12 07:03:46 +0000
commit15ad8700a85f66cd53cb24d6f1f0aaf8cb9c1c79 (patch)
treeaba45e9c2ac2d491b6e1f7a2b1e5c6809ec03e41
parentef3a8f0221f51896ad8faf9000888d9e56cfe1b4 (diff)
downloadxcache-15ad8700a85f66cd53cb24d6f1f0aaf8cb9c1c79.tar.gz
xcache-15ad8700a85f66cd53cb24d6f1f0aaf8cb9c1c79.zip
support for reference value
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1572 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
-rw-r--r--ChangeLog8
-rw-r--r--mod_cacher/xc_cacher.c48
-rw-r--r--processor/foot.m423
-rw-r--r--processor/processor.m424
-rw-r--r--tests/xcache_var_reference.phpt41
-rw-r--r--xcache/xc_compatibility.h3
6 files changed, 126 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index e77947a..60b3515 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
4.0.0 2014-??-??
API Changes
========
- * new: proto array xcache_get_refcount(mixed &$variable), with +1 side effect removed
- * chg: proto array xcache_get_cowcount(mixed $value)
+ * new: proto int xcache_get_refcount(mixed &$variable), with +1 side effect removed
+ * chg: proto int xcache_get_cowcount(mixed $value)
+ * new: proto mixed &xcache_get_ref(string name): Get cached data by specified name return referenced value. Not supported in PHP_4
+ * new: proto mixed &xcache_get_ref(string name): Get cached data by specified name return referenced value. Not supported in PHP_4
+ * new: proto bool xcache_set(string name, mixed &value [, int ttl]): Store data to cache by specified name maintaining value referenced
ChangeLog
========
@@ -11,6 +14,7 @@ ChangeLog
* (WIP) cache to disk
* fixed #348: added class const support for __FILE__ __DIR__
* closes #342: added support for object caching. handle IS_RESTORCE as interger
+ * able to return reference value by xcache_set_ref/xcache_get_ref
* disassembler, decompiler:
* PHP_5_6 support
* misc:
diff --git a/mod_cacher/xc_cacher.c b/mod_cacher/xc_cacher.c
index c29c01f..52c2a7f 100644
--- a/mod_cacher/xc_cacher.c
+++ b/mod_cacher/xc_cacher.c
@@ -3400,7 +3400,7 @@ PHP_FUNCTION(xcache_get)
}
}
- xc_processor_restore_var(return_value, stored_entry_var, xc_vector_data(zend_class_entry *, &index_to_ce) TSRMLS_CC);
+ xc_processor_restore_var(return_value, ZESW(NULL, return_value_ptr), stored_entry_var, xc_vector_data(zend_class_entry *, &index_to_ce) TSRMLS_CC);
xc_cached_hit_unlocked(cache->cached TSRMLS_CC);
} LEAVE_LOCK(cache);
} while (reload_class);
@@ -3473,6 +3473,38 @@ PHP_FUNCTION(xcache_set)
VAR_BUFFER_FREE(name);
}
/* }}} */
+/* {{{ proto mixed &xcache_get_ref(string name)
+ Get cached data by specified name return referenced value. Not supported in PHP_4 */
+#ifdef ZEND_BEGIN_ARG_INFO_EX
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_get_ref, 0, 1, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+#else
+static unsigned char arginfo_xcache_get_ref[] = { 1, BYREF_NONE };
+#endif
+
+PHP_FUNCTION(xcache_get_ref)
+{
+ zif_xcache_get(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto bool xcache_set(string name, mixed &value [, int ttl])
+ Store data to cache by specified name maintaining value referenced */
+#ifdef ZEND_BEGIN_ARG_INFO_EX
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_set_ref, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(1, value)
+ ZEND_ARG_INFO(0, ttl)
+ZEND_END_ARG_INFO()
+#else
+static unsigned char arginfo_xcache_set_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_NONE };
+#endif
+
+PHP_FUNCTION(xcache_set_ref)
+{
+ zif_xcache_set(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
/* {{{ proto bool xcache_isset(string name)
Check if an entry exists in cache by specified name */
#ifdef ZEND_BEGIN_ARG_INFO_EX
@@ -3627,7 +3659,6 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
zval *name;
long count = 1;
long value = 0;
- zval oldzval;
VAR_BUFFER_FLAGS(name);
if (!xc_var_caches) {
@@ -3680,10 +3711,11 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{
value = 0;
}
else {
- xc_processor_restore_var(&oldzval, stored_entry_var, NULL TSRMLS_CC);
- convert_to_long(&oldzval);
- value = Z_LVAL(oldzval);
- zval_dtor(&oldzval);
+ zval zv;
+ xc_processor_restore_var(&zv, NULL, stored_entry_var, NULL TSRMLS_CC);
+ convert_to_long(&zv);
+ value = Z_LVAL(zv);
+ zval_dtor(&zv);
}
}
else {
@@ -3750,6 +3782,10 @@ static zend_function_entry xcache_cacher_functions[] = /* {{{ */
PHP_FE(xcache_set_namespace, arginfo_xcache_set_namespace)
PHP_FE(xcache_get, arginfo_xcache_get)
PHP_FE(xcache_set, arginfo_xcache_set)
+ PHP_FE(xcache_get_ref, arginfo_xcache_get_ref)
+ PHP_FE(xcache_set_ref, arginfo_xcache_set_ref)
+#ifdef ZEND_BEGIN_ARG_INFO_EX
+#endif
PHP_FE(xcache_isset, arginfo_xcache_isset)
PHP_FE(xcache_unset, arginfo_xcache_unset)
PHP_FE(xcache_unset_by_prefix, arginfo_xcache_unset_by_prefix)
diff --git a/processor/foot.m4 b/processor/foot.m4
index 65d066f..0bfe239 100644
--- a/processor/foot.m4
+++ b/processor/foot.m4
@@ -86,17 +86,15 @@ dnl }}}
DEFINE_STORE_API(`xc_entry_php_t')
DEFINE_STORE_API(`xc_entry_data_php_t')
DEFINE_STORE_API(`xc_entry_var_t')
-EXPORTED_FUNCTION(`xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
+EXPORTED_FUNCTION(`void xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
memset(&processor, 0, sizeof(processor));
xc_restore_xc_entry_php_t(&processor, dst, src TSRMLS_CC);
-
- return dst;
}
dnl }}}
-EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC)') dnl {{{
+EXPORTED_FUNCTION(`void xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
@@ -115,10 +113,9 @@ EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);
}
- return dst;
}
dnl }}}
-EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_t *src, zend_class_entry **index_to_ce TSRMLS_DC)') dnl {{{
+EXPORTED_FUNCTION(`void xc_processor_restore_var(zval *dst, zval **dst_ptr, const xc_entry_var_t *src, zend_class_entry **index_to_ce TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
@@ -127,8 +124,9 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
if (processor.handle_reference) {
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
- dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
- zend_hash_add(&processor.zvalptrs, (char *)src->value, sizeof(src->value), (void *) &dst, sizeof(dst), NULL);
+ if (dst_ptr) {
+ zval_ptr_dtor(dst_ptr);
+ }
}
processor.index_to_ce = index_to_ce;
@@ -146,7 +144,12 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
}
}
#endif
- xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
+ if (dst_ptr) {
+ xc_restore_zval_ptr(&processor, dst_ptr, &src->value TSRMLS_CC);
+ }
+ else {
+ xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
+ }
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);
}
@@ -160,8 +163,6 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
efree(processor.object_handles);
}
#endif
-
- return dst;
}
dnl }}}
define(`DEFINE_RELOCATE_API', `
diff --git a/processor/processor.m4 b/processor/processor.m4
index d2e0ca5..b202bda 100644
--- a/processor/processor.m4
+++ b/processor/processor.m4
@@ -283,8 +283,9 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
if (zend_hash_find(&processor->zvalptrs, (char *) &SRC()[0], sizeof(SRC()[0]), (void **) &ppzv) == SUCCESS) {
IFCOPY(`
DST()[0] = *ppzv;
+ IFSTORE(`Z_ADDREF(**DST());')
/* *DST() is updated */
- dnl fprintf(stderr, "*DST() is set to %p, PROCESSOR_TYPE is_shm %d\n", DST()[0], xc_is_shm(DST()[0]));
+ dnl fprintf(stderr, "*DST() is set to %p, PROCESSOR_TYPE is_shm %d\n", (void *) DST()[0], xc_is_shm(DST()[0]));
')
IFCALCSTORE(`processor->have_references = 1;')
IFSTORE(`assert(xc_is_shm(DST()[0]));')
@@ -305,7 +306,8 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
RELOCATE_EX(zval, pzv)
')
if (zend_hash_add(&processor->zvalptrs, (char *) &SRC()[0], sizeof(SRC()[0]), (void *) &pzv, sizeof(pzv), NULL) == SUCCESS) { /* first add, go on */
- dnl fprintf(stderr, "mark[%p] = %p\n", SRC()[0], pzv);
+ IFSTORE(`Z_SET_REFCOUNT(**DST(), 1);')
+ dnl IFSTORE(`fprintf(stderr, "mark[%p] = %p\n", (void *) SRC()[0], (void *) pzv);')
}
else {
assert(0);
@@ -1416,6 +1418,24 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
STRUCT_P_EX(zval_ptr, DST(`value'), SRC(`value'), `value', `', `&')
+#if 0
+ IFSTORE(`
+ {
+ HashTable *ht;
+ zval **zv;
+
+ assert(Z_TYPE_P(SRC(`value')) == IS_ARRAY);
+ ht = Z_ARRVAL_P(SRC(`value'));
+ assert(ht->nNumOfElements == 1);
+ fprintf(stderr, "key %s\n", ht->pListHead->arKey);
+
+ zv = (zval **) ht->pListHead->pData;
+ fprintf(stderr, "%d\n", Z_TYPE_PP(zv));
+ assert(Z_TYPE_PP(zv) == IS_ARRAY);
+ assert(Z_ARRVAL_PP(zv) == ht);
+ }
+ ')
+#endif
#ifdef ZEND_ENGINE_2
IFCALC(`
diff --git a/tests/xcache_var_reference.phpt b/tests/xcache_var_reference.phpt
new file mode 100644
index 0000000..f632aa2
--- /dev/null
+++ b/tests/xcache_var_reference.phpt
@@ -0,0 +1,41 @@
+--TEST--
+xcache_set/get test for reference
+--SKIPIF--
+<?php
+require("skipif.inc");
+?>
+--INI--
+xcache.test = 1
+xcache.size = 32M
+xcache.var_size = 2M
+--FILE--
+<?php
+$ref = array();
+$ref['ref'] = &$ref;
+$ref['array'] = array(&$ref);
+var_dump(xcache_set_ref("ref", $ref));
+
+unset($ref);
+$ref = &xcache_get_ref("ref");
+var_dump(array(&$ref));
+
+$ref['test'] = 1;
+var_dump($ref['ref']['test']);
+var_dump($ref['array'][0]['test']);
+?>
+--EXPECT--
+bool(true)
+array(1) {
+ [0]=>
+ &array(2) {
+ ["ref"]=>
+ *RECURSION*
+ ["array"]=>
+ array(1) {
+ [0]=>
+ *RECURSION*
+ }
+ }
+}
+int(1)
+int(1)
diff --git a/xcache/xc_compatibility.h b/xcache/xc_compatibility.h
index b2be78c..2168b54 100644
--- a/xcache/xc_compatibility.h
+++ b/xcache/xc_compatibility.h
@@ -68,6 +68,9 @@
#ifndef Z_SET_REFCOUNT
# define Z_SET_REFCOUNT(z, rc) (z).refcount = rc
#endif
+#ifndef Z_ADDREF
+# define Z_ADDREF(z) (z).refcount++
+#endif
#ifndef IS_CONSTANT_TYPE_MASK
# define IS_CONSTANT_TYPE_MASK (~IS_CONSTANT_INDEX)
#endif