LWP_CreateThread counterpart to stop thread execution?

Post Reply
todd
Posts: 2
Joined: Fri Jun 10, 2011 8:03 am

LWP_CreateThread counterpart to stop thread execution?

Post by todd » Fri Jun 10, 2011 8:19 am

I'm writing an ftp server and I've run into a problem. If the client waits too long between messages, I want to end the connection. As of now my program is set up like this:

Main thread (for controller input) spawns a server thread
Server thread listens for new connections and spawns threads for new clients
Client threads run net_read() in a loop, which blocks until data is received

Since net_read() blocks, I can't tell from within the client threads if I should end the connection until more data comes in so it unblocks, which could be never. So my solution was to create a watchdog thread that will periodically check to see when the last time data was received in each child thread, and if it was more than X minutes ago, net_close() the socket and "delete" the thread. But I can't seem to find a function to completely get rid of the thread, only to suspend it, unless it exits on its own accord.

Is there such a function? If not, what would be the most elegant solution?

rodries
Posts: 2
Joined: Mon Jun 13, 2011 8:18 am

Re: LWP_CreateThread counterpart to stop thread execution?

Post by rodries » Mon Jun 13, 2011 8:19 am

You have to make the socket nonblocking

Here's the connection code from libtinysmb (smb.c) which should help.

Code: Select all

static s32 do_netconnect(SMBHANDLE *handle)
{
	u32 set = 1;
	s32 ret;
	s32 sock;
	u64 t1,t2;

	handle->sck_server = INVALID_SOCKET;
	/*** Create the global net_socket ***/
	sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if(sock==INVALID_SOCKET) return -1;

	// Switch off Nagle with TCP_NODELAY
	net_setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,&set,sizeof(set));

	// create non blocking socket
	ret = net_ioctl(sock, FIONBIO, &set);
	if (ret < 0)
	{
		net_close(sock);
		return ret;
	}

	t1=ticks_to_millisecs(gettime());
	while(1)
	{
		ret = net_connect(sock,(struct sockaddr*)&handle->server_addr,sizeof(handle->server_addr));
		if(ret==-EISCONN) break;
		t2=ticks_to_millisecs(gettime());
		usleep(1000);
		if((t2-t1) > CONN_TIMEOUT) break; // usually not more than 90ms
	}

	if(ret!=-EISCONN)
	{
		net_close(sock);
		return -1;
	}

	handle->sck_server = sock;
	return 0;
}
and the read data function which implements a timeout

Code: Select all

/**
 * smb_recv
 *
 * blocking call with timeout
 * will return when ANY data has been read from socket. Number of bytes read is returned.
 * OR timeout. Timeout will return -1
 * OR network error. -ve value will be returned
 */
static s32 smb_recv(s32 s,void *mem,s32 len)
{
	s32 ret,read,readtotal=0;
	u64 t1,t2;

	t1=ticks_to_millisecs(gettime());
	while(len > 0)
	{
		read=len;
		if(read>SMB_MAX_NET_READ_SIZE)
			read=SMB_MAX_NET_READ_SIZE; // optimized value

		ret=net_recv(s,mem+readtotal,read,0);
		if(ret>0)
		{
			readtotal+=ret;
			len-=ret;
			if(len==0) return readtotal;
		}
		else
		{
			if(ret!=-EAGAIN) return ret;
			t2=ticks_to_millisecs(gettime());
			if( (t2 - t1) > RECV_TIMEOUT) return -1;
		}
		usleep(1000);
	}
	return readtotal;
}

todd
Posts: 2
Joined: Fri Jun 10, 2011 8:03 am

Re: LWP_CreateThread counterpart to stop thread execution?

Post by todd » Mon Jun 13, 2011 8:32 pm

Awesome! I'll be sure to give this a try but it will take some work rewriting to use non-blocking sockets. I just wish there was some better documentation for libogc so I could've found out about this myself a few days ago.

Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests