static thread_func_t tcp_register_server_thread(void* s)
{
	char buffer[NL_BUFFER_SIZE+1];
	server_game* g = (server_game*)s;

	lock_w(&game_server_array);
	rAdd(&game_server_array, (void*)g);
	lock_uw(&game_server_array);

	LOG("New server added: %s.", g->name);

	/* Let every client aware of the new server. */
	broadcast_new_server(g);
	
	/* We do not have anything to share with the server.
	 * So we do a tcp_rcv, and we know that is unlocks only when
	 * the server leaves. */
	nl_tcp_rcv(buffer, g->socket);

	/* Close the server socket */
	close(g->socket);
	
	/* Let every client aware of the gone server. */
	broadcast_delete_server(g);
	
	lock_w(&game_server_array);
	rDelete(&game_server_array, (void*)g, NULL);
	lock_uw(&game_server_array);
	
	delete_game_server((void*)g);
	
	LOG("Server thread terminated.");
	
	thread_exit();
}
static thread_func_t tcp_register_client_thread(void* s)
{
	char buffer[NL_BUFFER_SIZE+1];
	server_game* g;
	client* c = (client*)s;
	void* remember = NULL;

	/* Then, we add the client to the array, such that he will
	* be informed whenever a new server arrives or leaves. */
	lock_w(&client_array);
	rAdd(&client_array, (void*)c);	
	lock_uw(&client_array);
	
	/* We now give him the preliminary information, list all the 
	 * servers already present. */
	lock_r(&game_server_array);
	nl_tcp_sndInt(game_server_array.length, c->socket);

	if((g = (server_game*)rGet(&game_server_array, FIRST, &remember)) != NULL)
	{
		do
		{
			nl_tcp_snd(g->name, c->socket);  /* Send the server's name */
			nl_snd_addr(g->addr, c->socket); /* And now it's address. */
		}
		while((g = (server_game*)rGet(&game_server_array, NEXT, &remember)) != NULL);
	}

	lock_ur(&game_server_array);
	
	/* 
	 * Done. We can now communicate.
	 * Actually we do not have much to say to each other.
	 * This is just a little trick to just wait, and then the 
	 * client leaves, this will exit.
	 */
	nl_tcp_rcv(buffer, c->socket);
	
	/* Close the client socket 
	 * If it has been closed from extern, don't try to close it again! */
	close(c->socket);
	
	lock_w(&client_array);
	rDelete(&client_array, (void*)c, NULL);
	delete_client((void*)c);
	lock_uw(&client_array);
	
	LOG("Client thread terminated.");
	
	thread_exit();
}
示例#3
0
    Lock::TempRelease::~TempRelease() {
        if( cant )
            return;

        LockState& ls = lockState();
        dassert( ls.recursive == 0 );
        DESTRUCTOR_GUARD( 
            fassert(0, ls.threadState == 't' || ls.threadState == 0);
            ls.threadState = 0;
            switch( type ) {
            case 'W':
                lock_W();
                break;
            case 'R':        
                lock_R();
                break;
            case 'w':
                if( local ) 
                    localDBLock.lock();
                else
                    ls.otherLock->lock();
                lock_w();
                break;
            case 'r':
                if( local ) 
                    localDBLock.lock_shared();
                else
                    ls.otherLock->lock_shared();
                lock_r();
                break;
            default:
                wassert(false);
            }
        )
    }
	static void draw_player(void *ptr, void *unused)
	{
		(void)unused;

		cpShape* shape = (cpShape*)ptr;
		chipmunk_data* p = (chipmunk_data*)shape->data;
	
		//chipmunk_lock_data(p);

		if(p == NULL || p->del)
		{
			/* We test if the player is marked for deletation.
			 * If so, we add it to the array of players ready to be deleted,
			 * which will be purged by another thread to prevent concurrence
			 * problems. */		
			lock_w(&to_remove_array);
			lAdd(&to_remove_array, (void*)shape);
			lock_uw(&to_remove_array);
		}
		else
		{
			p->px = (mFloat)shape->body->p.x;
			p->py = (mFloat)shape->body->p.y;
			p->an = (mFloat)shape->body->a;

			p->vx = (mFloat)shape->body->v.x;
			p->vy = (mFloat)shape->body->v.y;
			p->av = (mFloat)shape->body->w;

			/*p->ax = (mFloat)shape->body->f.x * shape->body->m_inv;
			p->ay = (mFloat)shape->body->f.y * shape->body->m_inv;
			p->aa = (mFloat)shape->body->t;*/
			/* Acceleration already defined in physics.c/update_keys */
		}

		//chipmunk_unlock_data(p);
	}
static void quit(void)
{
	void* remember;
	
	client* c;
	server_game* g;
	
	int port = NL_REGISTER_PORT;
	int web_port = NL_REGISTER_WEB_PORT;

	if(exit_time)
		return;
		
	write_config();
	
	exit_time = 1;

	/* We close everyone's socket, such that every thread
	 * closes tighly. */
	
	lock_r(&client_array);

	if((c = (client*)rGet(&client_array, FIRST, &remember)) != NULL)
	{
		do
		{
			/* This unlocks the server's recv call, who will close
			 * his socket, and therefore unlock our call to recv as well,
			 * letting the thread terminate. */
			nl_tcp_snd("X", c->socket);
		}
		while((c = (client*)rGet(&client_array, NEXT, &remember)) != NULL);
	}
	
	lock_ur(&client_array);	
	lock_r(&game_server_array);

	if((g = (server_game*)rGet(&game_server_array, FIRST, &remember)) != NULL)
	{
		do
		{
			/* This unlocks the server's recv call, who will close
			 * his socket, and therefore unlock our call to recv as well,
			 * letting the thread terminate. */
			nl_tcp_snd("X", g->socket);
		}
		while((g = (server_game*)rGet(&game_server_array, NEXT, &remember)) != NULL);
	}

	lock_ur(&game_server_array);

	/* Now every thread should be terminated.
	 * The list should be empty. Let's simply destroy the lists. */
	lock_w(&game_server_array);
	rDestroy(&game_server_array, delete_game_server);
	rFree(&game_server_array);

	lock_w(&client_array);
	rDestroy(&client_array, delete_client);
	rFree(&client_array);
	
	nl_release_tcp_network(&port, "N");

	LOG("The end.");
	
	nl_release_tcp_network(&web_port, NULL);
	thread_wait(web_t);
	
	common_finish();
	destroy_lang();
	
	exit(0);
}