int kn_msgque_read(kn_msgque_reader_t reader, void **msg,int ms){ errno = 0; struct msg *m = NULL; *msg = NULL; int ret = 0; kn_msgque* msgque = reader->msgque; m = (struct msg*)kn_list_pop(&reader->readbuff); if(m){ *msg = m->data; free(m); return ret; } kn_mutex_lock(msgque->mtx); do{ if(msgque->closing){ ret = -1; errno = MSGQUE_CLOSE; break; } if(_wait(reader,ms)){ m = (struct msg*)kn_list_pop(&reader->readbuff); *msg = m->data; free(m); }else if(msgque->closing){ ret = -1; errno = MSGQUE_CLOSE; } }while(0); kn_mutex_unlock(msgque->mtx); return ret; }
static void destroy_chrdev(kn_chr_dev *r){ printf("destroy_chrdev\n"); st_io *io_req; if(r->destry_stio){ while((io_req = (st_io*)kn_list_pop(&r->pending_write))!=NULL) r->destry_stio(io_req); while((io_req = (st_io*)kn_list_pop(&r->pending_read))!=NULL) r->destry_stio(io_req); } free(r); }
void kn_datasocket_destroy(void *ptr){ printf("kn_datasocket_destroy,%x\n",(int)ptr); kn_datasocket *t = (kn_datasocket *)((char*)ptr - sizeof(kn_dlist_node)); st_io *io_req; close(t->base.fd); if(t->destroy_stio){ while((io_req = (st_io*)kn_list_pop(&t->pending_send))!=NULL) t->destroy_stio(io_req); while((io_req = (st_io*)kn_list_pop(&t->pending_recv))!=NULL) t->destroy_stio(io_req); } free(t); }
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); } }
void kn_close_writer(kn_msgque_writer_t writer){ struct msg *m; while((m = (struct msg*)kn_list_pop(&writer->writebuff)) != NULL){ if(m->fn_destroy) m->fn_destroy(m->data); free(m); } refobj_dec((refobj*)writer->msgque); free(writer); }
static void msgque_destructor(void *ptr){ kn_msgque* msgque = (kn_msgque*)ptr; struct msg *m; while((m = (struct msg*)kn_list_pop(&msgque->shareque)) != NULL){ if(m->fn_destroy) m->fn_destroy(m->data); free(m); } kn_mutex_destroy(msgque->mtx); free(ptr); }
void kn_close_reader(kn_msgque_reader_t reader){ struct msg *m; while((m = (struct msg*)kn_list_pop(&reader->readbuff)) != NULL){ if(m->fn_destroy) m->fn_destroy(m->data); free(m); } refobj_dec((refobj*)reader->msgque); kn_condition_destroy(reader->cond); free(reader); }
static void on_destroy(void *_){ kn_socket *s = (kn_socket*)_; st_io *io_req; if(s->clear_func){ while((io_req = (st_io*)kn_list_pop(&s->pending_send))!=NULL) s->clear_func(io_req); while((io_req = (st_io*)kn_list_pop(&s->pending_recv))!=NULL) s->clear_func(io_req); } kn_stream_socket *ss = (kn_stream_socket*)_; if(ss->ctx){ SSL_CTX_free(ss->ctx); } if(ss->ssl){ if(s->comm_head.status == SOCKET_ESTABLISH) SSL_shutdown(ss->ssl); SSL_free(ss->ssl); } if(s->e){ kn_event_del(s->e,(handle_t)s); } close(s->comm_head.fd); free(s); }
static inline void _send(kn_datasocket* t) { st_io* io_req = 0; uint32_t err_code = 0; int32_t bytes_transfer; if(t->flag & writeable) { if((io_req = (st_io*)kn_list_pop(&t->pending_send))!=NULL) { bytes_transfer = t->raw_send(t,io_req,&err_code); //if(bytes_transfer == 0) bytes_transfer = -1; if(err_code != EAGAIN) t->cb_transfer((kn_fd_t)t,io_req,bytes_transfer,err_code); } } }
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; } }