예제 #1
0
파일: threads.c 프로젝트: MattTuttle/neko
EXTERN void neko_thread_blocking( thread_main_func f, void *p ) {
#	if !defined(NEKO_THREADS)
	f(p); // nothing
#	elif defined(NEKO_WINDOWS)
	f(p); // we don't have pthreads issues
#	else
	// we have different APIs depending on the GC version, make sure we load
	// the good one at runtime
	static callb_func do_blocking = NULL;
	static std_func start = NULL, end = NULL;
	if( do_blocking )
		do_blocking(f,p);
	else if( start ) {
		start();
		f(p);
		end();
	} else {
		void *self = dlopen(NULL,0);
		do_blocking = (callb_func)dlsym(self,"GC_do_blocking");
		if( !do_blocking ) {
			start = (std_func)dlsym(self,"GC_start_blocking");
			end = (std_func)dlsym(self,"GC_end_blocking");
			if( !start || !end )
				val_throw(alloc_string("Could not init GC blocking API"));
		}
		neko_thread_blocking(f,p);
	}
#	endif
}
예제 #2
0
파일: socket.c 프로젝트: motion-twin/neko
/**
	socket_recv : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Read up to [len] bytes from [buf] starting at [pos] from a connected socket.
	Return the number of bytes readed.</doc>
**/
static value socket_recv( value o, value data, value pos, value len ) {
	int p,l,dlen,ret;
	int retry = 0;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_again);
		return block_error();
	}
	return alloc_int(ret);
}
예제 #3
0
파일: socket.c 프로젝트: motion-twin/neko
/**
	socket_recv_from : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Read data from an unconnected UDP socket, store the address from which we received data in addr.
	</doc>
**/
static value socket_recv_from( value o, value data, value pos, value len, value addr ) {
	int p,l,dlen,ret;
	int retry = 0;
	struct sockaddr_in saddr;
	int slen = sizeof(saddr);
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(addr,object);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_from_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recvfrom(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_from_again);
#ifdef	NEKO_WINDOWS
		if( WSAGetLastError() == WSAECONNRESET )
			ret = 0;
		else
#endif
		return block_error();
	}
	alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr));
	alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port)));
	return alloc_int(ret);
}
예제 #4
0
파일: socket.c 프로젝트: motion-twin/neko
/**
	socket_recv_char : 'socket -> int
	<doc>Read a single char from a connected socket.</doc>
**/
static value socket_recv_char( value o ) {
	int ret;
	int retry = 0;
	unsigned char cc;
	val_check_kind(o,k_socket);
	POSIX_LABEL(recv_char_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = (char*)&cc;
		t.size = 1;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o),&cc,1,MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_char_again);
		return block_error();
	}
	if( ret == 0 )
		neko_error();
	return alloc_int(cc);
}