Skip to content

Commit

Permalink
Draft implementation of concurrent modification guard
Browse files Browse the repository at this point in the history
  • Loading branch information
rtheunissen committed Jan 30, 2019
1 parent 4bb4be2 commit 76eec53
Show file tree
Hide file tree
Showing 34 changed files with 223 additions and 51 deletions.
23 changes: 23 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@
#define PHP_DS_ME(cls, name) \
PHP_ME(cls, name, arginfo_##cls##_##name, ZEND_ACC_PUBLIC)

/**
*
*/
#define PHP_DS_NO_ITERATOR_OR_RETURN(obj) do { \
if (UNEXPECTED(obj->iteratorCount)) { \
MODIFIED_DURING_ITERATION(); \
} \
} while (0)

/**
* Increases the object's iterator count by 1.
*/
#define PHP_DS_INCR_ITERATOR(obj) (obj)->iteratorCount++

/**
* Decreases the object's iterator count by 1.
*/
#define PHP_DS_DECR_ITERATOR(obj) (obj)->iteratorCount--

/**
*
*/
Expand Down Expand Up @@ -222,6 +241,10 @@ int name##_unserialize( \
zend_ce_error, \
"Immutable objects may not be changed")

#define MODIFIED_DURING_ITERATION() ds_throw_exception( \
spl_ce_LogicException, \
"Modification during iteration is not supported")

/**
*
*/
Expand Down
3 changes: 3 additions & 0 deletions src/php/classes/php_map_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ METHOD(capacity)
METHOD(put)
{
PARSE_ZVAL_ZVAL(key, value);
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_MAP_OBJ());
ds_map_put(THIS_DS_MAP(), key, value);
}

METHOD(putAll)
{
PARSE_ZVAL(values);
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_MAP_OBJ());
ds_map_put_all(THIS_DS_MAP(), values);
}

Expand Down Expand Up @@ -96,6 +98,7 @@ METHOD(diff)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_MAP_OBJ());
ds_map_clear(THIS_DS_MAP());
}

Expand Down
3 changes: 3 additions & 0 deletions src/php/classes/php_priority_queue_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ METHOD(copy)
METHOD(push)
{
PARSE_ZVAL_ZVAL(value, priority);
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_PRIORITY_QUEUE_OBJ());
ds_priority_queue_push(THIS_DS_PRIORITY_QUEUE(), value, priority);
}

METHOD(pop)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_PRIORITY_QUEUE_OBJ());
ds_priority_queue_pop(THIS_DS_PRIORITY_QUEUE(), return_value);
}

Expand Down Expand Up @@ -76,6 +78,7 @@ METHOD(count)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_PRIORITY_QUEUE_OBJ());
ds_priority_queue_clear(THIS_DS_PRIORITY_QUEUE());
}

Expand Down
3 changes: 3 additions & 0 deletions src/php/classes/php_queue_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ METHOD(capacity)
METHOD(push)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_QUEUE_OBJ());
ds_queue_push(THIS_DS_QUEUE(), argc, argv);
}

METHOD(pop)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_QUEUE_OBJ());
ds_queue_pop_throw(THIS_DS_QUEUE(), return_value);
}

Expand All @@ -68,6 +70,7 @@ METHOD(count)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_QUEUE_OBJ());
ds_queue_clear(THIS_DS_QUEUE());
}

Expand Down
5 changes: 5 additions & 0 deletions src/php/classes/php_set_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ METHOD(capacity)
METHOD(add)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_SET_OBJ());
ds_set_add_va(THIS_DS_SET(), argc, argv);
}

METHOD(remove)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_SET_OBJ());
ds_set_remove_va(THIS_DS_SET(), argc, argv);
}

Expand Down Expand Up @@ -121,6 +123,7 @@ METHOD(union)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_SET_OBJ());
ds_set_clear(THIS_DS_SET());
}

Expand All @@ -144,6 +147,8 @@ METHOD(isEmpty)

METHOD(sort)
{
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_SET_OBJ());

if (ZEND_NUM_ARGS()) {
PARSE_COMPARE_CALLABLE();
ds_set_sort_callback(THIS_DS_SET());
Expand Down
3 changes: 3 additions & 0 deletions src/php/classes/php_stack_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ METHOD(capacity)
METHOD(push)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_STACK_OBJ());
ds_stack_push_va(THIS_DS_STACK(), argc, argv);
}

METHOD(pop)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_STACK_OBJ());
ds_stack_pop_throw(THIS_DS_STACK(), return_value);
}

Expand All @@ -69,6 +71,7 @@ METHOD(copy)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_STACK_OBJ());
ds_stack_clear(THIS_DS_STACK());
}

Expand Down
13 changes: 7 additions & 6 deletions src/php/classes/php_vector_ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ METHOD(capacity)
METHOD(clear)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_clear(THIS_DS_VECTOR());
}

Expand Down Expand Up @@ -97,6 +98,7 @@ METHOD(get)
METHOD(insert)
{
PARSE_LONG_AND_VARIADIC_ZVAL(index);
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_insert_va(THIS_DS_VECTOR(), index, argc, argv);
}

