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)); } }
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)); } }
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)); } }
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)); } }
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; } } }
bool fiber::self_killed(void) { ACL_FIBER* curr = acl_fiber_running(); if (curr == NULL) return false; return acl_fiber_killed(curr); }
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; }
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)); } }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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); }; } }
int acl_fiber_self(void) { ACL_FIBER *curr = acl_fiber_running(); return acl_fiber_id(curr); }