Example #1
0
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);	
}
Example #2
0
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;		
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
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);
	}	
}
Example #6
0
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;
}
Example #7
0
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;	
}
Example #8
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);
	}
}
Example #9
0
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;
	}		
}