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

Commit 5873a07

Browse files
authored
Merge pull request #25 from pinepain/cleanup-and-fixes
Cleanup and fixes
2 parents f87c8f6 + e5dcf7a commit 5873a07

36 files changed

+323
-1043
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ config.nice
1515
config.status
1616
config.sub
1717
configure
18+
configure.ac
1819
configure.in
1920
include
2021
install-sh

.travis.yml

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ dist: trusty
44
language: php
55

66
php:
7-
- 7.0
87
- 7.1
98
- nightly
109

README.md

+6-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This extension adds [Soft Reference](https://en.wikipedia.org/wiki/Soft_referenc
99
data structures that require advanced referencing model.
1010

1111

12-
**PHP >= 7.0.3 required**
12+
**PHP >= 7.1 required**
1313

1414
## Usage
1515

@@ -69,9 +69,9 @@ destroyed, while `WeakReference` call it notifier after referent object was dest
6969

7070
Note: What this extension provides aren't quite actual soft and weak references, but it comes close for most use cases.
7171

72-
### Notifiers
72+
### Notifier
7373

74-
Notifier can be one of `callable`, `array` or `null` types. `null` notifier denotes no notifier set.
74+
Notifier can be `callable` or `null`. `null` notifier denotes no notifier set.
7575

7676
Note that notification happens *after* referent object destruction, so at the time of notification `Ref\Referent::get()`
7777
will return `null` (unless rare case when object refcount get incremented in destructor, e.g. by storing destructing value
@@ -196,7 +196,7 @@ You may also want to add php-ref extension as a [composer.json dependency](https
196196

197197
"require": {
198198
...
199-
"ext-ref": "~0.1.0"
199+
"ext-ref": "*"
200200
...
201201
}
202202

@@ -210,9 +210,7 @@ with a custom one, which meta-code is:
210210
$exceptions = [];
211211

212212
foreach($soft_references as $soft_ref_object_handle => $soft_reference) {
213-
if (is_array($weak_reference->notifier)) {
214-
$soft_reference->notifier[] = $weak_reference;
215-
} elseif (is_callable($soft_reference->notifier)) {
213+
if (is_callable($soft_reference->notifier)) {
216214
try {
217215
$soft_reference->notifier($weak_reference);
218216
} catch(Throwable $e) {
@@ -233,9 +231,7 @@ if (refcount($object) == 1) {
233231
}
234232

235233
foreach($weak_references as $weak_ref_object_handle => $weak_reference) {
236-
if (is_array($weak_reference->notifier)) {
237-
$weak_reference->notifier[] = $weak_reference;
238-
} elseif (is_callable($weak_reference->notifier)) {
234+
if (is_callable($weak_reference->notifier)) {
239235
try {
240236
$weak_reference->notifier($weak_reference);
241237
} catch(Throwable $e) {

appveyor.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@ platform:
44

55
environment:
66
matrix:
7-
- PHP_VERSION: 7.0.20
7+
- PHP_VERSION: 7.1.8
88
THREAD_SAFE: true
9-
- PHP_VERSION: 7.0.20
10-
THREAD_SAFE: false
11-
- PHP_VERSION: 7.1.6
12-
THREAD_SAFE: true
13-
- PHP_VERSION: 7.1.6
9+
- PHP_VERSION: 7.1.8
1410
THREAD_SAFE: false
1511

1612

config.m4

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ if test "$PHP_REF" != "no"; then
1111
PHP_REF_FOUND_VERSION=`${PHP_CONFIG} --version`
1212
PHP_REF_FOUND_VERNUM=`${PHP_CONFIG} --vernum`
1313

14-
if test "$PHP_REF_FOUND_VERNUM" -lt "70003"; then
15-
AC_MSG_ERROR([not supported. Need a PHP version >= 7.0.3 (found $PHP_REF_FOUND_VERSION)])
14+
if test "$PHP_REF_FOUND_VERNUM" -lt "70100"; then
15+
AC_MSG_ERROR([not supported. PHP version >= 7.1 required (found $PHP_REF_FOUND_VERSION)])
1616
else
1717
AC_MSG_RESULT([supported ($PHP_REF_FOUND_VERSION)])
1818
fi

config.w32

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// $Id$
2-
// vim:ft=javascript
3-
41
ARG_ENABLE("ref", "enable ref support", "no");
52

63
if (PHP_REF != "no") {

package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
<dependencies>
157157
<required>
158158
<php>
159-
<min>7.0.3</min>
159+
<min>7.1.0</min>
160160
</php>
161161
<pearinstaller>
162162
<min>1.4.0</min>

php_ref.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ extern zend_module_entry php_ref_module_entry;
2626
#define PHP_REF_REVISION "dev"
2727
#endif
2828

29-
#if PHP_VERSION_ID < 70003
29+
#if PHP_VERSION_ID < 70100
3030
// should never get her, but just in case
31-
#error PHP >= 7.0.3 required
31+
#error PHP >= 7.1 required
3232
#endif
3333

3434
#define PHP_REF_NS "Ref"

php_ref_notifier_exception.c

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ static PHP_METHOD(NotifierException, __construct)
6262
} else {
6363
array_init_size(&tmp, 0);
6464
zend_update_property(this_ce, getThis(), ZEND_STRL("exceptions"), &tmp);
65+
zval_dtor(&tmp);
6566
}
6667

6768
if (code) {

php_ref_reference.c

+24-108
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ zend_object_handlers php_ref_reference_object_handlers;
2727
php_ref_reference_t *php_ref_reference_init(zval *this_ptr, zval *referent_zv, zval *notifier_zv);
2828

2929
static inline void php_ref_store_exceptions(zval *exceptions, zval *tmp);
30-
static int php_ref_reference_check_notifier(zval *notifier, zval *this);
3130

3231
//#define PHP_REF_DEBUG 1
3332

@@ -122,22 +121,18 @@ static void php_ref_call_notifiers(HashTable *references, zval *exceptions, zval
122121
reference->referent = NULL;
123122
}
124123

125-
switch (reference->notifier_type) {
126-
case PHP_REF_NOTIFIER_ARRAY:
127-
/* array notifier */
128-
add_next_index_zval(&reference->notifier, &reference->this_ptr);
129-
Z_ADDREF(reference->this_ptr);
130-
break;
131-
case PHP_REF_NOTIFIER_CALLBACK:
132-
/* callback notifier */
133-
php_ref_reference_call_notifier(&reference->this_ptr, &reference->notifier);
134-
135-
if (EG(exception)) {
136-
php_ref_store_exceptions(exceptions, tmp);
137-
}
138-
break;
139-
default:
140-
break;
124+
if (IS_NULL == Z_TYPE(reference->notifier)) {
125+
/* notifier is not set */
126+
break;
127+
}
128+
129+
/* WeakRef could be destroyed during notifier call, so we need to increment decrement refcount to survive */
130+
Z_ADDREF(reference->this_ptr);
131+
php_ref_reference_call_notifier(&reference->this_ptr, &reference->notifier);
132+
Z_DELREF(reference->this_ptr);
133+
134+
if (EG(exception)) {
135+
php_ref_store_exceptions(exceptions, tmp);
141136
}
142137

143138
if (!after_dtor && reference->referent && Z_REFCOUNT(reference->referent->this_ptr) > 1) {
@@ -157,8 +152,10 @@ static void php_ref_maybe_restore_handlers(php_ref_referent_t *referent)
157152
return;
158153
}
159154

160-
Z_OBJ(referent->this_ptr)->handlers = referent->original_handlers;
161-
referent->original_handlers = NULL;
155+
if (referent->original_handlers) {
156+
Z_OBJ(referent->this_ptr)->handlers = referent->original_handlers;
157+
referent->original_handlers = NULL;
158+
}
162159
}
163160

164161
void php_ref_referent_object_dtor_obj(zend_object *object)
@@ -211,6 +208,7 @@ void php_ref_referent_object_dtor_obj(zend_object *object)
211208
php_ref_create_notifier_exception(&exception, "One or more exceptions thrown during notifiers calling", &exceptions);
212209

213210
zend_throw_exception_object(&exception);
211+
zval_dtor(&exceptions);
214212
}
215213
}
216214

@@ -238,6 +236,10 @@ void php_ref_referent_abstract_references_ht_dtor(zval *zv)
238236
if (reference->referent) {
239237
reference->referent->tracked--;
240238
php_ref_maybe_restore_handlers(reference->referent);
239+
240+
if (!reference->referent->tracked) {
241+
zend_hash_index_del(PHP_REF_G(referents), reference->referent->handle);
242+
}
241243
}
242244

243245
/* clean links to ht & release callbacks as we don't need them already*/
@@ -335,12 +337,6 @@ php_ref_reference_t *php_ref_reference_init(zval *this_ptr, zval *referent_zv, z
335337

336338
PHP_REF_REFERENCE_FETCH_INTO(this_ptr, reference);
337339

338-
int notifier_type = php_ref_reference_check_notifier(notifier_zv, this_ptr);
339-
340-
if (PHP_REF_NOTIFIER_INVALID == notifier_type) {
341-
return reference;
342-
}
343-
344340
ZVAL_COPY_VALUE(&reference->this_ptr, this_ptr);
345341

346342
referent = php_ref_referent_get_or_create(referent_zv);
@@ -353,8 +349,6 @@ php_ref_reference_t *php_ref_reference_init(zval *this_ptr, zval *referent_zv, z
353349
ZVAL_NULL(&reference->notifier);
354350
}
355351

356-
reference->notifier_type = notifier_type;
357-
358352
return reference;
359353
}
360354

@@ -371,36 +365,6 @@ static inline void php_ref_store_exceptions(zval *exceptions, zval *tmp)
371365
zend_clear_exception();
372366
}
373367

374-
static int php_ref_reference_check_notifier(zval *notifier, zval *this)
375-
{
376-
if (NULL == notifier) {
377-
/* no value provided at all, nothing to check */
378-
return PHP_REF_NOTIFIER_NULL;
379-
}
380-
381-
if (IS_NULL == Z_TYPE_P(notifier)) {
382-
/* no notifier */
383-
return PHP_REF_NOTIFIER_NULL;
384-
}
385-
386-
/* maybe callback notifier */
387-
if (!zend_is_callable(notifier, 0, NULL)) {
388-
389-
if (IS_ARRAY == Z_TYPE_P(notifier)) {
390-
/* array notifier */
391-
return PHP_REF_NOTIFIER_ARRAY;
392-
}
393-
394-
zend_throw_error(zend_ce_type_error,
395-
"Argument 2 passed to %s::%s() must be callable, array or null, %s given",
396-
ZSTR_VAL(Z_OBJCE_P(this)->name), get_active_function_name(), zend_zval_type_name(notifier));
397-
398-
return PHP_REF_NOTIFIER_INVALID;
399-
}
400-
401-
return PHP_REF_NOTIFIER_CALLBACK;
402-
}
403-
404368
static HashTable *php_ref_reference_gc(zval *object, zval **table, int *n)
405369
{
406370
PHP_REF_REFERENCE_FETCH_INTO(object, reference);
@@ -508,7 +472,6 @@ static zend_object *php_ref_reference_clone_obj(zval *object)
508472

509473
ZVAL_OBJ(&new_reference->this_ptr, new_object);
510474
ZVAL_COPY(&new_reference->notifier, &old_reference->notifier);
511-
new_reference->notifier_type = old_reference->notifier_type;
512475

513476
if (old_reference->referent) {
514477
old_reference->register_reference(new_reference, old_reference->referent);
@@ -558,42 +521,6 @@ static HashTable *php_ref_get_debug_info(zval *object, int *is_temp)
558521
return debug_info;
559522
}
560523

561-
static int php_ref_compare_objects(zval *object1, zval *object2)
562-
{
563-
zval result;
564-
int res;
565-
566-
PHP_REF_REFERENCE_FETCH_INTO(object1, reference1);
567-
PHP_REF_REFERENCE_FETCH_INTO(object2, reference2);
568-
569-
/* Compare referent objects */
570-
if (NULL == reference1->referent && NULL == reference2->referent) {
571-
/* skip */
572-
} else if(NULL == reference1->referent) {
573-
return 1;
574-
} else if (NULL == reference2->referent) {
575-
return -1;
576-
} else {
577-
res = std_object_handlers.compare_objects(&reference1->referent->this_ptr, &reference2->referent->this_ptr);
578-
579-
if (res != 0) {
580-
return res;
581-
}
582-
}
583-
584-
/* Compare notifiers */
585-
ZVAL_LONG(&result, 0);
586-
587-
compare_function(&result, &reference1->notifier, &reference2->notifier);
588-
589-
if (Z_LVAL(result) != 0) {
590-
return (int) Z_LVAL(result);
591-
}
592-
593-
/* Compare standard objects */
594-
return std_object_handlers.compare_objects(object1, object2);
595-
}
596-
597524
static PHP_METHOD(WeakReference, __construct)
598525
{
599526
zval *referent_zv;
@@ -647,29 +574,19 @@ static PHP_METHOD(WeakReference, notifier)
647574
}
648575

649576
/* Change existent notifier */
650-
651-
int notifier_type = php_ref_reference_check_notifier(notifier_zv, getThis());
652-
653-
if (PHP_REF_NOTIFIER_INVALID == notifier_type) {
654-
return;
655-
}
656-
657577
RETVAL_ZVAL(&reference->notifier, 1, 1);
658578

659579
if (NULL == notifier_zv) {
660580
ZVAL_NULL(&reference->notifier);
661581
} else {
662582
ZVAL_COPY(&reference->notifier, notifier_zv);
663583
}
664-
665-
reference->notifier_type = notifier_type;
666-
667584
}
668585

669586

670587
ZEND_BEGIN_ARG_INFO_EX(arginfo_ref_reference___construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
671588
ZEND_ARG_INFO(0, referent)
672-
ZEND_ARG_INFO(0, notify)
589+
ZEND_ARG_CALLABLE_INFO(0, notify, 1)
673590
ZEND_END_ARG_INFO()
674591

675592
ZEND_BEGIN_ARG_INFO_EX(arginfo_ref_reference_get, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
@@ -678,8 +595,8 @@ ZEND_END_ARG_INFO()
678595
PHP_REF_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ref_reference_valid, ZEND_RETURN_VALUE, 0, _IS_BOOL, 0)
679596
ZEND_END_ARG_INFO()
680597

681-
ZEND_BEGIN_ARG_INFO_EX(arginfo_ref_reference_notifier, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
682-
ZEND_ARG_INFO(0, notify)
598+
PHP_REF_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ref_reference_notifier, ZEND_SEND_BY_VAL, 0, IS_CALLABLE, 1)
599+
ZEND_ARG_CALLABLE_INFO(0, notify, 1)
683600
ZEND_END_ARG_INFO()
684601

685602

@@ -721,7 +638,6 @@ PHP_MINIT_FUNCTION (php_ref_reference)
721638
php_ref_reference_object_handlers.get_gc = php_ref_reference_gc;
722639
php_ref_reference_object_handlers.clone_obj = php_ref_reference_clone_obj;
723640
php_ref_reference_object_handlers.get_debug_info = php_ref_get_debug_info;
724-
php_ref_reference_object_handlers.compare_objects = php_ref_compare_objects;
725641

726642
INIT_NS_CLASS_ENTRY(ce, PHP_REF_NS, "SoftReference", php_ref_weak_reference_methods);
727643
php_ref_soft_reference_class_entry = zend_register_internal_class_ex(&ce, php_ref_abstract_reference_class_entry);

php_ref_reference.h

-6
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ extern void php_ref_globals_referents_ht_dtor(zval *zv);
3838
#define PHP_REF_REFERENCE_FETCH(zv) php_ref_reference_fetch_object(Z_OBJ_P(zv))
3939
#define PHP_REF_REFERENCE_FETCH_INTO(pzval, into) php_ref_reference_t *(into) = PHP_REF_REFERENCE_FETCH((pzval));
4040

41-
#define PHP_REF_NOTIFIER_INVALID 0
42-
#define PHP_REF_NOTIFIER_NULL 1
43-
#define PHP_REF_NOTIFIER_ARRAY 2
44-
#define PHP_REF_NOTIFIER_CALLBACK 3
45-
4641
struct _php_ref_referent_t {
4742
zval this_ptr;
4843
uint32_t handle;
@@ -60,7 +55,6 @@ struct _php_ref_reference_t {
6055
php_ref_referent_t *referent;
6156

6257
zval notifier;
63-
int notifier_type;
6458

6559
php_ref_register register_reference;
6660
php_ref_unregister unregister_reference;

0 commit comments

Comments
 (0)