Beispiel #1
0
/* {{{ */
int pthreads_compare_objects(PTHREADS_COMPARE_PASSTHRU_D) {
	pthreads_object_t *left = PTHREADS_FETCH_FROM(Z_OBJ_P(op1));
	pthreads_object_t *right = PTHREADS_FETCH_FROM(Z_OBJ_P(op2));

	/* comparing property tables is not useful or efficient for threaded objects */
	/* in addition, it might be useful to know if two variables are infact the same physical threaded object */
	if (left->monitor == right->monitor) {
		return 0;
	}

	return 1;
} /* }}} */
Beispiel #2
0
/* {{{ */
zval * pthreads_read_property (PTHREADS_READ_PROPERTY_PASSTHRU_D) {
	zend_long *guard = NULL;
	pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));

	rebuild_object_properties(&threaded->std);

	if (Z_OBJCE_P(object)->__get && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_GET)) {
		zend_fcall_info fci = empty_fcall_info;
        zend_fcall_info_cache fcc = empty_fcall_info_cache;
		
		fci.size = sizeof(zend_fcall_info);
		fci.retval = rv;
		fci.object = &threaded->std;
		zend_fcall_info_argn(&fci, 1, member);
		fcc.initialized = 1;
		fcc.function_handler = Z_OBJCE_P(object)->__get;
		fcc.object = &threaded->std;
		
		(*guard) |= IN_GET;
		zend_call_function(&fci, &fcc);
		(*guard) &= ~IN_GET;

		zend_fcall_info_args_clear(&fci, 1);
	} else {
		pthreads_store_read(object, member, type, rv);
	}
	
	return rv;
} 
Beispiel #3
0
/* {{{ unset an object property */
void pthreads_unset_property(PTHREADS_UNSET_PROPERTY_PASSTHRU_D) {
	zval *mstring = NULL;
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);

	if (Z_TYPE_P(member) != IS_STRING) {
		ALLOC_ZVAL(mstring);
		*mstring = *member;
		zval_copy_ctor(
			mstring
		);
		INIT_PZVAL(mstring);
		convert_to_string(mstring);
		member = mstring;
#if PHP_VERSION_ID > 50399
		key = NULL;
#endif
	}

	if (Z_TYPE_P(member) == IS_STRING) {
		if (pthreads_store_delete(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member) TSRMLS_CC)!=SUCCESS){
			zend_error(
				E_WARNING, 
				"pthreads has experienced an internal error while deleting %s::$%s", 
				Z_OBJCE_P(object)->name, Z_STRVAL_P(member)
			);
		}
	} else zend_error(E_WARNING, "pthreads detected an attempt to use an unsupported kind of key in %s", Z_OBJCE_P(object)->name);
	
	if (mstring != NULL) {
		zval_ptr_dtor(&mstring);
	}
}
Beispiel #4
0
/* {{{ check if a thread has a property set, wherever it is available */
int pthreads_has_property(PTHREADS_HAS_PROPERTY_PASSTHRU_D) {
	int isset = 0;
	zval *mstring = NULL;

	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);

	if (Z_TYPE_P(member) != IS_STRING) {
		ALLOC_ZVAL(mstring);
		*mstring = *member;
		zval_copy_ctor(
			mstring
		);
		INIT_PZVAL(mstring);
		convert_to_string(mstring);
		member = mstring;
#if PHP_VERSION_ID > 50399
		key = NULL;
#endif
	}

	if (Z_TYPE_P(member) == IS_STRING) {
		isset = pthreads_store_isset(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member), has_set_exists TSRMLS_CC);
	} else zend_error(E_WARNING, "pthreads has detected an attempt to use an unsupported kind of key in %s", Z_OBJCE_P(object)->name);

	if (mstring != NULL) {
		zval_ptr_dtor(&mstring);
	}

	return isset;
}
Beispiel #5
0
/* {{{ */
void pthreads_write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_D) {
	pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));
	zend_bool nulled = 0;

	rebuild_object_properties(&threaded->std);

	switch(Z_TYPE_P(value)){
		case IS_UNDEF:
		case IS_STRING:
		case IS_LONG:
		case IS_ARRAY:
		case IS_OBJECT:
		case IS_NULL:
		case IS_DOUBLE:
		case IS_RESOURCE:
		case IS_TRUE:
		case IS_FALSE: {
			zend_long *guard = NULL;
			if ((member && Z_TYPE_P(member) != IS_NULL) && 
				Z_OBJCE_P(object)->__set && 
				(guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_SET)) {
				zend_fcall_info fci = empty_fcall_info;
				zend_fcall_info_cache fcc = empty_fcall_info_cache;
				zval rv;

				ZVAL_UNDEF(&rv);

				fci.size = sizeof(zend_fcall_info);
				fci.retval = &rv;
				fci.object = &threaded->std;
				zend_fcall_info_argn(&fci, 2, member, value);
				fcc.initialized = 1;
				fcc.function_handler = Z_OBJCE_P(object)->__set;
				fcc.object = &threaded->std;

				(*guard) |= IN_SET;
				zend_call_function(&fci, &fcc);
				(*guard) &= ~IN_SET;

				if (Z_TYPE(rv) != IS_UNDEF)
					zval_dtor(&rv);
				zend_fcall_info_args_clear(&fci, 1);
			} else {
				pthreads_store_write(object, member, value);
			}
		} break;
	
		default: {
			zend_throw_exception_ex(
				spl_ce_RuntimeException, 0,
				"pthreads detected an attempt to use unsupported data (%s) for %s::$%s", 
				zend_get_type_by_const(Z_TYPE_P(value)), 
				ZSTR_VAL(Z_OBJCE_P(object)->name), Z_STRVAL_P(member));
		}
	}
}
Beispiel #6
0
/* {{{ reads properties from storage for debug only */
HashTable* pthreads_read_debug(PTHREADS_READ_DEBUG_PASSTHRU_D) {
	HashTable *table = emalloc(sizeof(HashTable));
	zend_hash_init(table, 8, NULL, ZVAL_PTR_DTOR, 0);
	*is_temp = 1;
	pthreads_store_tohash(
		(PTHREADS_FETCH_FROM(object))->store,
		table TSRMLS_CC
	);
	return table;
} /* }}} */
Beispiel #7
0
/* {{{ */
HashTable* pthreads_read_properties(PTHREADS_READ_PROPERTIES_PASSTHRU_D) {
	pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));

	rebuild_object_properties(&threaded->std);

	pthreads_store_tohash(
		object, threaded->std.properties);
		
	return threaded->std.properties;
} /* }}} */
Beispiel #8
0
/* {{{ */
HashTable* pthreads_read_debug(PTHREADS_READ_DEBUG_PASSTHRU_D) {
	HashTable *table = emalloc(sizeof(HashTable));
	pthreads_object_t *threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));

	zend_hash_init(table, 8, NULL, ZVAL_PTR_DTOR, 0);
	*is_temp = 1;

	pthreads_store_tohash(object, table);

	return table;
} /* }}} */
Beispiel #9
0
/* {{{ unset an object property */
void pthreads_unset_property(PTHREADS_UNSET_PROPERTY_PASSTHRU_D) {
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	if (pthreads_store_delete(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member) TSRMLS_CC)!=SUCCESS){
		zend_error_noreturn(
			E_WARNING, 
			"pthreads has experienced an internal error while deleting %s::$%s", 
			Z_OBJCE_P(object)->name, Z_STRVAL_P(member)
		);
	}
	zend_handlers->unset_property(PTHREADS_UNSET_PROPERTY_PASSTHRU_C);
} 
Beispiel #10
0
/* {{{ check if a thread has a property set, wherever it is available */
int pthreads_has_property(PTHREADS_HAS_PROPERTY_PASSTHRU_D) {
	int isset = 0;
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	if (!(isset = pthreads_store_isset(
		pthreads->store, 
		Z_STRVAL_P(member), Z_STRLEN_P(member), 
		has_set_exists TSRMLS_CC
	))) {
		isset = zend_handlers->has_property(PTHREADS_HAS_PROPERTY_PASSTHRU_C);
	}
	return isset;
} 
Beispiel #11
0
/* {{ reads a property from a thread, wherever it is available */
zval * pthreads_read_property (PTHREADS_READ_PROPERTY_PASSTHRU_D) {
	zval *value = NULL;
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	if (Z_TYPE_P(member)==IS_STRING) {
		if (pthreads_store_read(
			pthreads->store, 
			Z_STRVAL_P(member), Z_STRLEN_P(member), 
			&value TSRMLS_CC
		)!=SUCCESS) {	
			value = zend_handlers->read_property(PTHREADS_READ_PROPERTY_PASSTHRU_C);
		} else zend_handlers->write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_C);
	} else value = zend_handlers->read_property(PTHREADS_READ_PROPERTY_PASSTHRU_C);
	return value;
} 
Beispiel #12
0
/* {{{ reads properties from storage */
HashTable* pthreads_read_properties(PTHREADS_READ_PROPERTIES_PASSTHRU_D) {
	PTHREAD pobject = PTHREADS_FETCH_FROM(object);

#if PHP_VERSION_ID > 50399
	rebuild_object_properties(&pobject->std);
#endif

	pthreads_store_tohash(
		pobject->store, 
		pobject->std.properties TSRMLS_CC
	);
			
	return pobject->std.properties;
} /* }}} */
Beispiel #13
0
/* {{{ */
zend_bool pthreads_globals_object_connect(zend_ulong address, zend_class_entry *ce, zval *object) {
	zend_bool valid = 0;

	if (!address)
		return valid;

	if (pthreads_globals_lock()) {
		if (zend_hash_index_exists(&PTHREADS_G(objects), address)) {
			valid = 1;
		}
		pthreads_globals_unlock();
	}

	if (valid) {
		
		/*
		* This can be done outside of a critical section because there are only two possibilities:
		*	We own the object: no possible pathway to fault (read free'd memory)
		*	We don't own the object: possibly pathway to fault whether we use critical section or not:
		*		We use a critical section: we create the connection knowing that address cannot be freed while doing so
		*		however, as soon as we leave the section, and before the conext that called this routine can reference the connection
		*		object the creating context may have free'd the object.
		*		We don't use a critical section: the object may be freed while we are creating the connection, causing a fault.
		* 
		* As always, it's necessary for the programmer to retain the appropriate references so that this does not fault, creating connections
		* in a critical section would be unecessarily slow, not to mention recursively lock mutex (which is fine, but not ideal).
		*/

		if (PTHREADS_IN_CREATOR(((pthreads_object_t*)address))) {
			/* we own the object in this context */
			ZVAL_OBJ(object, &((pthreads_object_t*)address)->std);
			Z_ADDREF_P(object);
		} else {
			/* we do not own the object, create a connection */
			if (!ce) {
				/* we may not know the class, can't use ce directly
					from zend_object because it is from another context */
				ce = zend_lookup_class(
					((pthreads_object_t*)address)->std.ce->name);
			}
			object_init_ex(object, ce);
			pthreads_connect(
				(pthreads_object_t*) address,
				PTHREADS_FETCH_FROM(Z_OBJ_P(object)));
		}
	}
	
	return valid;
} /* }}} */
Beispiel #14
0
/* {{{ pthreads_cast_object */
int pthreads_cast_object(PTHREADS_CAST_PASSTHRU_D) {
    switch (type) {
        case IS_ARRAY: {
            pthreads_store_tohash(
                (PTHREADS_FETCH_FROM(from))->store, Z_ARRVAL_P(to) TSRMLS_CC
            );
            return SUCCESS;
        } break;
        
        default:
            return FAILURE;
    }
    
    return SUCCESS;
} /* }}} */
Beispiel #15
0
/* {{ reads a property from a thread, wherever it is available */
zval * pthreads_read_property (PTHREADS_READ_PROPERTY_PASSTHRU_D) {
	zval *value = NULL, *mstring = NULL;
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	
	if (Z_TYPE_P(member) != IS_STRING) {
		ALLOC_ZVAL(mstring);
		*mstring = *member;
		zval_copy_ctor(
			mstring
		);
		INIT_PZVAL(mstring);
		zend_try {
			convert_to_string(mstring);
		} zend_end_try();
		member = mstring;
#if PHP_VERSION_ID > 50399
		key = NULL;
#endif
	}
Beispiel #16
0
/* {{{ pthreads_get_method will attempt to apply pthreads specific modifiers */
zend_function * pthreads_get_method(PTHREADS_GET_METHOD_PASSTHRU_D) {
	zend_class_entry *scope;
	zend_function *call;
	zend_function *callable;
	char *lcname;
	int access = 0;
	PTHREAD thread = PTHREADS_FETCH_FROM(*pobject);
	
	if (thread) {
		switch((access=pthreads_modifiers_get(thread->modifiers, method TSRMLS_CC))){
			case ZEND_ACC_PRIVATE:
			case ZEND_ACC_PROTECTED:
				scope = Z_OBJCE_PP(pobject);
				lcname =  (char*) calloc(1, methodl+1);
				zend_str_tolower_copy(lcname, method, methodl);
				if (zend_hash_find(&scope->function_table, lcname, methodl+1, (void**)&call)==SUCCESS) {
					callable = (zend_function*) emalloc(sizeof(zend_function));
					callable->type = ZEND_OVERLOADED_FUNCTION;
					callable->common.function_name = call->common.function_name;
					callable->common.fn_flags = ZEND_ACC_PUBLIC;
					callable->common.scope = scope;
					callable->common.arg_info = call->common.arg_info;
					callable->common.num_args = call->common.num_args;
					callable->common.required_num_args = call->common.required_num_args;
#if PHP_VERSION_ID < 50400
					callable->common.pass_rest_by_reference = call->common.pass_rest_by_reference;
					callable->common.return_reference = call->common.return_reference;
#endif
					free(lcname);
					return callable;
				}
				free(lcname);
				/* TODO : if not found ? switch to default ? or return some error ? */

			default: call = zend_handlers->get_method(PTHREADS_GET_METHOD_PASSTHRU_C);
		}
		
	} else call = zend_handlers->get_method(PTHREADS_GET_METHOD_PASSTHRU_C);
	
	return call;
} /* }}} */
Beispiel #17
0
/* {{{ */
int pthreads_has_property(PTHREADS_HAS_PROPERTY_PASSTHRU_D) {
	int isset = 0;
	zend_long *guard = NULL;
	pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));

	cache = NULL;

	if (Z_OBJCE_P(object)->__isset && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_ISSET)) {
		zend_fcall_info fci = empty_fcall_info;
		zend_fcall_info_cache fcc = empty_fcall_info_cache;
		zval rv;

		ZVAL_UNDEF(&rv);

		fci.size = sizeof(zend_fcall_info);
		fci.retval = &rv;
		fci.object = &threaded->std;
		zend_fcall_info_argn(&fci, 1, member);
		fcc.initialized = 1;
		fcc.function_handler = Z_OBJCE_P(object)->__isset;
		fcc.object = &threaded->std;

		(*guard) |= IN_ISSET;
		zend_call_function(&fci, &fcc);
		(*guard) &= ~IN_ISSET;
	
		if (Z_TYPE(rv) != IS_UNDEF) {
			isset = 
				zend_is_true(&rv);
			zval_dtor(&rv);
		}
		zend_fcall_info_args_clear(&fci, 1);
	} else {
		isset = pthreads_store_isset(object, member, has_set_exists);
	}

	return isset;
}
Beispiel #18
0
/* {{{ */
void pthreads_unset_property(PTHREADS_UNSET_PROPERTY_PASSTHRU_D) {
	zend_long *guard = NULL;
	pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object));

	cache = NULL;

	rebuild_object_properties(&threaded->std);

	if (Z_OBJCE_P(object)->__unset && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_UNSET)) {
		zend_fcall_info fci = empty_fcall_info;
		zend_fcall_info_cache fcc = empty_fcall_info_cache;
		zval rv;

		ZVAL_UNDEF(&rv);

		fci.size = sizeof(zend_fcall_info);
		fci.retval = &rv;
		fci.object = &threaded->std;
		zend_fcall_info_argn(&fci, 1, member);
		fcc.initialized = 1;
		fcc.function_handler = Z_OBJCE_P(object)->__unset;
		fcc.object = &threaded->std;

		(*guard) |= IN_UNSET;
		zend_call_function(&fci, &fcc);
		(*guard) &= ~IN_UNSET;
	
		if (Z_TYPE(rv) != IS_UNDEF) {
			zval_dtor(&rv);
		}
		zend_fcall_info_args_clear(&fci, 1);
	} else {
		if (pthreads_store_delete(object, member) == SUCCESS){
			
		}
	}
}
Beispiel #19
0
/* {{ reads a property from a thread, wherever it is available */
zval * pthreads_read_property (PTHREADS_READ_PROPERTY_PASSTHRU_D) {
	zval *value = NULL, *mstring = NULL;
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	
	if (Z_TYPE_P(member) != IS_STRING) {
		ALLOC_ZVAL(mstring);
		*mstring = *member;
		zval_copy_ctor(
			mstring
		);
		INIT_PZVAL(mstring);
		convert_to_string(mstring);
		member = mstring;
#if PHP_VERSION_ID > 50399
		key = NULL;
#endif
	}
	
	if (Z_TYPE_P(member)==IS_STRING) {
		pthreads_store_read(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member), &value TSRMLS_CC);
	} else {
		zend_error(E_WARNING, "pthreads detected an attempt to use an unsupported kind of key in %s", Z_OBJCE_P(object)->name);
		if (value != NULL) {
			value = EG(
				uninitialized_zval_ptr
			);
			Z_ADDREF_P(value);
		}
	}

	if (mstring != NULL) {
		zval_ptr_dtor(&mstring);
	}
	
	return value;
} 
Beispiel #20
0
/* {{{ writes a property to a thread in the appropriate way */
void pthreads_write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_D) {
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	if (Z_TYPE_P(member)==IS_STRING) {
		switch(Z_TYPE_P(value)){
			case IS_STRING:
			case IS_LONG:
			case IS_ARRAY:
			case IS_OBJECT:
			case IS_NULL:
			case IS_DOUBLE:
			case IS_BOOL: {
				if (pthreads_store_write(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member), &value TSRMLS_CC)!=SUCCESS){
					zend_error_noreturn(
						E_WARNING, 
						"pthreads failed to write member %s::$%s", 
						Z_OBJCE_P(object)->name, Z_STRVAL_P(member)
					);
				} else zend_handlers->write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_C);
			} break;
			
			default: zend_handlers->write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_C);
		}
	} else zend_handlers->write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_C);
} 
Beispiel #21
0
/* {{{ writes a property to a thread in the appropriate way */
void pthreads_write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_D) {
	PTHREAD pthreads = PTHREADS_FETCH_FROM(object);
	zval *mstring = NULL;
	zend_bool nulled = 0;
	zend_bool locked;
	
	if (member == NULL || Z_TYPE_P(member) == IS_NULL) {
	    /* for anonymous members, 
	        we acquire the lock and increment a counter
	        we do not store any additional information or perform any lookups */
		pthreads_lock_acquire(pthreads->store->lock, &locked TSRMLS_CC);
		{
			if (member == NULL) {
			    MAKE_STD_ZVAL(member);
			    
			    nulled = 1;
			}
			
			ZVAL_LONG(member, pthreads->store->next++);
		}
		pthreads_lock_release(pthreads->store->lock, locked TSRMLS_CC);
	}

	if (Z_TYPE_P(member) != IS_STRING) {
		ALLOC_ZVAL(mstring);
		*mstring = *member;
		zval_copy_ctor(
			mstring
		);
		INIT_PZVAL(mstring);
		convert_to_string(mstring);
		if(nulled) 
			FREE_ZVAL(member);
		member = mstring;
#if PHP_VERSION_ID > 50399
		key = NULL;
#endif
	}

	if (Z_TYPE_P(member)==IS_STRING) {
		switch(Z_TYPE_P(value)){
			case IS_STRING:
			case IS_LONG:
			case IS_ARRAY:
			case IS_OBJECT:
			case IS_NULL:
			case IS_DOUBLE:
			case IS_RESOURCE:
			case IS_BOOL: {
				if (pthreads_store_write(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member), &value TSRMLS_CC)!=SUCCESS){
					zend_error(
						E_WARNING, 
						"pthreads failed to write member %s::$%s", 
						Z_OBJCE_P(object)->name, Z_STRVAL_P(member)
					);
				}
			} break;
			
			default: {
				zend_error(
					E_WARNING, 
					"pthreads detected an attempt to use an unsupported kind of data for %s::$%s", 
					Z_OBJCE_P(object)->name, Z_STRVAL_P(member)
				);
			}
		}
	} else zend_error(
		E_WARNING,
		"pthreads detected an attempt to use an unsupported kind of key in %s", 
		Z_OBJCE_P(object)->name
	);

	if (mstring != NULL) {
		zval_ptr_dtor(&mstring);
	}
}
Beispiel #22
0
	if (pthreads_lock_acquire(thread->lock, &locked TSRMLS_CC)) {
		zend_llist *stack = &thread->stack->objects;
		if (work) {
			zend_llist_del_element(stack, &work, (int (*)(void *, void *)) pthreads_equal_func);
		} else zend_llist_destroy(stack);
		remain = stack->count;
		pthreads_lock_release(thread->lock, locked TSRMLS_CC);
	} else remain = -1;
	return remain;
} /* }}} */