Expand Down Expand Up @@ -143,21 +145,17 @@ METHOD(merge)
METHOD(pop)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_pop_throw(THIS_DS_VECTOR(), return_value);
}

METHOD(push)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_push_va(THIS_DS_VECTOR(), argc, argv);
}

METHOD(push_one)
{
PARSE_ZVAL(value);
ds_vector_push(THIS_DS_VECTOR(), value);
}

METHOD(reduce)
{
PARSE_CALLABLE_AND_OPTIONAL_ZVAL(initial);
Expand All @@ -167,6 +165,7 @@ METHOD(reduce)
METHOD(remove)
{
PARSE_LONG(index);
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_remove(THIS_DS_VECTOR(), index, return_value);
}

Expand Down Expand Up @@ -197,6 +196,7 @@ METHOD(set)
METHOD(shift)
{
PARSE_NONE;
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_shift_throw(THIS_DS_VECTOR(), return_value);
}

Expand Down Expand Up @@ -254,6 +254,7 @@ METHOD(toArray)
METHOD(unshift)
{
PARSE_VARIADIC_ZVAL();
PHP_DS_NO_ITERATOR_OR_RETURN(THIS_DS_VECTOR_OBJ());
ds_vector_unshift_va(THIS_DS_VECTOR(), argc, argv);
}

Expand Down
3 changes: 3 additions & 0 deletions src/php/handlers/php_deque_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static void php_ds_deque_write_dimension(zval *obj, zval *offset, zval *value)
ds_deque_t *deque = Z_DS_DEQUE_P(obj);

if (offset == NULL) { /* $v[] = ... */
PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_DEQUE_OBJ_P(obj));
ds_deque_push(deque, value);

} else {
Expand Down Expand Up @@ -72,6 +73,8 @@ static void php_ds_deque_unset_dimension(zval *obj, zval *offset)
{
ZVAL_DEREF(offset);

PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_DEQUE_OBJ_P(obj));

if (Z_TYPE_P(offset) != IS_LONG) {
return;

Expand Down
3 changes: 3 additions & 0 deletions src/php/handlers/php_map_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static void php_ds_map_write_dimension(zval *obj, zval *offset, zval *value)

ZVAL_DEREF(offset);

PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_MAP_OBJ_P(obj));
ds_htable_put(map->table, offset, value);
}

Expand All @@ -67,6 +68,8 @@ static void php_ds_map_unset_dimension(zval *obj, zval *offset)

ZVAL_DEREF(offset);


PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_MAP_OBJ_P(obj));
ds_htable_remove(map->table, offset, NULL);
}

Expand Down
1 change: 1 addition & 0 deletions src/php/handlers/php_queue_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ static void php_ds_queue_write_dimension(zval *obj, zval *offset, zval *value)
ds_queue_t *queue = Z_DS_QUEUE_P(obj);

if (offset == NULL) {
PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_QUEUE_OBJ_P(obj));
ds_queue_push_one(queue, value);
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/php/handlers/php_set_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static zval *php_ds_set_read_dimension(zval *obj, zval *offset, int type, zval *
static void php_ds_set_write_dimension(zval *obj, zval *offset, zval *value)
{
if (offset == NULL) {
PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_SET_OBJ_P(obj));
ds_set_add(Z_DS_SET_P(obj), value);
return;
}
Expand Down Expand Up @@ -87,7 +88,7 @@ void php_ds_register_set_handlers()
{
memcpy(&php_ds_set_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));

php_ds_set_handlers.offset = 0; // XtOffsetOf(php_ds_set_t, std);
php_ds_set_handlers.offset = 0;

php_ds_set_handlers.cast_object = php_ds_default_cast_object;
php_ds_set_handlers.clone_obj = php_ds_set_clone_obj;
Expand Down
1 change: 1 addition & 0 deletions src/php/handlers/php_stack_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ static void php_ds_stack_write_dimension(zval *obj, zval *offset, zval *value)
ds_stack_t *stack = Z_DS_STACK_P(obj);

if (offset == NULL) {
PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_STACK_OBJ_P(obj));
ds_stack_push(stack, value);
return;
}
Expand Down
3 changes: 3 additions & 0 deletions src/php/handlers/php_vector_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static void php_ds_vector_write_dimension(zval *obj, zval *offset, zval *value)

/* $v[] = ... */
if (offset == NULL) {
PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_VECTOR_OBJ_P(obj));
ds_vector_push(vector, value);

} else {
Expand Down Expand Up @@ -74,6 +75,8 @@ static void php_ds_vector_unset_dimension(zval *obj, zval *offset)
zend_long index;
ds_vector_t *vector = Z_DS_VECTOR_P(obj);

PHP_DS_NO_ITERATOR_OR_RETURN(Z_DS_VECTOR_OBJ_P(obj));

ZVAL_DEREF(offset);

if (Z_TYPE_P(offset) == IS_LONG) {
Expand Down
Loading

0 comments on commit 76eec53

Please sign in to comment.