Beispiel #1
0
/* Restart all threads that are waiting on the condition variable */
int acl_pthread_cond_broadcast(acl_pthread_cond_t *cond)
{
	const char *myname = "acl_pthread_cond_broadcast";

	if (cond == NULL) {
		acl_msg_error("%s, %s(%d): input invalid",
			__FILE__, myname, __LINE__);
		return -1;
	}

	/* If there are waiting threads not already signalled, then
	 * signal the condition and wait for the thread to respond.
	 */
	acl_pthread_mutex_lock(cond->lock);
	if (cond->waiting > cond->signals) {
		int i, num_waiting;

		num_waiting = (cond->waiting - cond->signals);
		cond->signals = cond->waiting;
		for (i = 0; i < num_waiting; ++i)
			acl_sem_post(cond->wait_sem);

		/* Now all released threads are blocked here, waiting for us.
		 * Collect them all (and win fabulous prizes!) :-)
		 */
		acl_pthread_mutex_unlock(cond->lock);
		for (i = 0; i < num_waiting; ++i)
			acl_sem_wait(cond->wait_done);
	} else
		acl_pthread_mutex_unlock(cond->lock);

	return 0;
}
Beispiel #2
0
bool rpc_request::cond_signal()
{
	int status;

	status = acl_pthread_mutex_lock(lock_);
	if (status != 0)
	{
		logger_error("pthread_mutex_lock error: %d", status);
		return false;
	}

	cond_count_++;

	status = acl_pthread_cond_signal(cond_);
	if (status != 0)
	{
		(void) acl_pthread_mutex_unlock(lock_);
		logger_error("pthread_cond_signal error: %d", status);
		return false;
	}

	status = acl_pthread_mutex_unlock(lock_);
	if (status != 0)
	{
		logger_error("pthread_mutex_unlock error: %d", status);
		return false;
	}

	return true;
}
Beispiel #3
0
void hook_epoll(void)
{
	static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER;
	static int __called = 0;

	(void) acl_pthread_mutex_lock(&__lock);

	if (__called) {
		(void) acl_pthread_mutex_unlock(&__lock);
		return;
	}

	__called++;

	__sys_epoll_create = (epoll_create_fn) dlsym(RTLD_NEXT, "epoll_create");
	acl_assert(__sys_epoll_create);

	__sys_epoll_wait   = (epoll_wait_fn) dlsym(RTLD_NEXT, "epoll_wait");
	acl_assert(__sys_epoll_wait);

	__sys_epoll_ctl    = (epoll_ctl_fn) dlsym(RTLD_NEXT, "epoll_ctl");
	acl_assert(__sys_epoll_ctl);

	(void) acl_pthread_mutex_unlock(&__lock);
}
Beispiel #4
0
void * acl_atomic_xchg(ACL_ATOMIC *self, void *value)
{
#ifndef HAS_ATOMIC
	void *old;

	acl_pthread_mutex_lock(&self->lock);
	old = self->value;
	self->value = value;
	acl_pthread_mutex_unlock(&self->lock);

	return old;
#elif	defined(ACL_WINDOWS)
	return InterlockedExchangePointer((volatile PVOID*)&self->value, value);
#elif	defined(ACL_LINUX)
# if defined(__GNUC__) && (__GNUC__ >= 4)
	return __sync_lock_test_and_set(&self->value, value);
# else
	(void) self;
	(void) value;
	acl_msg_error("%s(%d), %s: not support!",
		 __FILE__, __LINE__, __FUNCTION__);
	return NULL;
# endif
#endif
}
Beispiel #5
0
bool locker::lock()
{
#ifdef	ACL_HAS_SPINLOCK
	if (spinlock_)
	{
		if (pthread_spin_lock(spinlock_) != 0)
			return false;
	}
	else
#endif
	if (mutex_)
	{
		if (acl_pthread_mutex_lock(mutex_) != 0)
			return false;
	}

	if (fHandle_ == ACL_FILE_INVALID)
		return true;

	int operation = ACL_FLOCK_OP_EXCLUSIVE;
	if (acl_myflock(fHandle_, ACL_FLOCK_STYLE_FCNTL, operation) == 0)
		return true;

	if (mutex_)
		acl_assert(acl_pthread_mutex_unlock(mutex_) == 0);
	return false;
}
Beispiel #6
0
static void run_thread(void *arg)
{
	RUN_CTX *ctx = (RUN_CTX*) arg;

	acl_pthread_mutex_lock(&__mutex);
	acl_vstream_fprintf(ctx->fp, "hello world, hello world, hello world, hello world, i: %d\n", ctx->i);
	acl_pthread_mutex_unlock(&__mutex);
	acl_myfree(ctx);
}
Beispiel #7
0
static void test_thread(void)
{
	acl_pthread_t tid;
	acl_pthread_attr_t attr;
	THREAD_CTX ctx, *pctx;
	void *return_arg;
	unsigned int id;

	acl_pthread_mutex_lock(&mutex_init1);
	printf("lock mutex_init1 ok\n");
	acl_pthread_mutex_lock(&mutex_init2);
	printf("lock mutex_init2 ok\n");

	ctx.i = 0;
	acl_pthread_attr_init(&attr);
	acl_pthread_create(&tid, &attr, test_thread_fn, &ctx);
	acl_pthread_join(tid, (void**) &return_arg);
	pctx = (THREAD_CTX*) return_arg;
	memcpy(&id, &tid, sizeof(id));
	printf("ctx.i=%d, pctx->i=%d, the thread id is: %u\r\n",
		ctx.i, pctx->i, id);
}
Beispiel #8
0
bool thread_mutex::lock(void)
{
	int ret = acl_pthread_mutex_lock(mutex_);
	if (ret)
	{
#ifdef ACL_UNIX
		acl_set_error(ret);
		logger_error("pthread_mutex_lock error %s", last_serror());
#endif
		return false;
	}
	return true;
}
Beispiel #9
0
static DWORD WINAPI RunThreadWrap(LPVOID data)
#endif
{
	acl_pthread_t *thread = (acl_pthread_t *) data;
	void *return_arg;
	ACL_FIFO *tls_value_list_ptr = tls_value_list_get();
	unsigned long *tid = 0;

	/* 只是为了避免与主线程的 h_thread->handle = handle 产生冲突 */
	if (__thread_inited)
		acl_pthread_mutex_lock(&__thread_lock);
	if (__thread_inited)
		acl_pthread_mutex_unlock(&__thread_lock);

	thread->id = acl_pthread_self();

	return_arg = (void*) thread->start_routine(thread->routine_arg);

	/* 释放由 acl_pthread_setspecific 添加的线程局部变量 */
	while (1) {
		TLS_VALUE *tls_value = private_fifo_pop(tls_value_list_ptr);

		if (tls_value == NULL)
			break;

		if (tls_value->tls_key == NULL
			|| tls_value->tls_key->destructor == NULL
			|| tls_value->tls_key->key < 0
			|| tls_value->tls_key->key >= ACL_PTHREAD_KEYS_MAX)
		{
			acl_default_free(__FILE__, __LINE__, tls_value);
			continue;
		}
		tls_value->tls_key->destructor(tls_value->value);
		acl_default_free(__FILE__, __LINE__, tls_value);
	}

	private_fifo_free(tls_value_list_ptr, NULL);

	/* 如果线程创建时为分离方式则需要关闭线程句柄 */
	if (thread->detached) {
		if (!CloseHandle(thread->handle)) {
			acl_msg_error("close handle error(%s)", 
				acl_last_serror());
		}
	}

	acl_default_free(__FILE__, __LINE__, thread);
	return (DWORD) return_arg;
}
Beispiel #10
0
int acl_mbox_send(ACL_MBOX *mbox, void *msg)
{
	int ret;

	acl_pthread_mutex_lock(mbox->lock);
	acl_ypipe_write(mbox->ypipe, msg);
	ret = acl_ypipe_flush(mbox->ypipe);
	acl_pthread_mutex_unlock(mbox->lock);
	if (ret == 0)
		return 0;

	mbox->nsend++;

	if (acl_vstream_writen(mbox->out, __key, sizeof(__key) - 1)
		== ACL_VSTREAM_EOF)
	{
		return -1;
	} else
		return 0;

}
Beispiel #11
0
/* Restart one of the threads that are waiting on the condition variable */
int acl_pthread_cond_signal(acl_pthread_cond_t *cond)
{
	const char *myname = "acl_pthread_cond_signal";

	if (cond == NULL) {
		acl_msg_error("%s, %s(%d): input invalid",
			__FILE__, myname, __LINE__);
		return -1;
	}

	/* If there are waiting threads not already signalled, then
	 *  signal the condition and wait for the thread to respond.
	 */
	acl_pthread_mutex_lock(cond->lock);
	if (cond->waiting > cond->signals) {
		++cond->signals;
		acl_sem_post(cond->wait_sem);
		acl_pthread_mutex_unlock(cond->lock);
		acl_sem_wait(cond->wait_done);
	} else
		acl_pthread_mutex_unlock(cond->lock);

	return 0;
}
Beispiel #12
0
int  acl_pthread_create(acl_pthread_t *thread, acl_pthread_attr_t *attr,
	void *(*start_routine)(void *), void *arg)
{
	const char *myname = "acl_pthread_create";
	acl_pthread_t *h_thread;
	HANDLE handle;
	unsigned long id, flag;
	
	if (thread == NULL) {
		acl_msg_error("%s, %s(%d): input invalid",
			__FILE__, myname, __LINE__);
		acl_set_error(ACL_EINVAL);
		return ACL_EINVAL;
	}
	acl_pthread_once(&__create_thread_control_once, acl_pthread_init_once);
	memset(thread, 0, sizeof(acl_pthread_t));

	h_thread = acl_default_calloc(__FILE__, __LINE__,
			1, sizeof(acl_pthread_t));
	if (h_thread == NULL) {
		acl_msg_error("%s, %s(%d): calloc error(%s)",
			__FILE__, myname, __LINE__, acl_last_serror());
		acl_set_error(ACL_ENOMEM);
		return ACL_ENOMEM;
	}

	if (attr != NULL)
		h_thread->detached = attr->detached;
	else
		h_thread->detached = 1;
	h_thread->start_routine = start_routine;
	h_thread->routine_arg   = arg;

	if (__thread_inited) {
		acl_pthread_mutex_lock(&__thread_lock);
		flag = 0;
	} else
		flag = CREATE_SUSPENDED;

#ifdef ACL_WIN32_STDC
	h_thread->handle = handle = (HANDLE) _beginthreadex(NULL,
			attr ? (unsigned int) attr->stacksize : 0,
			RunThreadWrap,
			(void *) h_thread,
			flag,
			&id);
#else
	h_thread->handle = handle = CreateThread(NULL,
			attr ? attr->stacksize : 0,,
			RunThreadWrap,
			h_thread,
			flag,
			&id);
#endif

	if (__thread_inited)
		acl_pthread_mutex_unlock(&__thread_lock);
	else if (flag == CREATE_SUSPENDED && handle != 0)
		ResumeThread(handle);
	if (handle == 0) {
		acl_msg_error("%s, %s(%d): CreateThread error(%s)",
			__FILE__, myname, __LINE__, acl_last_serror());
		return -1;
	}
	thread->start_routine = start_routine;
	thread->routine_arg   = arg;
	thread->id            = id;
	thread->handle        = 0;

	/* 根据线程的属性来确定线程创建时是分离模式还是非分离模式 */

	if (attr == NULL || attr->detached) {
		thread->detached = 1;
		return 0;
	}

	thread->detached = 0;
	thread->handle = handle;
	return 0;
}
Beispiel #13
0
bool rpc_request::cond_wait(int timeout /* = -1 */)
{
	int status;

	status = acl_pthread_mutex_lock(lock_);
	if (status != 0)
	{
		logger_error("pthread_mutex_lock error: %d", status);
		return false;
	}

	if (--cond_count_ >= 0)
	{
		status = acl_pthread_mutex_unlock(lock_);
		if (status != 0)
		{
			logger_error("pthread_mutex_unlock error: %d", status);
			return false;
		}
		return true;
	}

	if (timeout < 0)
	{
		status = acl_pthread_cond_wait(cond_, lock_);
		if (status != 0)
		{
			logger_error("pthread_cond_wait error: %d", status);
			status = acl_pthread_mutex_unlock(lock_);
			if (status != 0)
				logger_error("pthread_mutex_unlock error: %d", status);
			return false;
		}
		status = acl_pthread_mutex_unlock(lock_);
		if (status != 0)
		{
			logger_error("pthread_mutex_unlock error: %d", status);
			return false;
		}
		return true;
	}

	struct  timeval   tv;
	struct	timespec  when_ttl;
	gettimeofday(&tv, NULL);
	when_ttl.tv_sec = tv.tv_sec + timeout / 1000;
	when_ttl.tv_nsec = tv.tv_usec * 1000 + (timeout % 1000) * 1000;
	wait_timedout_ = false;

	status = acl_pthread_cond_timedwait(cond_, lock_, &when_ttl);
	if (status != 0)
	{
		if (status == ACL_ETIMEDOUT)
			wait_timedout_ = true;
		else
			logger_error("pthread_cond_timedwait error: %d", status);
		status = acl_pthread_mutex_unlock(lock_);
		if (status != 0)
			logger_error("pthread_mutex_unlock error: %d", status);
		return false;
	}
	else
	{
		status = acl_pthread_mutex_unlock(lock_);
		if (status != 0)
		{
			logger_error("pthread_mutex_unlock error: %d", status);
			return false;
		}
		return true;
	}
}
Beispiel #14
0
static void mempool_bench_test(const char *label, int mutex, int loop, acl_mem_type type, int size)
{
	int   i = 0;
	time_t begin = 0, end = 0;
	void *buf;
#ifdef	MUTEX_INIT
	acl_pthread_mutex_t lock;
#elif defined(WIN32)
	acl_pthread_mutex_t lock;
#define MUTEX_INIT
#else
	acl_pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#endif

	if (mutex) {
#ifdef	MUTEX_INIT
		acl_pthread_mutex_init(&lock, NULL);
#endif
		time(&begin);
		while (i++ < loop) {
			acl_pthread_mutex_lock(&lock);
			acl_pthread_mutex_unlock(&lock);
		}
		time(&end);
		printf("lock and unkock, loop %d, time cost is %ld\r\n", loop, (long int) end - begin);

		i = 0;
		if (type > ACL_MEM_TYPE_NONE && type < ACL_MEM_TYPE_MAX) {
			time(&begin);
			while (i++ < loop) {
				acl_pthread_mutex_lock(&lock);
				buf = acl_allocator_mem_alloc(__var_allocator, type);
				acl_pthread_mutex_unlock(&lock);

				acl_pthread_mutex_lock(&lock);
				acl_allocator_mem_free(__var_allocator, type, buf);
				acl_pthread_mutex_unlock(&lock);
			}
			time(&end);
		} else if (type == MEM_TYPE_GROSS) {
			acl_pthread_mutex_lock(&lock);
			buf = acl_allocator_membuf_alloc(__FILE__, __LINE__,
				__var_allocator, size);
			acl_pthread_mutex_unlock(&lock);

			acl_pthread_mutex_lock(&lock);
			acl_allocator_membuf_free(__FILE__, __LINE__,
				__var_allocator, buf);
			acl_pthread_mutex_unlock(&lock);
		} else {
			time(&begin);
			while (i++ < loop) {
				acl_pthread_mutex_lock(&lock);
				buf = MALLOC(size);
				acl_pthread_mutex_unlock(&lock);

				acl_pthread_mutex_lock(&lock);
				FREE(buf);
				acl_pthread_mutex_unlock(&lock);
			}
			time(&end);
		}
#ifdef	MUTEX_INIT
		acl_pthread_mutex_destroy(&lock);
#endif
	} else {
		if (type > ACL_MEM_TYPE_NONE && type < ACL_MEM_TYPE_MAX) {
			time(&begin);
			while (i++ < loop) {
				buf = acl_allocator_mem_alloc(__var_allocator, type);
				acl_allocator_mem_free(__var_allocator, type, buf);
			}
			time(&end);
		} else if (type == MEM_TYPE_GROSS) {
			buf = acl_allocator_membuf_alloc(__FILE__, __LINE__,
				__var_allocator, size);
			acl_allocator_membuf_free(__FILE__, __LINE__,
				__var_allocator, buf);
		} else {
			time(&begin);
			while (i++ < loop) {
				buf = MALLOC(size);
				FREE(buf);
			}
			time(&end);
		}
	}

	printf("%s: time cost is %ld seconds, count is %d\r\n",
		label, (long int) end - begin, loop);
}
Beispiel #15
0
void hook_io(void)
{
	static acl_pthread_mutex_t __lock = PTHREAD_MUTEX_INITIALIZER;
	static int __called = 0;

	(void) acl_pthread_mutex_lock(&__lock);

	if (__called) {
		(void) acl_pthread_mutex_unlock(&__lock);
		return;
	}

	__called++;

	__sys_sleep      = (sleep_fn) dlsym(RTLD_NEXT, "sleep");
	acl_assert(__sys_sleep);

	__sys_pipe       = (pipe_fn) dlsym(RTLD_NEXT, "pipe");
	acl_assert(__sys_pipe);

#ifdef HAS_PIPE2
	__sys_pipe2      = (pipe2_fn) dlsym(RTLD_NEXT, "pipe2");
	acl_assert(__sys_pipe2);
#endif

	__sys_popen      = (popen_fn) dlsym(RTLD_NEXT, "popen");
	acl_assert(__sys_popen);

	__sys_pclose     = (pclose_fn) dlsym(RTLD_NEXT, "pclose");
	acl_assert(__sys_pclose);

	__sys_close      = (close_fn) dlsym(RTLD_NEXT, "close");
	acl_assert(__sys_close);

	__sys_mkdir      = (mkdir_fn) dlsym(RTLD_NEXT, "mkdir");
	acl_assert(__sys_mkdir);

	__sys_stat       = (stat_fn) dlsym(RTLD_NEXT, "__xstat");
	acl_assert(__sys_stat);

	__sys_fstat      = (fstat_fn) dlsym(RTLD_NEXT, "__fxstat");
	acl_assert(__sys_fstat);

	__sys_read       = (read_fn) dlsym(RTLD_NEXT, "read");
	acl_assert(__sys_read);

	__sys_readv      = (readv_fn) dlsym(RTLD_NEXT, "readv");
	acl_assert(__sys_readv);

	__sys_recv       = (recv_fn) dlsym(RTLD_NEXT, "recv");
	acl_assert(__sys_recv);

	__sys_recvfrom   = (recvfrom_fn) dlsym(RTLD_NEXT, "recvfrom");
	acl_assert(__sys_recvfrom);

	__sys_recvmsg    = (recvmsg_fn) dlsym(RTLD_NEXT, "recvmsg");
	acl_assert(__sys_recvmsg);

	__sys_write      = (write_fn) dlsym(RTLD_NEXT, "write");
	acl_assert(__sys_write);

	__sys_writev     = (writev_fn) dlsym(RTLD_NEXT, "writev");
	acl_assert(__sys_writev);

	__sys_send       = (send_fn) dlsym(RTLD_NEXT, "send");
	acl_assert(__sys_send);

	__sys_sendto     = (sendto_fn) dlsym(RTLD_NEXT, "sendto");
	acl_assert(__sys_sendto);

	__sys_sendmsg    = (sendmsg_fn) dlsym(RTLD_NEXT, "sendmsg");
	acl_assert(__sys_sendmsg);

#ifndef __USE_FILE_OFFSET64
	__sys_sendfile   = (sendfile_fn) dlsym(RTLD_NEXT, "sendfile");
	acl_assert(__sys_sendfile);
#endif

#ifdef __USE_LARGEFILE64
	__sys_sendfile64 = (sendfile64_fn) dlsym(RTLD_NEXT, "sendfile64");
	acl_assert(__sys_sendfile64);
#endif

	__sys_pread = (pread_fn) dlsym(RTLD_NEXT, "pread");
	acl_assert(__sys_pread);
	__sys_pwrite = (pwrite_fn) dlsym(RTLD_NEXT, "pwrite");
	acl_assert(__sys_pwrite);

	__sys_pread64 = (pread64_fn) dlsym(RTLD_NEXT, "pread64");
	acl_assert(__sys_pread64);
	__sys_pwrite64 = (pwrite64_fn) dlsym(RTLD_NEXT, "pwrite64");
	acl_assert(__sys_pwrite64);

	(void) acl_pthread_mutex_unlock(&__lock);
}
Beispiel #16
0
/* Wait on the condition variable for at most 'ms' milliseconds.
 * The mutex must be locked before entering this function!
 * The mutex is unlocked during the wait, and locked again after the wait.

Typical use:

Thread A:
	pthread_mutex_lock(lock);
	while ( ! condition ) {
		SDL_CondWait(cond);
	}
	pthread_mutex_unlock(lock);

Thread B:
	pthread_mutex_lock(lock);
	...
	condition = true;
	...
	pthread_mutex_unlock(lock);
 */
