static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { const char *myname = "event_enable_write"; EVENT_POLL_THR *event_thr = (EVENT_POLL_THR *) eventp; ACL_EVENT_FDTABLE *fdp; ACL_SOCKET sockfd; sockfd = ACL_VSTREAM_SOCK(stream); fdp = (ACL_EVENT_FDTABLE*) stream->fdp; if (fdp == NULL) { fdp = event_fdtable_alloc(); fdp->listener = 0; fdp->stream = stream; stream->fdp = (void *) fdp; } else if (fdp->flag & EVENT_FDTABLE_FLAG_READ) acl_msg_panic("%s(%d)->%s: fd %d: multiple I/O request", __FILE__, __LINE__, myname, sockfd); else { fdp->listener = 0; fdp->stream = stream; } if (fdp->w_callback != callback || fdp->w_context != context) { fdp->w_callback = callback; fdp->w_context = context; } if (timeout > 0) { fdp->w_timeout = timeout * 1000000; fdp->w_ttl = eventp->present + fdp->w_timeout; } else { fdp->w_ttl = 0; fdp->w_timeout = 0; } if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE) != 0) return; stream->nrefer++; fdp->flag = EVENT_FDTABLE_FLAG_WRITE | EVENT_FDTABLE_FLAG_EXPT; THREAD_LOCK(&event_thr->event.tb_mutex); fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt++] = fdp; event_thr->fds[fdp->fdidx].fd = sockfd; event_thr->fds[fdp->fdidx].events = POLLOUT | POLLHUP | POLLERR; if (eventp->maxfd == ACL_SOCKET_INVALID || eventp->maxfd < sockfd) eventp->maxfd = sockfd; acl_fdmap_add(event_thr->fdmap, sockfd, fdp); THREAD_UNLOCK(&event_thr->event.tb_mutex); if (event_thr->event.blocked && event_thr->event.evdog && event_dog_client(event_thr->event.evdog) != stream) event_dog_notify(event_thr->event.evdog); }
static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp; ACL_EVENT_FDTABLE *fdp = (ACL_EVENT_FDTABLE *) stream->fdp; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(stream); if (fdp == NULL) { fdp = event_fdtable_alloc(); fdp->flag = EVENT_FDTABLE_FLAG_ADD_WRITE | EVENT_FDTABLE_FLAG_EXPT; fdp->stream = stream; acl_ring_append(&ev->fdp_delay_list, &fdp->delay_entry); fdp->flag |= EVENT_FDTABLE_FLAG_DELAY_OPER; stream->fdp = (void *) fdp; /* 添加流关闭时的回调函数 */ acl_vstream_add_close_handle(stream, stream_on_close, eventp); #ifdef USE_FDMAP acl_fdmap_add(ev->fdmap, sockfd, fdp); #endif } else if ((fdp->flag & EVENT_FDTABLE_FLAG_ADD_WRITE)) { goto END; } else if ((fdp->flag & EVENT_FDTABLE_FLAG_DEL_WRITE)) { acl_assert((fdp->flag & EVENT_FDTABLE_FLAG_WRITE)); fdp->flag &= ~EVENT_FDTABLE_FLAG_DEL_WRITE; } else if (!(fdp->flag & EVENT_FDTABLE_FLAG_WRITE)) { fdp->flag |= EVENT_FDTABLE_FLAG_ADD_WRITE; if (!(fdp->flag & EVENT_FDTABLE_FLAG_DELAY_OPER)) { acl_ring_append(&ev->fdp_delay_list, &fdp->delay_entry); fdp->flag |= EVENT_FDTABLE_FLAG_DELAY_OPER; } } END: if (fdp->fdidx == -1) { fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt++] = fdp; } if (eventp->maxfd != ACL_SOCKET_INVALID && eventp->maxfd < sockfd) eventp->maxfd = sockfd; if (fdp->w_callback != callback || fdp->w_context != context) { fdp->w_callback = callback; fdp->w_context = context; } if (timeout > 0) { fdp->w_timeout = timeout * 1000000; fdp->w_ttl = eventp->present + fdp->w_timeout; } else { fdp->w_ttl = 0; fdp->w_timeout = 0; } }
static ACL_EVENT_FDTABLE *read_enable(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { EVENT_POLL *ev = (EVENT_POLL *) eventp; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(stream); ACL_EVENT_FDTABLE *fdp = (ACL_EVENT_FDTABLE *) stream->fdp; if (fdp == NULL) { fdp = event_fdtable_alloc(); fdp->stream = stream; stream->fdp = (void *) fdp; acl_vstream_add_close_handle(stream, stream_on_close, eventp); acl_fdmap_add(ev->fdmap, sockfd, fdp); } if (fdp->fdidx == -1) { fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt++] = fdp; } if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE)) { fdp->flag |= EVENT_FDTABLE_FLAG_READ; ev->fds[fdp->fdidx].events |= POLLIN | POLLHUP | POLLERR; } else { fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT; ev->fds[fdp->fdidx].events = POLLIN | POLLHUP | POLLERR; } ev->fds[fdp->fdidx].fd = sockfd; if (eventp->maxfd != ACL_SOCKET_INVALID && eventp->maxfd < sockfd) eventp->maxfd = sockfd; if (fdp->r_callback != callback || fdp->r_context != context) { fdp->r_callback = callback; fdp->r_context = context; } if (timeout > 0) { fdp->r_timeout = ((acl_int64) timeout) * 1000000; fdp->r_ttl = eventp->present + fdp->r_timeout; } else { fdp->r_ttl = 0; fdp->r_timeout = 0; } return fdp; }
static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { const char *myname = "event_enable_read"; EVENT_KERNEL_THR *event_thr = (EVENT_KERNEL_THR *) eventp; ACL_EVENT_FDTABLE *fdp; ACL_SOCKET sockfd; char ebuf[256]; int err = 0; sockfd = ACL_VSTREAM_SOCK(stream); THREAD_LOCK(&event_thr->event.tb_mutex); /* * Disallow multiple requests on the same file descriptor. * Allow duplicates of the same request. */ fdp = stream->fdp; if (fdp == NULL) fdp = event_fdtable_alloc(); if (fdp == NULL) acl_msg_fatal("%s(%d): alloc fdtable error", __FILE__, __LINE__); if (fdp->flag & EVENT_FDTABLE_FLAG_WRITE) acl_msg_panic("%s(%d)->%s: fd %d: multiple I/O request", __FILE__, __LINE__, myname, sockfd); if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) == 0) { fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT; stream->fdp = (void *) fdp; stream->nrefer++; fdp->stream = stream; fdp->listener = 0; fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt] = fdp; eventp->fdcnt++; if (eventp->maxfd != ACL_SOCKET_INVALID && eventp->maxfd < sockfd) eventp->maxfd = sockfd; #ifdef USE_FDMAP acl_fdmap_add(event_thr->fdmap, sockfd, fdp); #endif EVENT_REG_ADD_READ(err, event_thr->event_fd, sockfd, fdp); if (err < 0) { acl_msg_fatal("%s: %s: %s, err(%d), fd(%d)", myname, EVENT_REG_ADD_TEXT, acl_last_strerror(ebuf, sizeof(ebuf)), err, sockfd); } } if (fdp->r_callback != callback || fdp->r_context != context) { fdp->r_callback = callback; fdp->r_context = context; } if (timeout > 0) { fdp->r_timeout = timeout * 1000000; fdp->r_ttl = eventp->event_present + fdp->r_timeout; } else { fdp->r_ttl = 0; fdp->r_timeout = 0; } THREAD_UNLOCK(&event_thr->event.tb_mutex); /* 主要是为了减少通知次数 */ if (event_thr->event.blocked && event_thr->event.evdog && event_dog_client(event_thr->event.evdog) != stream) event_dog_notify(event_thr->event.evdog); }
static ACL_EVENT_FDTABLE *read_enable(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp; ACL_EVENT_FDTABLE *fdp = (ACL_EVENT_FDTABLE *) stream->fdp; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(stream); if (fdp == NULL) { fdp = event_fdtable_alloc(); fdp->flag = EVENT_FDTABLE_FLAG_ADD_READ | EVENT_FDTABLE_FLAG_EXPT; fdp->stream = stream; acl_ring_append(&ev->fdp_delay_list, &fdp->delay_entry); fdp->flag |= EVENT_FDTABLE_FLAG_DELAY_OPER; stream->fdp = (void *) fdp; /* 添加流关闭时的回调函数 */ acl_vstream_add_close_handle(stream, stream_on_close, eventp); #ifdef USE_FDMAP acl_fdmap_add(ev->fdmap, sockfd, fdp); #endif } else if ((fdp->flag & EVENT_FDTABLE_FLAG_ADD_READ)) { goto END; } else if ((fdp->flag & EVENT_FDTABLE_FLAG_DEL_READ)) { /* 停止禁止读监听过程 */ acl_assert((fdp->flag & EVENT_FDTABLE_FLAG_READ)); /* 重新启用读监听过程, 因为之前的过程是正在拆除读监听过程但 * 还没有正式拆除,所以只需要清除拆除标志位即可 */ fdp->flag &= ~EVENT_FDTABLE_FLAG_DEL_READ; } else if (!(fdp->flag & EVENT_FDTABLE_FLAG_READ)) { fdp->flag |= EVENT_FDTABLE_FLAG_ADD_READ; if (!(fdp->flag & EVENT_FDTABLE_FLAG_DELAY_OPER)) { acl_ring_append(&ev->fdp_delay_list, &fdp->delay_entry); fdp->flag |= EVENT_FDTABLE_FLAG_DELAY_OPER; } } END: if (fdp->fdidx == -1) { fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt++] = fdp; } if (eventp->maxfd != ACL_SOCKET_INVALID && eventp->maxfd < sockfd) eventp->maxfd = sockfd; if (fdp->r_callback != callback || fdp->r_context != context) { fdp->r_callback = callback; fdp->r_context = context; } if (stream->read_ready || ACL_VSTREAM_BFRD_CNT(stream) > 0) eventp->read_ready++; if (timeout > 0) { fdp->r_timeout = ((acl_int64) timeout) * 1000000; fdp->r_ttl = eventp->present + fdp->r_timeout; } else { fdp->r_ttl = 0; fdp->r_timeout = 0; } return fdp; }
static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context) { const char *myname = "event_enable_read"; EVENT_KERNEL_THR *event_thr = (EVENT_KERNEL_THR *) eventp; ACL_EVENT_FDTABLE *fdp; ACL_SOCKET sockfd; int err = 0; sockfd = ACL_VSTREAM_SOCK(stream); fdp = (ACL_EVENT_FDTABLE*) stream->fdp; if (fdp == NULL) { fdp = event_fdtable_alloc(); fdp->listener = 0; fdp->stream = stream; stream->fdp = (void *) fdp; } /* 对同一连接的读写操作禁止同时进行监控 */ else if (fdp->flag & EVENT_FDTABLE_FLAG_WRITE) acl_msg_panic("%s(%d), %s: fd %d: multiple I/O request", __FILE__, __LINE__, myname, sockfd); else { fdp->listener = 0; fdp->stream = stream; } if (fdp->r_callback != callback || fdp->r_context != context) { fdp->r_callback = callback; fdp->r_context = context; } if (timeout > 0) { fdp->r_timeout = ((acl_int64) timeout) * 1000000; fdp->r_ttl = eventp->present + fdp->r_timeout; } else { fdp->r_ttl = 0; fdp->r_timeout = 0; } if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) == 0) { stream->nrefer++; fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT; THREAD_LOCK(&event_thr->event.tb_mutex); fdp->fdidx = eventp->fdcnt; eventp->fdtabs[eventp->fdcnt] = fdp; eventp->fdcnt++; #ifdef USE_FDMAP acl_fdmap_add(event_thr->fdmap, sockfd, fdp); #endif EVENT_REG_ADD_READ(err, event_thr->event_fd, sockfd, fdp); THREAD_UNLOCK(&event_thr->event.tb_mutex); if (err < 0) { acl_msg_fatal("%s: %s: %s, err(%d), fd(%d)", myname, EVENT_REG_ADD_TEXT, acl_last_serror(), err, sockfd); } } /* 主要是为了减少通知次数 */ if (event_thr->event.blocked && event_thr->event.evdog && event_dog_client(event_thr->event.evdog) != stream) event_dog_notify(event_thr->event.evdog); }