Ejemplo n.º 1
0
/**
	socket_select : read : 'socket array -> write : 'socket array -> others : 'socket array -> timeout:number? -> 'socket array array
	<doc>Perform the [select] operation. Timeout is in seconds or [null] if infinite</doc>
**/
static value socket_select( value rs, value ws, value es, value timeout ) {
	struct timeval tval;
	struct timeval *tt;
	SOCKET n = 0;
	fd_set rx, wx, ex;
	fd_set *ra, *wa, *ea;
	value r;
	POSIX_LABEL(select_again);
	ra = make_socket_array(rs,val_array_size(rs),&rx,&n);
	wa = make_socket_array(ws,val_array_size(ws),&wx,&n);
	ea = make_socket_array(es,val_array_size(es),&ex,&n);
	if( ra == &INVALID || wa == &INVALID || ea == &INVALID )
		neko_error();
	if( val_is_null(timeout) )
		tt = NULL;
	else {
		val_check(timeout,number);
		tt = &tval;
		init_timeval(val_number(timeout),tt);
	}
	if( select((int)(n+1),ra,wa,ea,tt) == SOCKET_ERROR ) {
		HANDLE_EINTR(select_again);
		neko_error();
	}
	r = alloc_array(3);
	val_array_ptr(r)[0] = make_array_result(rs,ra);
	val_array_ptr(r)[1] = make_array_result(ws,wa);
	val_array_ptr(r)[2] = make_array_result(es,ea);
	return r;
}
Ejemplo n.º 2
0
/**
	socket_select : read : 'socket array -> write : 'socket array -> others : 'socket array -> timeout:number? -> 'socket array array
	<doc>Perform the [select] operation. Timeout is in seconds or [null] if infinite</doc>
**/
static value socket_select( value rs, value ws, value es, value timeout ) {
	struct timeval tval;
	struct timeval *tt;
	SOCKET n = 0;
	fd_set rx, wx, ex;
	fd_set *ra, *wa, *ea;
	value r;
	POSIX_LABEL(select_again);
	ra = make_socket_array(rs,&rx,&n);
	wa = make_socket_array(ws,&wx,&n);
	ea = make_socket_array(es,&ex,&n);
	if( ra == &INVALID || wa == &INVALID || ea == &INVALID )
	{
		val_throw( alloc_string("No valid sockets") );
		return alloc_null();
	}
	if( val_is_null(timeout) )
		tt = NULL;
	else {
		val_check(timeout,number);
		tt = &tval;
		init_timeval(val_number(timeout),tt);
	}
	gc_enter_blocking();
	if( select((int)(n+1),ra,wa,ea,tt) == SOCKET_ERROR ) {
		HANDLE_EINTR(select_again);
		gc_exit_blocking();
		char buf[100];
		sprintf(buf,"Select error %d", errno );
		val_throw( alloc_string(buf) );
	}
	gc_exit_blocking();
	r = alloc_array(3);
	val_array_set_i(r,0,make_array_result(rs,ra));
	val_array_set_i(r,1,make_array_result(ws,wa));
	val_array_set_i(r,2,make_array_result(es,ea));
	return r;
}
Ejemplo n.º 3
0
/**
	socket_epoll_wait : 'epoll -> int -> float -> int array
	<doc>Wait and return a list of socket fds with events.</doc>
**/
static value socket_epoll_wait(value e, value timeout) {
	epolldata *ep;
#ifndef HAS_EPOLL
	struct timeval t;
	SOCKET n = 0;
	bool indefinite;
	fd_set rx, wx;
	fd_set *ra, *wa;
	int i;
	int pos = 0;
	val_check_kind(e,k_epoll);
	ep = val_epoll(e);
	POSIX_LABEL(select_again);
	ra = ep->rcount == 0 ? NULL : make_socket_array(ep->read, ep->rcount, &rx, &n);
	wa = ep->wcount == 0 ? NULL : make_socket_array(ep->write, ep->wcount, &wx, &n);
	indefinite = val_is_null(timeout);
	if (!indefinite) {
		val_check(timeout,number);
		init_timeval(val_number(timeout),&t);
	}
	if( select((int)(n+1),ra,wa,NULL,indefinite ? NULL : &t) == SOCKET_ERROR ) {
		HANDLE_EINTR(select_again);
		val_throw(alloc_int(errno));
	}
	if (ra != NULL) {
		for (i=0; i < ep->rcount && pos < ep->maxevents; i++) {
			value s = val_array_ptr(ep->read)[i];
			if (FD_ISSET(val_sock(s),ra))
				val_array_ptr(ep->result)[pos++] = alloc_int(val_sock(s));
		}
	}
	if (wa != NULL) {
		for (i=0; i < ep->wcount && pos < ep->maxevents; i++) {
			value s = val_array_ptr(ep->write)[i];
			if (FD_ISSET(val_sock(s),wa))
				val_array_ptr(ep->result)[pos++] = alloc_int(val_sock(s));
		}
	}
	val_set_size(ep->result,pos);
	return ep->result;
#else
	int t;
	val_check_kind(e,k_epoll);
	ep = val_epoll(e);
	if (val_is_null(timeout))
		t = -1;
	else {
		val_check(timeout,number);
		t = (int)(val_number(timeout)) * 1000;
	}
	int ret = epoll_wait(ep->epollfd, ep->events, ep->maxevents, t);
	if (ret == -1)
		val_throw(alloc_int(errno));
	val_set_size(ep->result, ret);
	int i;
	for (i = 0; i < ret; i++) {
		val_array_ptr(ep->result)[i] = alloc_int(ep->events[i].data.fd);
	}
	return ep->result;
#endif
}