/* {{{ push an item onto the work buffer */
size_t pthreads_stack_push(PTHREAD thread, zval *work TSRMLS_DC) {
	zend_bool locked;
	PTHREAD stackable = PTHREADS_FETCH_FROM(work);
	size_t counted = 0L;

	if (pthreads_lock_acquire(thread->lock, &locked TSRMLS_CC)) {
		zend_llist *stack = &thread->stack->objects;
		if (stack) {
			zend_llist_add_element(
				stack, &stackable
			);
			counted = stack->count;

			Z_OBJ_HT_P(work)->add_ref(work TSRMLS_CC);
		}
		pthreads_lock_release(thread->lock, locked TSRMLS_CC);

		if (counted > 0L) {
Beispiel #23
0
				    zend_hash_get_current_data_ex(stack, (void**)&search, &position) == SUCCESS;
				    zend_hash_move_forward_ex(stack, &position)) {
				    /* arghhh */
				}
			} else zend_hash_destroy(stack);
			remain = zend_hash_num_elements(stack);
		}
		pthreads_lock_release(thread->lock, locked TSRMLS_CC);
	} else remain = -1;
	return remain;
} /* }}} */

/* {{{ push an item onto the work buffer */
size_t pthreads_stack_push(PTHREAD thread, zval *work TSRMLS_DC) {
	zend_bool locked;
	PTHREAD threaded = PTHREADS_FETCH_FROM(work);
	size_t counted = 0L;
	
	if (pthreads_lock_acquire(thread->lock, &locked TSRMLS_CC)) {
		HashTable *stack = &thread->stack->objects;
		if (stack) {
	        if (!zend_hash_num_elements(stack)) {
	            zend_hash_clean(
	                stack);
	            thread->stack->position = 0L;
	        }
	        
		    zend_hash_next_index_insert(
		        stack, (void**) &threaded, sizeof(struct _pthread_construct), NULL
		    );
			counted = zend_hash_num_elements(stack);
Beispiel #24
0
        if (zend_hash_init(&store->table, 8, NULL, (dtor_func_t) pthreads_store_storage_dtor, 1)==SUCCESS) {
            if ((store->lock = pthreads_lock_alloc(TSRMLS_C))) {
                store->next = 0L;

                return store;
            }
            zend_hash_destroy(&store->table);
        }
        free(store);
    }
    return NULL;
} /* }}} */

/* {{{ lock storage, userland only */
zend_bool pthreads_store_lock(zval *this_ptr TSRMLS_DC) {
    PTHREAD pobject = PTHREADS_FETCH_FROM(getThis());
    if (pobject) {
        return pthreads_lock_acquire(
                   pobject->store->lock,
                   &pobject->hold TSRMLS_CC
               );
    } else return 0;
} /* }}} */

/* {{{ unlock storage, userland only */
zend_bool pthreads_store_unlock(zval *this_ptr TSRMLS_DC) {
    PTHREAD pobject = PTHREADS_FETCH_FROM(getThis());
    if (pobject) {
        return pthreads_lock_release(
                   pobject->store->lock,
                   pobject->hold TSRMLS_CC