Example #1
0
inline ssize_t fiber_sendto(int sockfd, const void *buf, size_t len, int flags,
	const struct sockaddr *dest_addr, socklen_t addrlen)
{
	ACL_FIBER *me;

	while (1) {
		ssize_t n = __sys_sendto(sockfd, buf, len, flags,
				dest_addr, addrlen);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_write(sockfd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%d is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Example #2
0
inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt)
{
	ACL_FIBER *me;

	if (__sys_readv == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_readv(fd, iov, iovcnt);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_read(fd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Example #3
0
inline ssize_t fiber_write(int fd, const void *buf, size_t count)
{
	ACL_FIBER *me;

	while (1) {
		ssize_t n = __sys_write(fd, buf, count);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_write(fd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%d is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Example #4
0
inline ssize_t fiber_recv(int sockfd, void *buf, size_t len, int flags)
{
	ACL_FIBER *me;

	if (__sys_recv == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_recv(sockfd, buf, len, flags);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_read(sockfd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Example #5
0
ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset, size_t count)
{
	ACL_FIBER *me;

	if (__sys_sendfile64 == NULL)
		hook_io();

	while (1) {
		ssize_t n = __sys_sendfile64(out_fd, in_fd, offset, count);
		if (!acl_var_hook_sys_api || n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_write(out_fd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me)) {
			acl_msg_info("%s(%d), %s: fiber-%u is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
			return -1;
		}
	}
}
Example #6
0
bool fiber::self_killed(void)
{
	ACL_FIBER* curr = acl_fiber_running();
	if (curr == NULL)
		return false;
	return acl_fiber_killed(curr);
}
Example #7
0
int acl_fiber_sem_wait(ACL_FIBER_SEM *sem)
{
	ACL_FIBER *curr;

	if (sem->tid != acl_pthread_self())
		return -1;

	if (sem->num > 0) {
		sem->num--;
		return sem->num;
	}

	curr = acl_fiber_running();
	if (curr == NULL)
		return -1;

	acl_ring_prepend(&sem->waiting, &curr->me);
	acl_fiber_switch();

	/* if switch to me because other killed me, I should detach myself;
	 * else if because other unlock, I'll be detached twice which is
	 * hamless because ACL_RING can deal with it.
	 */
	acl_ring_detach(&curr->me);

	return sem->num;
}
Example #8
0
inline ssize_t fiber_sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
	ACL_FIBER *me;

	while (1) {
		ssize_t n = __sys_sendmsg(sockfd, msg, flags);

		if (!acl_var_hook_sys_api)
			return n;

		if (n >= 0)
			return n;

		fiber_save_errno();

#if EAGAIN == EWOULDBLOCK
		if (errno != EAGAIN)
#else
		if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
			return -1;

		fiber_wait_write(sockfd);

		me = acl_fiber_running();
		if (acl_fiber_killed(me))
			acl_msg_info("%s(%d), %s: fiber-%d is existing",
				__FILE__, __LINE__, __FUNCTION__,
				acl_fiber_id(me));
	}
}
Example #9
0
static int __wlock(ACL_FIBER_RWLOCK *lk, int block)
{
	ACL_FIBER *curr;

	if (lk->writer == NULL && lk->readers == 0) {
		lk->writer = acl_fiber_running();
		return 1;
	}

	if (!block)
		return 0;

	curr = acl_fiber_running();
	acl_ring_prepend(&lk->wwaiting, &curr->me);
	acl_fiber_switch();

	/* if switch to me because other killed me, I should detach myself */
	acl_ring_detach(&curr->me);

	return 1;
}
Example #10
0
fiber::fiber(bool running /* = false */)
{
	if (running)
	{
		f_ = acl_fiber_running();
		if (f_ == NULL)
			acl_msg_fatal("%s(%d), %s: current fiber not running!",
				__FILE__, __LINE__, __FUNCTION__);
	}
	else
		f_ = NULL;
}
Example #11
0
static int __lock(ACL_FIBER_MUTEX *lk, int block)
{
	ACL_FIBER *curr = acl_fiber_running();

	if (lk->owner == NULL) {
		lk->owner = acl_fiber_running();
		acl_ring_prepend(&curr->holding, &lk->me);
		return 0;
	}

	// xxx: no support recursion lock
	assert(lk->owner != curr);

	if (!block)
		return -1;

	acl_ring_prepend(&lk->waiting, &curr->me);
	curr->waiting = lk;

	acl_fiber_switch();

	/* if switch to me because other killed me, I should detach myself;
	 * else if because other unlock, I'll be detached twice which is
	 * hamless because ACL_RING can deal with it.
	 */
	acl_ring_detach(&curr->me);

	if (lk->owner == curr)
		return 0;

	if (acl_fiber_killed(curr))
		acl_msg_info("%s(%d), %s: lock fiber-%u was killed",
			__FILE__, __LINE__, __FUNCTION__, acl_fiber_id(curr));
	else
		acl_msg_warn("%s(%d), %s: qlock: owner=%p self=%p oops",
			__FILE__, __LINE__, __FUNCTION__, lk->owner, curr);

	return 0;
}
Example #12
0
inline ssize_t fiber_recvfrom(int sockfd, void *buf, size_t len, int flags,
	struct sockaddr *src_addr, socklen_t *addrlen)
{
	ssize_t ret;
	EVENT  *ev;
	ACL_FIBER *me;

	if (sockfd < 0) {
		acl_msg_error("%s: invalid sockfd: %d", __FUNCTION__, sockfd);
		return -1;
	}

	if (!acl_var_hook_sys_api) {
		if (__sys_recvfrom == NULL)
			hook_io();

		return __sys_recvfrom(sockfd, buf, len,
				flags, src_addr, addrlen);
	}

	ev = fiber_io_event();
	if (ev && event_readable(ev, sockfd)) {
		event_clear_readable(ev, sockfd);

		ret = __sys_recvfrom(sockfd, buf, len,
				flags, src_addr, addrlen);
		if (ret < 0)
			fiber_save_errno();
		return ret;
	}

	fiber_wait_read(sockfd);
	if (ev)
		event_clear_readable(ev, sockfd);

	ret = __sys_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
	if (ret >= 0)
		return ret;

	fiber_save_errno();

	me = acl_fiber_running();
	if (acl_fiber_killed(me)) {
		acl_msg_info("%s(%d), %s: fiber-%u is existing",
			__FILE__, __LINE__, __FUNCTION__, acl_fiber_id(me));
		return -1;
	}

	return ret;
}
Example #13
0
inline ssize_t fiber_recvmsg(int sockfd, struct msghdr *msg, int flags)
{
	ssize_t ret;
	EVENT  *ev;
	ACL_FIBER *me;

	if (sockfd < 0) {
		acl_msg_error("%s: invalid sockfd: %d", __FUNCTION__, sockfd);
		return -1;
	}

	if (!acl_var_hook_sys_api) {
		if (__sys_recvmsg == NULL)
			hook_io();

		return __sys_recvmsg(sockfd, msg, flags);
	}

	ev = fiber_io_event();
	if (ev && event_readable(ev, sockfd)) {
		event_clear_readable(ev, sockfd);

		ret = __sys_recvmsg(sockfd, msg, flags);
		if (ret < 0)
			fiber_save_errno();
		return ret;
	}

	fiber_wait_read(sockfd);
	if (ev)
		event_clear_readable(ev, sockfd);

	ret = __sys_recvmsg(sockfd, msg, flags);
	if (ret >= 0)
		return ret;

	fiber_save_errno();

	me = acl_fiber_running();
	if (acl_fiber_killed(me))
		acl_msg_info("%s(%d), %s: fiber-%u is existing",
			__FILE__, __LINE__, __FUNCTION__, acl_fiber_id(me));

	return ret;
}
Example #14
0
inline ssize_t fiber_readv(int fd, const struct iovec *iov, int iovcnt)
{
	ssize_t ret;
	EVENT  *ev;
	ACL_FIBER *me;

	if (fd < 0) {
		acl_msg_error("%s: invalid fd: %d", __FUNCTION__, fd);
		return -1;
	}

	if (!acl_var_hook_sys_api) {
		if (__sys_readv == NULL)
			hook_io();

		return __sys_readv(fd, iov, iovcnt);
	}

	ev = fiber_io_event();
	if (ev && event_readable(ev, fd)) {
		event_clear_readable(ev, fd);

		ret = __sys_readv(fd, iov, iovcnt);
		if (ret < 0)
			fiber_save_errno();
		return ret;
	}

	fiber_wait_read(fd);
	if (ev)
		event_clear_readable(ev, fd);

	ret = __sys_readv(fd, iov, iovcnt);
	if (ret >= 0)
		return ret;

	fiber_save_errno();

	me = acl_fiber_running();
	if (acl_fiber_killed(me))
		acl_msg_info("%s(%d), %s: fiber-%u is existing",
			__FILE__, __LINE__, __FUNCTION__, acl_fiber_id(me));

	return ret;
}
Example #15
0
void acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *lk)
{
	ACL_FIBER *ready, *curr = acl_fiber_running();
	
	if (lk->owner == NULL)
		acl_msg_fatal("%s(%d), %s: qunlock: owner NULL",
			__FILE__, __LINE__, __FUNCTION__);
	if (lk->owner != curr)
		acl_msg_fatal("%s(%d), %s: invalid owner=%p, %p",
			__FILE__, __LINE__, __FUNCTION__, lk->owner, curr);

	acl_ring_detach(&lk->me);
	ready = FIRST_FIBER(&lk->waiting);

	if ((lk->owner = ready) != NULL) {
		acl_ring_detach(&ready->me);
		acl_fiber_ready(ready);
	}
}
Example #16
0
inline ssize_t fiber_read(int fd, void *buf, size_t count)
{
	ssize_t ret;
	EVENT  *ev;
	ACL_FIBER *me;

	if (fd < 0) {
		acl_msg_error("%s: invalid fd: %d", __FUNCTION__, fd);
		return -1;
	}

	if (!acl_var_hook_sys_api)
		return __sys_read(fd, buf, count);

	ev = fiber_io_event();
	if (ev && event_readable(ev, fd)) {
		event_clear_readable(ev, fd);

		ret = __sys_read(fd, buf, count);
		if (ret < 0)
			fiber_save_errno();
		return ret;
	}

	fiber_wait_read(fd);
	if (ev)
		event_clear_readable(ev, fd);

	ret = __sys_read(fd, buf, count);
	if (ret >= 0)
		return ret;

	fiber_save_errno();

	me = acl_fiber_running();
	if (acl_fiber_killed(me))
		acl_msg_info("%s(%d), %s: fiber-%d is existing",
			__FILE__, __LINE__, __FUNCTION__, acl_fiber_id(me));

	return ret;
}
Example #17
0
static void fiber_accept(acl::server_socket& ss)
{
    __fiber_accept = acl_fiber_running();

    while (true)
    {
        // 等待接收客户端连接
        acl::socket_stream* conn = ss.accept();
        if (conn == NULL)
        {
            printf("accept error %s\r\n", acl::last_serror());
            break;
        }

        // 创建处理客户端对象的协程
        go_stack(STACK_SIZE) [=] {
            __nclients++;
            fiber_client(conn);
        };
    }
}
Example #18
0
int acl_fiber_self(void)
{
	ACL_FIBER *curr = acl_fiber_running();
	return acl_fiber_id(curr);
}