Exemple #1
0
/**
	socket_poll_events : 'poll -> timeout:float -> void
	<doc>
	Update the read/write flags arrays that were created with [socket_poll_prepare].
	</doc>
**/
static value socket_poll_events( value pdata, value timeout ) {
	polldata *p;
#	ifdef NEKO_WINDOWS
	unsigned int i;
	int k = 0;
	struct timeval t;
	val_check_kind(pdata,k_poll);
	p = val_poll(pdata);
	memcpy(p->outr,p->fdr,FDSIZE(p->fdr->fd_count));
	memcpy(p->outw,p->fdw,FDSIZE(p->fdw->fd_count));
	val_check(timeout,number);
	init_timeval(val_number(timeout),&t);
	gc_enter_blocking();
	if( p->fdr->fd_count + p->fdw->fd_count != 0 && select(0,p->outr,p->outw,NULL,&t) == SOCKET_ERROR )
	{
		gc_exit_blocking();
		return alloc_null();
	}
	gc_exit_blocking();
	k = 0;
	for(i=0;i<p->fdr->fd_count;i++)
		if( FD_ISSET(p->fdr->fd_array[i],p->outr) )
			val_array_set_i(p->ridx,k++,alloc_int(i));
	val_array_set_i(p->ridx,k,alloc_int(-1));
	k = 0;
	for(i=0;i<p->fdw->fd_count;i++)
		if( FD_ISSET(p->fdw->fd_array[i],p->outw) )
			val_array_set_i(p->widx,k++, alloc_int(i));
	val_array_set_i(p->widx,k,alloc_int(-1));
#else
	int i,k;
	int tot;
	val_check_kind(pdata,k_poll);
	val_check(timeout,number);
	p = val_poll(pdata);
	tot = p->rcount + p->wcount;
	gc_enter_blocking();
	POSIX_LABEL(poll_events_again);
	if( poll(p->fds,tot,(int)(val_number(timeout) * 1000)) < 0 ) {
		HANDLE_EINTR(poll_events_again);
		gc_exit_blocking();
		return alloc_null();
	}
	gc_exit_blocking();
	k = 0;
	for(i=0;i<p->rcount;i++)
		if( p->fds[i].revents & (POLLIN|POLLHUP) )
			val_array_set_i(p->ridx,k++,alloc_int(i));
	val_array_set_i(p->ridx,k, alloc_int(-1));
	k = 0;
	for(;i<tot;i++)
		if( p->fds[i].revents & (POLLOUT|POLLHUP) )
			val_array_set_i(p->widx,k++, alloc_int(i - p->rcount));
	val_array_set_i(p->widx,k, alloc_int(-1));
#endif
	return val_null;
}
Exemple #2
0
/**
	socket_poll_prepare : 'poll -> read:'socket array -> write:'socket array -> int array array
	<doc>
	Prepare a poll for scanning events on sets of sockets.
	</doc>
**/
static value socket_poll_prepare( value pdata, value rsocks, value wsocks ) {
	polldata *p;
	int i,len;
	val_check(rsocks,array);
	val_check(wsocks,array);
	val_check_kind(pdata,k_poll);
	p = val_poll(pdata);
	len = val_array_size(rsocks);
	if( len + val_array_size(wsocks) > p->max )
		val_throw(alloc_string("Too many sockets in poll"));
#	ifdef NEKO_WINDOWS
	for(i=0;i<len;i++) {
		value s = val_array_ptr(rsocks)[i];
		val_check_kind(s,k_socket);
		p->fdr->fd_array[i] = val_sock(s);
	}
	p->fdr->fd_count = len;
	len = val_array_size(wsocks);
	for(i=0;i<len;i++) {
		value s = val_array_ptr(wsocks)[i];
		val_check_kind(s,k_socket);
		p->fdw->fd_array[i] = val_sock(s);
	}
	p->fdw->fd_count = len;
#	else
	for(i=0;i<len;i++) {
		value s = val_array_ptr(rsocks)[i];
		val_check_kind(s,k_socket);
		p->fds[i].fd = val_sock(s);
		p->fds[i].events = POLLIN;
		p->fds[i].revents = 0;
	}
	p->rcount = len;
	len = val_array_size(wsocks);
	for(i=0;i<len;i++) {
		int k = i + p->rcount;
		value s = val_array_ptr(wsocks)[i];
		val_check_kind(s,k_socket);
		p->fds[k].fd = val_sock(s);
		p->fds[k].events = POLLOUT;
		p->fds[k].revents = 0;
	}
	p->wcount = len;
#	endif
	{
		value a = alloc_array(2);
		val_array_ptr(a)[0] = p->ridx;
		val_array_ptr(a)[1] = p->widx;
		return a;
	}
}
Exemple #3
0
/**
	socket_poll : 'socket array -> 'poll -> timeout:float -> 'socket array
	<doc>
	Perform a polling for data available over a given set of sockets. This is similar to [socket_select]
	except that [socket_select] is limited to a given number of simultaneous sockets to check.
	</doc>
**/
static value socket_poll( value socks, value pdata, value timeout ) {
	polldata *p;
	value a;
	int i, rcount = 0;
	if( val_is_null( socket_poll_prepare(pdata,socks,alloc_array(0))) )
		return alloc_null();
	socket_poll_events(pdata,timeout);
	p = val_poll(pdata);
	while( val_int(val_array_i(p->ridx,rcount)) != -1 )
		rcount++;
	a = alloc_array(rcount);
	for(i=0;i<rcount;i++)
		val_array_set_i(a,i, val_array_i(socks,val_int(val_array_i(p->ridx,i))));
	return a;
}
Exemple #4
0
/**
	socket_poll : 'socket array -> 'poll -> timeout:float -> 'socket array
	<doc>
	Perform a polling for data available over a given set of sockets. This is similar to [socket_select]
	except that [socket_select] is limited to a given number of simultaneous sockets to check.
	</doc>
**/
static value socket_poll( value socks, value pdata, value timeout ) {
	polldata *p;
	value a;
	int i, rcount = 0;
	if( socket_poll_prepare(pdata,socks,alloc_array(0)) == NULL )
		neko_error();
	if( socket_poll_events(pdata,timeout) == NULL )
		neko_error();
	p = val_poll(pdata);
	while( val_array_ptr(p->ridx)[rcount] != alloc_int(-1) )
		rcount++;
	a = alloc_array(rcount);
	for(i=0;i<rcount;i++)
		val_array_ptr(a)[i] = val_array_ptr(socks)[val_int(val_array_ptr(p->ridx)[i])];
	return a;
}