Skip to content
This repository was archived by the owner on Jul 7, 2018. It is now read-only.

Commit 70708e9

Browse files
committed
Add softrefcounted(), softrefcount() and softrefs() functions
1 parent c5e2b53 commit 70708e9

File tree

6 files changed

+443
-6
lines changed

6 files changed

+443
-6
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ Short list if what provided by this extension is:
3838
- `class Weak\NotifierException extend Exception`
3939
- `function Weak\refcounted()`
4040
- `function Weak\refcount()`
41+
- `function Weak\softrefcounted()`
42+
- `function Weak\softrefcount()`
43+
- `function Weak\softrefs()`
4144
- `function Weak\weakrefcounted()`
4245
- `function Weak\weakrefcount()`
4346
- `function Weak\weakrefs()`

php_weak_functions.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,77 @@ PHP_FUNCTION(refcount)
4242
RETURN_LONG(0);
4343
} /* }}} */
4444

45+
PHP_FUNCTION(softrefcounted) /* {{{ */
46+
{
47+
zval *zv;
48+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv) == FAILURE) {
49+
return;
50+
}
51+
52+
if (IS_OBJECT == Z_TYPE_P(zv)) {
53+
php_weak_referent_t *referent = php_weak_referent_find_ptr((zend_ulong)Z_OBJ_HANDLE_P(zv));
54+
55+
RETURN_BOOL(NULL != referent && zend_hash_num_elements(&referent->soft_references));
56+
}
57+
58+
RETURN_BOOL(0);
59+
} /* }}} */
60+
61+
PHP_FUNCTION(softrefcount) /* {{{ */
62+
{
63+
zval *zv;
64+
65+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv) == FAILURE) {
66+
return;
67+
}
68+
69+
if (IS_OBJECT == Z_TYPE_P(zv)) {
70+
71+
php_weak_referent_t *referent = php_weak_referent_find_ptr((zend_ulong)Z_OBJ_HANDLE_P(zv));
72+
73+
if (NULL == referent) {
74+
RETURN_LONG(0);
75+
}
76+
77+
RETURN_LONG(zend_hash_num_elements(&referent->soft_references));
78+
}
79+
80+
RETURN_LONG(0);
81+
} /* }}} */
82+
83+
PHP_FUNCTION(softrefs) /* {{{ */
84+
{
85+
zval *zv;
86+
zval softrefs;
87+
88+
php_weak_reference_t *reference;
89+
90+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv) == FAILURE) {
91+
return;
92+
}
93+
94+
ZVAL_UNDEF(&softrefs);
95+
96+
if (IS_OBJECT == Z_TYPE_P(zv)) {
97+
php_weak_referent_t *referent = php_weak_referent_find_ptr((zend_ulong)Z_OBJ_HANDLE_P(zv));
98+
99+
if (NULL != referent) {
100+
array_init_size(&softrefs, zend_hash_num_elements(&referent->soft_references));
101+
102+
ZEND_HASH_FOREACH_PTR(&referent->soft_references, reference) {
103+
add_next_index_zval(&softrefs, &reference->this_ptr);
104+
Z_ADDREF(reference->this_ptr);
105+
} ZEND_HASH_FOREACH_END();
106+
}
107+
}
108+
109+
if (IS_UNDEF == Z_TYPE(softrefs)) {
110+
array_init_size(&softrefs, 0);
111+
}
112+
113+
RETURN_ZVAL(&softrefs, 1, 1);
114+
} /* }}} */
115+
45116
PHP_FUNCTION(weakrefcounted) /* {{{ */
46117
{
47118
zval *zv;
@@ -148,6 +219,18 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(refcount_arg, ZEND_RETURN_VALUE, 1, IS_L
148219
ZEND_ARG_INFO(0, value)
149220
ZEND_END_ARG_INFO()
150221

222+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(softrefcounted_arg, ZEND_RETURN_VALUE, 1, _IS_BOOL, NULL, 0)
223+
ZEND_ARG_INFO(0, object)
224+
ZEND_END_ARG_INFO()
225+
226+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(softrefcount_arg, ZEND_RETURN_VALUE, 1, IS_LONG, NULL, 0)
227+
ZEND_ARG_INFO(0, object)
228+
ZEND_END_ARG_INFO()
229+
230+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(softrefs_arg, ZEND_RETURN_VALUE, 1, IS_ARRAY, NULL, 0)
231+
ZEND_ARG_INFO(0, object)
232+
ZEND_END_ARG_INFO()
233+
151234
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(weakrefcounted_arg, ZEND_RETURN_VALUE, 1, _IS_BOOL, NULL, 0)
152235
ZEND_ARG_INFO(0, object)
153236
ZEND_END_ARG_INFO()
@@ -172,6 +255,10 @@ const zend_function_entry php_weak_functions[] = { /* {{{ */
172255
ZEND_NS_FE(PHP_WEAK_NS, refcounted, refcounted_arg)
173256
ZEND_NS_FE(PHP_WEAK_NS, refcount, refcount_arg)
174257

258+
ZEND_NS_FE(PHP_WEAK_NS, softrefcounted, softrefcounted_arg)
259+
ZEND_NS_FE(PHP_WEAK_NS, softrefcount, softrefcount_arg)
260+
ZEND_NS_FE(PHP_WEAK_NS, softrefs, softrefs_arg)
261+
175262
ZEND_NS_FE(PHP_WEAK_NS, weakrefcounted, weakrefcounted_arg)
176263
ZEND_NS_FE(PHP_WEAK_NS, weakrefcount, weakrefcount_arg)
177264
ZEND_NS_FE(PHP_WEAK_NS, weakrefs, weakrefs_arg)

stubs/weak/functions.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,33 @@ function refcounted(mixed $value) : bool {}
3232
*/
3333
function refcount(mixed $value) : int {}
3434

35+
/**
36+
* Check whether object has soft references
37+
*
38+
* @param object $value
39+
*
40+
* @return bool
41+
*/
42+
function softrefcounted(object $value) : bool {}
43+
44+
/**
45+
* Get object's soft references count
46+
47+
* @param object $value
48+
*
49+
* @return int
50+
*/
51+
function softrefcount(object $value) : int {}
52+
53+
/**
54+
* Get object's soft references
55+
*
56+
* @param object $value
57+
*
58+
* @return mixed
59+
*/
60+
function softrefs(object $value) : array {}
61+
3562
/**
3663
* Check whether object has weak references
3764
*
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
--TEST--
2+
Weak\functions - test soft* and weak* functions together
3+
--SKIPIF--
4+
<?php if (!extension_loaded("weak")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
use function Weak\{
9+
refcounted,
10+
refcount,
11+
softrefcounted,
12+
softrefcount,
13+
softrefs,
14+
weakrefcounted,
15+
weakrefcount,
16+
weakrefs,
17+
object_handle,
18+
is_obj_destructor_called
19+
};
20+
21+
use Weak\Reference;
22+
use Weak\SoftReference;
23+
24+
/** @var \Testsuite $helper */
25+
$helper = require '.testsuite.php';
26+
27+
28+
$obj1 = new stdClass();
29+
$obj2 = new stdClass();
30+
$obj3 = new stdClass();
31+
32+
$test = $obj1;
33+
34+
$soft_ref1a = new SoftReference($obj1);
35+
$soft_ref1b = new SoftReference($obj1);
36+
$soft_ref2 = new SoftReference($obj2);
37+
38+
39+
$helper->header('Test Weak\softrefcounted');
40+
$helper->export_annotated('softrefcounted($obj1)', softrefcounted($obj1));
41+
$helper->export_annotated('softrefcounted($obj2)', softrefcounted($obj2));
42+
$helper->export_annotated('softrefcounted($obj3)', softrefcounted($obj3));
43+
$helper->line();
44+
45+
46+
$helper->header('Test Weak\softrefcount');
47+
$helper->export_annotated('softrefcount($obj1)', softrefcount($obj1));
48+
$helper->export_annotated('softrefcount($obj2)', softrefcount($obj2));
49+
$helper->export_annotated('softrefcount($obj3)', softrefcount($obj3));
50+
$helper->line();
51+
52+
53+
$helper->header('Test Weak\softrefs');
54+
55+
$helper->assert('Multiple soft refs reported for object with softrefs()', softrefs($obj1), [$soft_ref1a, $soft_ref1b]);
56+
$helper->dump(softrefs($obj1));
57+
$helper->line();
58+
59+
$helper->assert('Single soft ref reported for object with softrefs()', softrefs($obj2), [$soft_ref2]);
60+
$helper->dump(softrefs($obj2));
61+
$helper->line();
62+
63+
$helper->assert('No soft refs reported for object with softrefs()', softrefs($obj3), []);
64+
$helper->dump(softrefs($obj3));
65+
$helper->line();
66+
67+
68+
69+
$weak_ref1a = new Reference($obj1);
70+
$weak_ref1b = new Reference($obj1);
71+
$weak_ref2 = new Reference($obj2);
72+
73+
74+
$helper->header('Test Weak\weakrefcounted');
75+
$helper->export_annotated('weakrefcounted($obj1)', weakrefcounted($obj1));
76+
$helper->export_annotated('weakrefcounted($obj2)', weakrefcounted($obj2));
77+
$helper->export_annotated('weakrefcounted($obj3)', weakrefcounted($obj3));
78+
$helper->line();
79+
80+
81+
$helper->header('Test Weak\weakrefcount');
82+
$helper->export_annotated('weakrefcount($obj1)', weakrefcount($obj1));
83+
$helper->export_annotated('weakrefcount($obj2)', weakrefcount($obj2));
84+
$helper->export_annotated('weakrefcount($obj3)', weakrefcount($obj3));
85+
$helper->line();
86+
87+
88+
$helper->header('Test Weak\weakrefs');
89+
90+
$helper->assert('Multiple weak refs reported for object with weakrefs()', weakrefs($obj1), [$weak_ref1a, $weak_ref1b]);
91+
$helper->dump(weakrefs($obj1));
92+
$helper->line();
93+
94+
$helper->assert('Single weak ref reported for object with weakrefs()', weakrefs($obj2), [$weak_ref2]);
95+
$helper->dump(weakrefs($obj2));
96+
$helper->line();
97+
98+
$helper->assert('No weak refs reported for object with weakrefs()', weakrefs($obj3), []);
99+
$helper->dump(weakrefs($obj3));
100+
$helper->line();
101+
102+
?>
103+
--EXPECT--
104+
Test Weak\softrefcounted:
105+
-------------------------
106+
softrefcounted($obj1): boolean: true
107+
softrefcounted($obj2): boolean: true
108+
softrefcounted($obj3): boolean: false
109+
110+
Test Weak\softrefcount:
111+
-----------------------
112+
softrefcount($obj1): integer: 2
113+
softrefcount($obj2): integer: 1
114+
softrefcount($obj3): integer: 0
115+
116+
Test Weak\softrefs:
117+
-------------------
118+
Multiple soft refs reported for object with softrefs(): ok
119+
array(2) refcount(2){
120+
[0]=>
121+
object(Weak\SoftReference)#5 (2) refcount(2){
122+
["referent":"Weak\AbstractReference":private]=>
123+
object(stdClass)#2 (0) refcount(3){
124+
}
125+
["notifier":"Weak\AbstractReference":private]=>
126+
NULL
127+
}
128+
[1]=>
129+
object(Weak\SoftReference)#6 (2) refcount(2){
130+
["referent":"Weak\AbstractReference":private]=>
131+
object(stdClass)#2 (0) refcount(3){
132+
}
133+
["notifier":"Weak\AbstractReference":private]=>
134+
NULL
135+
}
136+
}
137+
138+
Single soft ref reported for object with softrefs(): ok
139+
array(1) refcount(2){
140+
[0]=>
141+
object(Weak\SoftReference)#7 (2) refcount(2){
142+
["referent":"Weak\AbstractReference":private]=>
143+
object(stdClass)#3 (0) refcount(2){
144+
}
145+
["notifier":"Weak\AbstractReference":private]=>
146+
NULL
147+
}
148+
}
149+
150+
No soft refs reported for object with softrefs(): ok
151+
array(0) refcount(2){
152+
}
153+
154+
Test Weak\weakrefcounted:
155+
-------------------------
156+
weakrefcounted($obj1): boolean: true
157+
weakrefcounted($obj2): boolean: true
158+
weakrefcounted($obj3): boolean: false
159+
160+
Test Weak\weakrefcount:
161+
-----------------------
162+
weakrefcount($obj1): integer: 2
163+
weakrefcount($obj2): integer: 1
164+
weakrefcount($obj3): integer: 0
165+
166+
Test Weak\weakrefs:
167+
-------------------
168+
Multiple weak refs reported for object with weakrefs(): ok
169+
array(2) refcount(2){
170+
[0]=>
171+
object(Weak\Reference)#8 (2) refcount(2){
172+
["referent":"Weak\AbstractReference":private]=>
173+
object(stdClass)#2 (0) refcount(3){
174+
}
175+
["notifier":"Weak\AbstractReference":private]=>
176+
NULL
177+
}
178+
[1]=>
179+
object(Weak\Reference)#9 (2) refcount(2){
180+
["referent":"Weak\AbstractReference":private]=>
181+
object(stdClass)#2 (0) refcount(3){
182+
}
183+
["notifier":"Weak\AbstractReference":private]=>
184+
NULL
185+
}
186+
}
187+
188+
Single weak ref reported for object with weakrefs(): ok
189+
array(1) refcount(2){
190+
[0]=>
191+
object(Weak\Reference)#10 (2) refcount(2){
192+
["referent":"Weak\AbstractReference":private]=>
193+
object(stdClass)#3 (0) refcount(2){
194+
}
195+
["notifier":"Weak\AbstractReference":private]=>
196+
NULL
197+
}
198+
}
199+
200+
No weak refs reported for object with weakrefs(): ok
201+
array(0) refcount(2){
202+
}

0 commit comments

Comments
 (0)