Exemplo n.º 1
0
static void end_read(TsHashTable *ht)
{
#ifdef ZTS
	tsrm_mutex_lock(ht->mx_reader);
	if ((--(ht->reader)) == 0) {
		tsrm_mutex_unlock(ht->mx_writer);
	}
	tsrm_mutex_unlock(ht->mx_reader);
#endif
}
Exemplo n.º 2
0
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{/*{{{*/
	int i;

	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));

	tsrm_mutex_lock(tsmm_mutex);

	/* obtain a resource id */
	*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));

	/* store the new resource type in the resource sizes table */
	if (resource_types_table_size < id_count) {
		tsrm_resource_type *_tmp;
		_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
		if (!_tmp) {
			tsrm_mutex_unlock(tsmm_mutex);
			TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
			*rsrc_id = 0;
			return 0;
		}
		resource_types_table = _tmp;
		resource_types_table_size = id_count;
	}
	resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
	resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
	resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
	resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;

	/* enlarge the arrays for the already active threads */
	for (i=0; i<tsrm_tls_table_size; i++) {
		tsrm_tls_entry *p = tsrm_tls_table[i];

		while (p) {
			if (p->count < id_count) {
				int j;

				p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
				for (j=p->count; j<id_count; j++) {
					p->storage[j] = (void *) malloc(resource_types_table[j].size);
					if (resource_types_table[j].ctor) {
						resource_types_table[j].ctor(p->storage[j]);
					}
				}
				p->count = id_count;
			}
			p = p->next;
		}
	}
	tsrm_mutex_unlock(tsmm_mutex);

	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
	return *rsrc_id;
}/*}}}*/
Exemplo n.º 3
0
/* }}} */
void xc_mutex_unlock(xc_mutex_t *mutex) /* {{{ */
{
#ifndef NDEBUG
	assert(mutex->locked);
	mutex->locked = 0;
	assert(!mutex->locked);
#endif

#ifdef XC_MUTEX_USE_FCNTL
	if (xc_want_inter_process()) {
		xc_fcntl_unlock(&mutex->fcntl_mutex);
	}
#endif

#ifdef XC_MUTEX_USE_TSRM
	if (tsrm_mutex_unlock(mutex->tsrm_mutex) < 0) {
		zend_error(E_ERROR, "xc_mutex_unlock failed errno:%d", errno);
	}
#endif

#ifdef XC_MUTEX_USE_PTHREAD
	if (pthread_mutex_unlock(&mutex->pthread_mutex) < 0) {
		zend_error(E_ERROR, "xc_mutex_unlock failed errno:%d", errno);
	}
#endif
}
Exemplo n.º 4
0
/* deallocates all occurrences of a given id */
void ts_free_id(ts_rsrc_id id)
{/*{{{*/
	int i;
	int j = TSRM_UNSHUFFLE_RSRC_ID(id);

	tsrm_mutex_lock(tsmm_mutex);

	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Freeing resource id %d", id));

	if (tsrm_tls_table) {
		for (i=0; i<tsrm_tls_table_size; i++) {
			tsrm_tls_entry *p = tsrm_tls_table[i];

			while (p) {
				if (p->count > j && p->storage[j]) {
					if (resource_types_table && resource_types_table[j].dtor) {
						resource_types_table[j].dtor(p->storage[j]);
					}
					free(p->storage[j]);
					p->storage[j] = NULL;
				}
				p = p->next;
			}
		}
	}
	resource_types_table[j].done = 1;

	tsrm_mutex_unlock(tsmm_mutex);

	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
}/*}}}*/
Exemplo n.º 5
0
void _crypt_extended_init_r(void)
{
#ifdef PHP_WIN32
	LONG volatile initialized = 0;
#elif defined(HAVE_ATOMIC_H) /* Solaris 10 defines atomic API within */
	volatile unsigned int initialized = 0;
#else
	static volatile sig_atomic_t initialized = 0;
#endif

#ifdef ZTS
	tsrm_mutex_lock(php_crypt_extended_init_lock);
#endif

	if (!initialized) {
#ifdef PHP_WIN32
		InterlockedIncrement(&initialized);
#elif defined(HAVE_SYNC_FETCH_AND_ADD)
		__sync_fetch_and_add(&initialized, 1);
#elif (defined(__GNUC__) && (__GNUC__ >= 3))
		initialized = 1;
#elif defined(HAVE_ATOMIC_H) /* Solaris 10 defines atomic API within */
		membar_producer();
		atomic_add_int(&initialized, 1);
#endif
		_crypt_extended_init();
	}
#ifdef ZTS
	tsrm_mutex_unlock(php_crypt_extended_init_lock);
#endif
}
Exemplo n.º 6
0
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
{
	int i;

	TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
	(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
	(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
	(*thread_resources_ptr)->count = id_count;
	(*thread_resources_ptr)->thread_id = thread_id;
	(*thread_resources_ptr)->next = NULL;

	/* Set thread local storage to this new thread resources structure */
	tsrm_tls_set(*thread_resources_ptr);

	if (tsrm_new_thread_begin_handler) {
		tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
	}
	for (i=0; i<id_count; i++) {
		if (resource_types_table[i].done) {
			(*thread_resources_ptr)->storage[i] = NULL;
		} else
		{
			(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
			if (resource_types_table[i].ctor) {
				resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
			}
		}
	}

	if (tsrm_new_thread_end_handler) {
		tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
	}

	tsrm_mutex_unlock(tsmm_mutex);
}
Exemplo n.º 7
0
/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
{/*{{{*/
	THREAD_T thread_id;
	int hash_value;
	tsrm_tls_entry *thread_resources;

	if (!th_id) {
		/* Fast path for looking up the resources for the current
		 * thread. Its used by just about every call to
		 * ts_resource_ex(). This avoids the need for a mutex lock
		 * and our hashtable lookup.
		 */
		thread_resources = tsrm_tls_get();

		if (thread_resources) {
			TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
			/* Read a specific resource from the thread's resources.
			 * This is called outside of a mutex, so have to be aware about external
			 * changes to the structure as we read it.
			 */
			TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
		}
		thread_id = tsrm_thread_id();
	} else {
		thread_id = *th_id;
	}

	TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
	tsrm_mutex_lock(tsmm_mutex);

	hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
	thread_resources = tsrm_tls_table[hash_value];

	if (!thread_resources) {
		allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
		return ts_resource_ex(id, &thread_id);
	} else {
		 do {
			if (thread_resources->thread_id == thread_id) {
				break;
			}
			if (thread_resources->next) {
				thread_resources = thread_resources->next;
			} else {
				allocate_new_resource(&thread_resources->next, thread_id);
				return ts_resource_ex(id, &thread_id);
				/*
				 * thread_resources = thread_resources->next;
				 * break;
				 */
			}
		 } while (thread_resources);
	}
	tsrm_mutex_unlock(tsmm_mutex);
	/* Read a specific resource from the thread's resources.
	 * This is called outside of a mutex, so have to be aware about external
	 * changes to the structure as we read it.
	 */
	TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
}/*}}}*/
Exemplo n.º 8
0
static void php_http_openssl_thread_lock(int mode, int n, const char * file, int line)
{
	if (mode & CRYPTO_LOCK) {
		tsrm_mutex_lock(php_http_openssl_tsl[n]);
	} else {
		tsrm_mutex_unlock(php_http_openssl_tsl[n]);
	}
}
Exemplo n.º 9
0
void php_win32_free_rng_lock()
{
	tsrm_mutex_lock(php_lock_win32_cryptoctx);
	CryptReleaseContext(hCryptProv, 0);
	has_crypto_ctx = 0;
	tsrm_mutex_unlock(php_lock_win32_cryptoctx);
	tsrm_mutex_free(php_lock_win32_cryptoctx);

}
Exemplo n.º 10
0
/* ts management functions */
static void begin_read(TsHashTable *ht)
{
#ifdef ZTS
	tsrm_mutex_lock(ht->mx_reader);
	if ((++(ht->reader)) == 1) {
		tsrm_mutex_lock(ht->mx_writer);
	}
	tsrm_mutex_unlock(ht->mx_reader);
#endif
}
Exemplo n.º 11
0
void
mkd_shlib_destructor()
{
	/* on merge: added critical section */
#ifdef ZTS
	tsrm_mutex_lock(tags_mutex);
#endif
	mkd_deallocate_tags();
#ifdef ZTS
	tsrm_mutex_unlock(tags_mutex);
#endif
}
Exemplo n.º 12
0
void zend_shared_alloc_unlock(void)
{
	ZCG(locked) = 0;

#ifndef ZEND_WIN32
	if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) {
		zend_accel_error(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno);
	}
#ifdef ZTS
	tsrm_mutex_unlock(zts_lock);
#endif
#else
	zend_shared_alloc_unlock_win32();
#endif
}
Exemplo n.º 13
0
void
mkd_shlib_destructor()
{
	/* on merge: added critical section */
#ifdef ZTS
	tsrm_mutex_lock(tags_mutex);
#endif
	/* on merge: reduced to call to mkd_deallocate_tags(); */
    /*if ( !need_to_setup ) {
	need_to_setup = 1;*/
	mkd_deallocate_tags();
    /*}*/
#ifdef ZTS
	tsrm_mutex_unlock(tags_mutex);
#endif
}
Exemplo n.º 14
0
PHPAPI int php_win32_get_random_bytes(unsigned char *buf, size_t size) {  /* {{{ */

	unsigned int has_contextg = 0;

	BOOL ret;
	size_t i = 0;

#ifdef ZTS
	tsrm_mutex_lock(php_lock_win32_cryptoctx);
#endif

	if (has_crypto_ctx == 0) {
		/* CRYPT_VERIFYCONTEXT > only hashing&co-like use, no need to acces prv keys */
		if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_VERIFYCONTEXT )) {
			/* Could mean that the key container does not exist, let try 
			   again by asking for a new one. If it fails here, it surely means that the user running 
               this process does not have the permission(s) to use this container.
             */
			if (GetLastError() == NTE_BAD_KEYSET) {
				if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT )) {
					has_crypto_ctx = 1;
				} else {
					has_crypto_ctx = 0;
				}
			}
		} else {
			has_crypto_ctx = 1;
		}
	}

