Re: weak references
| From: | Lars Strojny | Date: | Mon, 18 Jul 2011 14:42:14 +0000 |
| Subject: | Re: weak references | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-54040@lists.php.net to get a copy of this message | ||
While I like SplWeekRef and the somewhat proposed SplWeekRefList, you’ll
find attached a patch that exposes a simple function „refcount“ having
this signature:
int refcount(mixed value)
So if you would like to play around with it, have fun. It would be
interesting to see if there are any other use cases besides destroying a
reference.
An idea for a userland implementation of SplWeekRefList with auto cleanup:
let SplWeekRefList register a ticket function which executes cleanup with
a certain propability. Something along the lines of this:
<?php
declare(ticks=1);
class WeekRefList extends SplObjectStorage
{
public function __construct()
{
register_tick_function(array($this, 'cleanup'));
}
public function cleanup()
{
if (rand(1, 10) === 1) {
foreach ($this as $entry) {
// First ref is in ObjectStorage, second is $entry var
if (refcount($entry) === 2) {
unset($this[$entry]);
}
}
}
}
}
With regards,
Lars
Am 18.07.11 10:28 schrieb "Lars Schultz" unter <lars.schultz@toolpark.com>:
>Am 18.07.2011 10:15, schrieb Ferenc Kovacs:
>> I think that having to know and care about refcounts and zvals are
>> more complicated than having an Spl class, which can hold a reference
>> for a variable what can be destroyed to free memory.
>> and there is a chance that people are familiar with the Weak
>> references from other languages, while the zval approach only familiar
>> for those that knows about php internals.
>> so I think that from the userland POV, weak references are easier to
>>grasp.
>
>You're right for users who indeed have this problem. But I am worried
>about those users, which do not have the problem, but still have to know
>what WeakReferences are...but I should wait for the RFC.
>
>
>--
>PHP Internals - PHP Runtime Development Mailing List
>To unsubscribe, visit: http://www.php.net/unsub.php
>
Index: Zend/zend_builtin_functions.c =================================================================== --- Zend/zend_builtin_functions.c (revision 313122) +++ Zend/zend_builtin_functions.c (working copy) @@ -94,6 +94,7 @@ static ZEND_FUNCTION(gc_enabled); static ZEND_FUNCTION(gc_enable); static ZEND_FUNCTION(gc_disable); +static ZEND_FUNCTION(refcount); /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0) @@ -237,6 +238,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1) ZEND_ARG_INFO(0, extension_name) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_refcount, 0, 0, 0) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() /* }}} */ static const zend_function_entry builtin_functions[] = { /* {{{ */ @@ -306,6 +311,7 @@ ZEND_FE(gc_enabled, arginfo_zend__void) ZEND_FE(gc_enable, arginfo_zend__void) ZEND_FE(gc_disable, arginfo_zend__void) + ZEND_FE(refcount, arginfo_refcount) { NULL, NULL, NULL } }; /* }}} */ @@ -385,6 +391,19 @@ } /* }}} */ +/* {{{ proto int refcount(mixed value) + Returns the refcount for the passed object */ +ZEND_FUNCTION(refcount) +{ + zval *value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) { + return; + } + + RETURN_LONG(Z_REFCOUNT_P(value) - 1); +} + /* {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args)
Index: Zend/zend_builtin_functions.c =================================================================== --- Zend/zend_builtin_functions.c (revision 313122) +++ Zend/zend_builtin_functions.c (working copy) @@ -94,6 +94,7 @@ static ZEND_FUNCTION(gc_enabled); static ZEND_FUNCTION(gc_enable); static ZEND_FUNCTION(gc_disable); +static ZEND_FUNCTION(refcount); /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0) @@ -237,6 +238,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1) ZEND_ARG_INFO(0, extension_name) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_refcount, 0, 0, 0) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() /* }}} */ static const zend_function_entry builtin_functions[] = { /* {{{ */ @@ -306,6 +311,7 @@ ZEND_FE(gc_enabled, arginfo_zend__void) ZEND_FE(gc_enable, arginfo_zend__void) ZEND_FE(gc_disable, arginfo_zend__void) + ZEND_FE(refcount, arginfo_refcount) { NULL, NULL, NULL } }; /* }}} */ @@ -385,6 +391,19 @@ } /* }}} */ +/* {{{ proto int refcount(mixed value) + Returns the refcount for the passed object */ +ZEND_FUNCTION(refcount) +{ + zval *value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) { + return; + } + + RETURN_LONG(Z_REFCOUNT_P(value) - 1); +} + /* {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args)