int acl_pthread_cond_timedwait(acl_pthread_cond_t *cond,
	acl_pthread_mutex_t *mutex, const struct timespec *timeout)
{
	const char *myname = "acl_pthread_cond_timedwait";
	int   retval;
	
	if (cond == NULL) {
		acl_msg_error("%s, %s(%d): input invalid",
			__FILE__, myname, __LINE__);
		return -1;
	}

	/* Obtain the protection mutex, and increment the number of waiters.
	 * This allows the signal mechanism to only perform a signal if there
	 * are waiting threads.
	 */
	acl_pthread_mutex_lock(cond->lock);
	++cond->waiting;
	acl_pthread_mutex_unlock(cond->lock);

	/* Unlock the mutex, as is required by condition variable semantics */
	acl_pthread_mutex_unlock(mutex);

	/* Wait for a signal */
	if (timeout == NULL)
		retval = acl_sem_wait(cond->wait_sem);
	else {
		int ms;
		struct timeval tv;

		gettimeofday(&tv, NULL);
		ms = (int) (timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000);
		ms -= tv.tv_sec * 1000 + tv.tv_usec / 1000;
		if (ms < 0)
			ms = 0;
		retval = acl_sem_wait_timeout(cond->wait_sem, (unsigned int) ms);
	}

	/* Let the signaler know we have completed the wait, otherwise
         * the signaler can race ahead and get the condition semaphore
         * if we are stopped between the mutex unlock and semaphore wait,
         * giving a deadlock.  See the following URL for details:
         * http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
	 */
	acl_pthread_mutex_lock(cond->lock);
	if (cond->signals > 0) {
		/* If we timed out, we need to eat a condition signal */
		if (retval > 0)
			acl_sem_wait(cond->wait_sem);

		/* We always notify the signal thread that we are done */
		acl_sem_post(cond->wait_done);

		/* Signal handshake complete */
		--cond->signals;
	}
	--cond->waiting;
	acl_pthread_mutex_unlock(cond->lock);

	/* Lock the mutex, as is required by condition variable semantics */
	acl_pthread_mutex_lock(mutex);

	return retval;
}