static inline int _wait(kn_msgque_reader_t reader,int ms){ kn_msgque* msgque = reader->msgque; if(ms > 0){ uint32_t timeout = kn_systemms() + (uint32_t)ms; kn_dlist_push(&msgque->waits,(kn_dlist_node*)reader); while(kn_list_size(&msgque->shareque) == 0 && !msgque->closing){ uint32_t now = kn_systemms(); uint32_t sleepms = timeout > now ? timeout - now : 0; if(!sleepms) break; if(0 != kn_condition_timedwait(reader->cond,msgque->mtx,(int32_t)sleepms)){ break; } } kn_dlist_remove((kn_dlist_node*)reader); }else if(ms < 0){ //无限等待 kn_dlist_push(&msgque->waits,(kn_dlist_node*)reader); while(kn_list_size(&msgque->shareque) == 0 && !msgque->closing){ if(0 != kn_condition_wait(reader->cond,msgque->mtx)) break; } kn_dlist_remove((kn_dlist_node*)reader); kn_list_swap(&reader->readbuff,&msgque->shareque); }else{ //不等待 kn_list_swap(&reader->readbuff,&msgque->shareque); } return kn_list_size(&reader->readbuff); }
static inline int datagam_socket_send(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(h->status != SOCKET_DATAGRAM){ return -1; } if(0 != kn_list_size(&s->pending_send)) return kn_sock_post_recv(h,req); struct msghdr _msghdr = { .msg_name = &req->addr, .msg_namelen = sizeof(req->addr), .msg_iov = req->iovec, .msg_iovlen = req->iovec_count, .msg_flags = 0, .msg_control = NULL, .msg_controllen = 0 }; return TEMP_FAILURE_RETRY(sendmsg(s->comm_head.fd,&_msghdr,0)); } int kn_sock_send(handle_t h,st_io *req){ if(h->type != KN_SOCKET){ return -1; } if(((kn_socket*)h)->type == SOCK_STREAM) return stream_socket_send(h,req); else if(((kn_socket*)h)->type == SOCK_DGRAM) return datagam_socket_send(h,req); else return -1; } static inline int stream_socket_recv(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(!s->e || h->status != SOCKET_ESTABLISH){ return -1; } if(0 != kn_list_size(&s->pending_recv)) return kn_sock_post_recv(h,req); int bytes_transfer = 0; if(((kn_stream_socket*)s)->ssl){ bytes_transfer = TEMP_FAILURE_RETRY(SSL_read(((kn_stream_socket*)s)->ssl,req->iovec[0].iov_base,req->iovec[0].iov_len)); int ssl_error = SSL_get_error(((kn_stream_socket*)s)->ssl,bytes_transfer); if(bytes_transfer < 0 && (ssl_error == SSL_ERROR_WANT_WRITE || ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_X509_LOOKUP)){ errno = EAGAIN; } } else bytes_transfer = TEMP_FAILURE_RETRY(readv(h->fd,req->iovec,req->iovec_count)); if(bytes_transfer < 0 && errno == EAGAIN) return kn_sock_post_recv(h,req); return bytes_transfer > 0 ? bytes_transfer:-1; }
int8_t kn_datasocket_process(kn_fd_t s) { kn_datasocket* t = (kn_datasocket *)s; kn_ref_acquire(&s->ref);//防止s在_recv/_send中回调cb_transfer时被释放 _recv(t); _send(t); int32_t read_active = (t->flag & readable) && kn_list_size(&t->pending_recv); int32_t write_active = (t->flag & writeable)&& kn_list_size(&t->pending_send); kn_ref_release(&s->ref); return (read_active || write_active); }
static inline int stream_socket_send(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(!s->e || h->status != SOCKET_ESTABLISH){ return -1; } if(0 != kn_list_size(&s->pending_send)) return kn_sock_post_send(h,req); int bytes_transfer = 0; if(((kn_stream_socket*)s)->ssl){ assert(req->iovec_count == 1); if(req->iovec_count != 1) return -1; bytes_transfer = TEMP_FAILURE_RETRY(SSL_write(((kn_stream_socket*)s)->ssl,req->iovec[0].iov_base,req->iovec[0].iov_len)); int ssl_error = SSL_get_error(((kn_stream_socket*)s)->ssl,bytes_transfer); if(bytes_transfer < 0 && (ssl_error == SSL_ERROR_WANT_WRITE || ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_X509_LOOKUP)){ errno = EAGAIN; } } else bytes_transfer = TEMP_FAILURE_RETRY(writev(h->fd,req->iovec,req->iovec_count)); if(bytes_transfer < 0 && errno == EAGAIN) return kn_sock_post_send(h,req); return bytes_transfer > 0 ? bytes_transfer:-1; }
static void process_read(kn_socket *s){ st_io* io_req = 0; int bytes_transfer = 0; s->flag |= READABLE; if((io_req = (st_io*)kn_list_pop(&s->pending_recv))!=NULL){ errno = 0; if(((kn_stream_socket*)s)->ssl){ bytes_transfer = TEMP_FAILURE_RETRY(SSL_read(((kn_stream_socket*)s)->ssl,io_req->iovec[0].iov_base,io_req->iovec[0].iov_len)); int ssl_error = SSL_get_error(((kn_stream_socket*)s)->ssl,bytes_transfer); if(bytes_transfer < 0 && (ssl_error == SSL_ERROR_WANT_WRITE || ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_X509_LOOKUP)){ errno = EAGAIN; } } else bytes_transfer = TEMP_FAILURE_RETRY(readv(s->comm_head.fd,io_req->iovec,io_req->iovec_count)); s->callback((handle_t)s,io_req,bytes_transfer,errno); if(s->comm_head.status == SOCKET_CLOSE) return; } if(!kn_list_size(&s->pending_recv)){ //没有接收请求了,取消EPOLLIN kn_disable_read(s->e,(handle_t)s); } }
static inline int write_buff(kn_msgque_writer_t writer,struct msg *msg){ //先写入本线程缓存 int ret = 0; kn_list_pushback(&writer->writebuff,(kn_list_node*)msg); if(kn_list_size(&writer->writebuff) >= writer->buffsize){ ret = msgque_flush(writer); } return ret; }
static inline int datagam_socket_recv(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(!s->e || h->status != SOCKET_DATAGRAM){ return -1; } if(0 != kn_list_size(&s->pending_recv)) return kn_sock_post_recv(h,req); struct msghdr _msghdr = { .msg_name = &req->addr, .msg_namelen = sizeof(req->addr), .msg_iov = req->iovec, .msg_iovlen = req->iovec_count, .msg_flags = 0, .msg_control = NULL, .msg_controllen = 0 }; req->recvflags = 0; int bytes_transfer = TEMP_FAILURE_RETRY(recvmsg(s->comm_head.fd,&_msghdr,0)); req->recvflags = _msghdr.msg_flags; if(bytes_transfer < 0 && errno == EAGAIN) return kn_sock_post_recv(h,req); return bytes_transfer > 0 ? bytes_transfer:-1; } int kn_sock_recv(handle_t h,st_io *req){ if(h->type != KN_SOCKET){ return -1; } if(((kn_socket*)h)->type == SOCK_STREAM) return stream_socket_recv(h,req); else if(((kn_socket*)h)->type == SOCK_DGRAM) return datagam_socket_recv(h,req); else return -1; } static inline int stream_socket_post_send(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; if(!s->e || h->status != SOCKET_ESTABLISH){ return -1; } if(((kn_stream_socket*)s)->ssl){ assert(req->iovec_count == 1); if(req->iovec_count != 1) return -1; } if(!is_set_write(h)){ if(0 != kn_enable_write(s->e,h)) return -1; } kn_list_pushback(&s->pending_send,(kn_list_node*)req); return 0; }
void kn_datasocket_on_active(kn_fd_t s,int event){ kn_datasocket* t = (kn_datasocket*)s; char buf[1]; if(event & (EPOLLERR | EPOLLHUP)){ kn_ref_acquire(&s->ref);//防止s在cb_transfer中被释放 errno = 0; read(s->fd,buf,1);//触发errno变更 t->cb_transfer(s,NULL,-1,errno); kn_ref_release(&s->ref); return; } if(event & (EPOLLRDHUP | EPOLLIN)){ t->flag |= readable; if(kn_list_size(&t->pending_recv)) kn_procator_putin_active(s->proactor,s); } if(event & EPOLLOUT){ t->flag |= writeable; if(kn_list_size(&t->pending_send)) kn_procator_putin_active(s->proactor,s); } }
static void process_write(kn_chr_dev *r){ st_io* io_req = 0; int bytes_transfer = 0; int total_transfer = 0; while(total_transfer < 65535 && (io_req = (st_io*)kn_list_pop(&r->pending_write))!=NULL){ errno = 0; bytes_transfer = TEMP_FAILURE_RETRY(writev(r->comm_head.fd,io_req->iovec,io_req->iovec_count)); if(bytes_transfer < 0 && errno == EAGAIN){ //将请求重新放回到队列 kn_list_pushback(&r->pending_write,(kn_list_node*)io_req); break; }else{ r->cb_ontranfnish((handle_t)r,io_req,bytes_transfer,errno); if(r->comm_head.status == KN_CHRDEV_RELEASE) return; } } if(kn_list_size(&r->pending_write) == 0){ //没有接收请求了,取消EPOLLOUT int events = r->events ^ EPOLLOUT; if(0 == kn_event_mod(r->e,(handle_t)r,events)) r->events = events; } }