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(!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; }
static inline int stream_socket_post_recv(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_read(h)){ if(0 != kn_enable_read(s->e,h)) return -1; } kn_list_pushback(&s->pending_recv,(kn_list_node*)req); return 0; }
//用于已连接的数据报协议或流协议 static int32_t kn_stream_raw_recv(kn_datasocket* d,st_io *io_req,uint32_t *err_code) { int32_t ret; *err_code = 0; ret = TEMP_FAILURE_RETRY(readv(d->base.fd,io_req->iovec,io_req->iovec_count)); if(ret < 0) { *err_code = errno; if(*err_code == EAGAIN) { d->flag &= (~readable); //将请求重新放回到队列 kn_list_pushback(&d->pending_recv,(kn_list_node*)io_req); } } return ret; }
static inline int write_nobuff(kn_msgque* msgque,struct msg *msg){ int ret = 0; errno = 0; kn_mutex_lock(msgque->mtx); do{ kn_list_pushback(&msgque->shareque,(kn_list_node*)msg); if(msgque->closing){ errno = MSGQUE_CLOSE; ret = -1; break; } //检查是否有wait的线程 kn_msgque_reader_t reader = (kn_msgque_reader_t)kn_dlist_pop(&msgque->waits); if(reader) kn_condition_signal(reader->cond); }while(0); kn_mutex_unlock(msgque->mtx); return ret; }
int kn_chrdev_read(handle_t h,st_io *req){ if(((handle_t)h)->type != KN_CHRDEV) return -1; if(((handle_t)h)->status == KN_CHRDEV_RELEASE) return -1; kn_chr_dev *r = (kn_chr_dev*)h; if(!(r->events & EPOLLIN)){ int ret = 0; if(r->events == 0){ ret = kn_event_add(r->e,(handle_t)r,EPOLLIN); }else ret = kn_event_mod(r->e,(handle_t)r,EPOLLIN); if(ret == 0) r->events = EPOLLIN; else return -1; } kn_list_pushback(&r->pending_read,(kn_list_node*)req); return 0; }
static int32_t kn_dgram_raw_send(kn_datasocket* d,st_io *io_req,uint32_t *err_code) { int32_t ret; int family = d->addr_local.addrtype; PREPARE_MSG(d->connected,msg,family,io_req); *err_code = 0; ret = TEMP_FAILURE_RETRY(sendmsg(d->base.fd,&msg,0)); if(ret < 0) { *err_code = errno; if(*err_code == EAGAIN) { d->flag &= (~writeable); //将请求重新放回到队列 kn_list_pushback(&d->pending_send,(kn_list_node*)io_req); } } return ret; }
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; } }