#ifdef ZTS
	tsrm_mutex_unlock(php_lock_win32_cryptoctx);
#endif

	if (has_crypto_ctx == 0) {
		return FAILURE;
	}

	ret = CryptGenRandom(hCryptProv, size, buf);

	if (ret) {
		return SUCCESS;
	} else {
		return FAILURE;
	}
}
Exemplo n.º 15
0
void zend_shared_alloc_unlock(TSRMLS_D)
{
	/* Destroy translation table */
	zend_hash_destroy(&xlat_table);

	ZCG(locked) = 0;

#ifndef ZEND_WIN32
	if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) {
		zend_accel_error(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno);
	}
#ifdef ZTS
	tsrm_mutex_unlock(zts_lock);
#endif
#else
	zend_shared_alloc_unlock_win32();
#endif
}
Exemplo n.º 16
0
void _crypt_extended_init_r(void)
{
	static volatile sig_atomic_t initialized = 0;

#ifdef ZTS
	tsrm_mutex_lock(php_crypt_extended_init_lock);
#endif

	if (initialized) {
		return;
	} else {
		_crypt_extended_init();
		initialized = 1;
	}
#ifdef ZTS
	tsrm_mutex_unlock(php_crypt_extended_init_lock);
#endif
}
Exemplo n.º 17
0
/* frees all resources allocated for all threads except current */
void ts_free_worker_threads(void)
{/*{{{*/
	tsrm_tls_entry *thread_resources;
	int i;
	THREAD_T thread_id = tsrm_thread_id();
	int hash_value;
	tsrm_tls_entry *last=NULL;

	tsrm_mutex_lock(tsmm_mutex);
	hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
	thread_resources = tsrm_tls_table[hash_value];

	while (thread_resources) {
		if (thread_resources->thread_id != thread_id) {
			for (i=0; i<thread_resources->count; i++) {
				if (resource_types_table[i].dtor) {
					resource_types_table[i].dtor(thread_resources->storage[i]);
				}
			}
			for (i=0; i<thread_resources->count; i++) {
				free(thread_resources->storage[i]);
			}
			free(thread_resources->storage);
			if (last) {
				last->next = thread_resources->next;
			} else {
				tsrm_tls_table[hash_value] = thread_resources->next;
			}
			free(thread_resources);
			if (last) {
				thread_resources = last->next;
			} else {
				thread_resources = tsrm_tls_table[hash_value];
			}
		} else {
			if (thread_resources->next) {
				last = thread_resources;
			}
			thread_resources = thread_resources->next;
		}
	}
	tsrm_mutex_unlock(tsmm_mutex);
}/*}}}*/
Exemplo n.º 18
0
void
mkd_initialize()
{
	/* on merge: added critical section */
#ifdef ZTS
	tsrm_mutex_lock(tags_mutex);
#endif
	/* on merge: reduced to call to mkd_prepare_tags(); */
    /* if ( need_to_initrng ) {
	need_to_initrng = 0;
	INITRNG(time(0));
    }
    if ( need_to_setup ) {
	need_to_setup = 0;*/
	mkd_prepare_tags();
    /*}*/

#ifdef ZTS
	tsrm_mutex_unlock(tags_mutex);
#endif
}
Exemplo n.º 19
0
ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
{
	anc_reg_key			key = { cmsg_level, msg_type };
	ancillary_reg_entry	*entry;

#ifdef ZTS
	tsrm_mutex_lock(ancillary_mutex);
#endif
	if (!ancillary_registry.initialized) {
		init_ancillary_registry();
	}
#ifdef ZTS
	tsrm_mutex_unlock(ancillary_mutex);
#endif

	if ((entry = zend_hash_str_find_ptr(&ancillary_registry.ht, (char*)&key, sizeof(key) - 1)) != NULL) {
		return entry;
	} else {
		return NULL;
	}
}
Exemplo n.º 20
0
ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
{
	anc_reg_key			key = { cmsg_level, msg_type };
	ancillary_reg_entry	*entry;

#ifdef ZTS
	tsrm_mutex_lock(ancillary_mutex);
#endif
	if (!ancillary_registry.initialized) {
		init_ancillary_registry();
	}
#ifdef ZTS
	tsrm_mutex_unlock(ancillary_mutex);
#endif

	if (zend_hash_find(&ancillary_registry.ht, (char*)&key, sizeof(key),
			(void**)&entry) == SUCCESS) {
		return entry;
	} else {
		return NULL;
	}
}
Exemplo n.º 21
0
static void end_write(TsHashTable *ht)
{
#ifdef ZTS
	tsrm_mutex_unlock(ht->mx_writer);
#endif
}
Exemplo n.º 22
0
void call_backtrace(int fd, zend_backtrace_globals* g, backtrace_callback_t callback)
{
#ifdef DEBUG
	fprintf(stderr, "[%d]: call_backtrace()\n", getpid());
	fflush(stderr);
#endif

	if (!callback) {
		return;
	}

	HashPosition pos;
	void** current;
	THREAD_T self = tsrm_thread_id();
	int processed_self = 0;

	tsrm_mutex_lock(mutex);

	for (
			zend_hash_internal_pointer_reset_ex(&thread_ids, &pos);
			SUCCESS == zend_hash_get_current_data_ex(&thread_ids, (void**)&current, &pos);
			zend_hash_move_forward_ex(&thread_ids, &pos)
	)
	{
		char* key;
		uint key_len;
		ulong idx;
		int type;

		type = zend_hash_get_current_key_ex(&thread_ids, &key, &key_len, &idx, 0, &pos);
		if (HASH_KEY_IS_STRING == type) {
			idx = atol(key);
		}

#ifdef DEBUG
		fprintf(stderr, "[%d]: Trying thread %lu\n", getpid(), idx);
		fflush(stderr);
#endif

		if (idx) {
#if defined(PTHREADS)
			int res = pthread_kill((pthread_t)idx, 0);
			if (res) {
				continue;
			}
#elif defined(GNUPTH)
			int res = pth_raise((pth_t)idx, 0);
			if (!res) {
				continue;
			}
#endif

#ifdef DEBUG
			fprintf(stderr, "[%d]: Processing thread %lu\n", getpid(), idx);
			fflush(stderr);
#endif

			THREAD_T thread_id = idx;

#if defined(PTHREADS)
			if (!processed_self && pthread_equal(thread_id, self)) {
				processed_self = 1;
			}
#else
			if (thread_id == self) {
				processed_self = 1;
			}
#endif

			void*** tsrm_ls = (void***)ts_resource_ex(0, &thread_id);
			callback(fd, g, tsrm_ls);
#ifdef DEBUG
			fprintf(stderr, "[%d]: Processed thread %lu\n", getpid(), idx);
			fflush(stderr);
#endif
		}
	}

	if (!processed_self) {
#ifdef DEBUG
		fprintf(stderr, "[%d]: Processing self\n", getpid());
		fflush(stderr);
#endif
		void*** tsrm_ls = (void***)ts_resource_ex(0, (THREAD_T*)0);
		callback(fd, g, tsrm_ls);
#ifdef DEBUG
		fprintf(stderr, "[%d]: Processed self\n", getpid());
		fflush(stderr);
#endif
	}

	tsrm_mutex_unlock(mutex);
}
Exemplo n.º 23
0
static int php_http_gnutls_mutex_unlock(void **m)
{
	return tsrm_mutex_unlock(*((MUTEX_T *) m));
}
Exemplo n.º 24
0
/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
{
	THREAD_T thread_id;
	int hash_value;
	tsrm_tls_entry *thread_resources;

#ifdef NETWARE
	/* The below if loop is added for NetWare to fix an abend while unloading PHP
	 * when an Apache unload command is issued on the system console.
	 * While exiting from PHP, at the end for some reason, this function is called
	 * with tsrm_tls_table = NULL. When this happened, the server abends when
	 * tsrm_tls_table is accessed since it is NULL.
	 */
	if(tsrm_tls_table) {
#endif
	if (!th_id) {
		/* Fast path for looking up the resources for the current
		 * thread. Its used by just about every call to
		 * ts_resource_ex(). This avoids the need for a mutex lock
		 * and our hashtable lookup.
		 */
		thread_resources = tsrm_tls_get();

		if (thread_resources) {
			TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
			/* Read a specific resource from the thread's resources.
			 * This is called outside of a mutex, so have to be aware about external
			 * changes to the structure as we read it.
			 */
			TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
		}
		thread_id = tsrm_thread_id();
	} else {
		thread_id = *th_id;
	}

	TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
	tsrm_mutex_lock(tsmm_mutex);

	hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
	thread_resources = tsrm_tls_table[hash_value];

	if (!thread_resources) {
		allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
		return ts_resource_ex(id, &thread_id);
	} else {
		 do {
			if (thread_resources->thread_id == thread_id) {
				break;
			}
			if (thread_resources->next) {
				thread_resources = thread_resources->next;
			} else {
				allocate_new_resource(&thread_resources->next, thread_id);
				return ts_resource_ex(id, &thread_id);
				/*
				 * thread_resources = thread_resources->next;
				 * break;
				 */
			}
		 } while (thread_resources);
	}
	tsrm_mutex_unlock(tsmm_mutex);
	/* Read a specific resource from the thread's resources.
	 * This is called outside of a mutex, so have to be aware about external
	 * changes to the structure as we read it.
	 */
	TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
#ifdef NETWARE
	}	/* if(tsrm_tls_table) */
#endif
}