Simple Threading

Hello,

I’ve delved into threads. I’m using enet for networking and I want to hand off the connected peer to a new thread, so I’ll have a thread for each connected player.

My problem is, when I start a thread with joinable=false, it still blocks the main thread. If I try yield, either forced or suggested, I don’t get any joy. If I sleep, the main thread comes back alive but I get the opposite problem, in that my thread doesn’t seem to catch any events and the main thread catches them instead (I enabled the receive events in the main thread to test this btw). Also I don’t really want to sleep for a second or more, I was just looking for a worker thread.

Here’s what I’m doing:

AsyncTask::DoneStatus NetworkServer::ReaderPolling(GenericAsyncTask* task, void* data)
{
	NetworkServer* server = static_cast<NetworkServer*>(data);
	/* Wait up to 0 milliseconds for an event. */
	while (enet_host_service(server->server_, server->event_, 0) > 0)
	{
		switch (server->event_->type)
		{
		case ENET_EVENT_TYPE_RECEIVE:
			printf("NetworkServer::ReaderPolling Received\n");
			break;

	/*	case ENET_EVENT_TYPE_DISCONNECT:
			printf ("NetworkServer::ReaderPolling %s disconnected.\n",
                          server->event_->peer->data);
			break;*/

		case ENET_EVENT_TYPE_CONNECT:
			printf("A new client connected\n");  //new thread to listen and receive
			Logger::Instance()->WriteFile(" NetworkServer::ReaderPolling A new client connected\n");
			ConnectedThread* thread = new ConnectedThread("threadName","syncName",server->server_, server->event_);
			thread->start(ThreadPriority::TP_high,false);
			break;
		}
	}
	return AsyncTask::DS_cont;
}

And ConnectedThread is:

void ConnectedThread::thread_main()
{
	printf("ConnectedThread::thread_main()\n");
	Logger::Instance()->WriteFile("ConnectedThread::thread_main()\n");
	//taskManager_->add(threadReaderPolling_);
	ENetEvent* event = new ENetEvent();
	Server* state = new Server();

	while(1)
	{
		force_yield();
	//	sleep(1);

		while (enet_host_service(host_, event, 0) > 0)
		{
			switch (event->type)
			{
		
			case ENET_EVENT_TYPE_RECEIVE:
				printf("ConnectedThread::thread_main ENET_EVENT_TYPE_RECEIVE\n");
				Logger::Instance()->WriteFile("ConnectedThread::thread_main ENET_EVENT_TYPE_RECEIVE\n");
				state->ReceiveData(event);
				break;
	       
			case ENET_EVENT_TYPE_DISCONNECT:
				printf("ConnectedThread::thread_main ENET_EVENT_TYPE_DISCONNECT\n");
				Logger::Instance()->WriteFile("ConnectedThread::thread_main ENET_EVENT_TYPE_DISCONNECT\n");
				return;

			}
		}

	}
}

I’m not sure tasks are suited to what I want to do, since they’re static and have to be created statically. Whereas I was looking at threading each connection, to do that with tasks I’d have to init X number of tasks.

Looking at this again it seems the thread is not blocking. I logged my asynctask in the main thread as it ran and I can see it’s polling alternately with my connectedthread. Though the behaviour is unexpected - I’d expect the main thread to catch the CONNECT event but it only does this for the first connection, then the connectedthread catches everything which is odd.

Sleeping at the correct moment seemed to fix it, but it seems very fragile (and the sleep is too long), so back to the drawing board.