/* {{{ isset helper for handlers */ zend_bool pthreads_store_isset(pthreads_store store, char *key, int keyl, int has_set_exists TSRMLS_DC) { zend_bool locked = 0, isset = 0; if (store) { if (pthreads_lock_acquire(store->lock, &locked TSRMLS_CC)) { pthreads_storage *storage; if (zend_ts_hash_find(&store->table, key, keyl, (void**)&storage)==SUCCESS) { isset=((*storage)->exists); } pthreads_lock_release(store->lock, locked TSRMLS_CC); } } return isset; } /* }}} */
/* {{{ pop for php */ size_t pthreads_stack_pop(PTHREAD thread, PTHREAD work TSRMLS_DC) { zend_bool locked; int remain = 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; } /* }}} */
/* {{{ delete a value from the store */ int pthreads_store_delete(pthreads_store store, char *key, int keyl TSRMLS_DC) { int result = FAILURE; zend_bool locked; if (store) { if (pthreads_lock_acquire(store->lock, &locked TSRMLS_CC)) { if (zend_ts_hash_exists(&store->table, key, keyl)) { if (zend_ts_hash_del(&store->table, key, keyl)!=SUCCESS) { result = FAILURE; } else result = SUCCESS; } else result = SUCCESS; pthreads_lock_release(store->lock, locked TSRMLS_CC); } else result = FAILURE; } return result; }
/* {{{ pop for php */ size_t pthreads_stack_pop(PTHREAD thread, PTHREAD work TSRMLS_DC) { zend_bool locked; int remain = 0; if (pthreads_lock_acquire(thread->lock, &locked TSRMLS_CC)) { HashTable *stack = &thread->stack->objects; if (work) { HashPosition position; PTHREAD search = NULL; for (zend_hash_internal_pointer_reset_ex(stack, &position); 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, PTHREAD work TSRMLS_DC) { zend_bool locked; 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, &work ); counted = stack->count; } pthreads_lock_release(thread->lock, locked TSRMLS_CC); if (counted > 0L) { if (pthreads_state_isset(thread->state, PTHREADS_ST_WAITING TSRMLS_CC)) { pthreads_unset_state(thread, PTHREADS_ST_WAITING TSRMLS_CC); } } } return counted; } /* }}} */
/* {{{ 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); } }