Implement GC for spl dll

As far as I can discern this should be safe, because the rc on the
linked list elements is only > 1 if an iterator points to it and
the iterator will also hold a reference to the list object.

The implementation for mangagement of the GC array is the same as
with the spl object storage.
This commit is contained in:
Nikita Popov 2015-04-16 15:13:15 +02:00
parent 018bcc6388
commit c77d97f356

View file

@ -93,6 +93,8 @@ struct _spl_dllist_object {
zend_function *fptr_offset_del;
zend_function *fptr_count;
zend_class_entry *ce_get_iterator;
zval *gc_data;
int gc_data_count;
zend_object std;
};
@ -354,6 +356,10 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */
zval_ptr_dtor(&tmp);
}
if (intern->gc_data != NULL) {
efree(intern->gc_data);
};
spl_ptr_llist_destroy(intern->llist);
SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
}
@ -531,6 +537,28 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* {
}
/* }}}} */
static HashTable *spl_dllist_object_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */
{
spl_dllist_object *intern = Z_SPLDLLIST_P(obj);
spl_ptr_llist_element *current = intern->llist->head;
int i = 0;
if (intern->gc_data_count < intern->llist->count) {
intern->gc_data_count = intern->llist->count;
intern->gc_data = safe_erealloc(intern->gc_data, intern->gc_data_count, sizeof(zval), 0);
}
while (current) {
ZVAL_COPY_VALUE(&intern->gc_data[i++], &current->data);
current = current->next;
}
*gc_data = intern->gc_data;
*gc_data_count = i;
return zend_std_get_properties(obj);
}
/* }}} */
/* {{{ proto bool SplDoublyLinkedList::push(mixed $value)
Push $value on the SplDoublyLinkedList */
SPL_METHOD(SplDoublyLinkedList, push)
@ -1366,6 +1394,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone;
spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements;
spl_handler_SplDoublyLinkedList.get_debug_info = spl_dllist_object_get_debug_info;
spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc;
spl_handler_SplDoublyLinkedList.dtor_obj = zend_objects_destroy_object;
spl_handler_SplDoublyLinkedList.free_obj = spl_dllist_object_free_storage;