コード例 #1
0
ファイル: VRDeviceServer.cpp プロジェクト: jrevote/3DA-Vrui
VRDeviceServer::~VRDeviceServer(void)
	{
	/* Lock client list: */
	{
	Threads::Mutex::Lock clientListLock(clientListMutex);
	
	/* Stop connection initiating thread: */
	listenThread.cancel();
	listenThread.join();
	
	/* Disconnect all clients: */
	deviceManager->lockState();
	for(ClientList::iterator c**t=clientList.begin();c**t!=clientList.end();++c**t)
		{
		/* Stop client communication thread: */
		(*c**t)->communicationThread.cancel();
		(*c**t)->communicationThread.join();
		
		/* Delete client data object (closing TCP socket): */
		delete *c**t;
		}
	deviceManager->unlockState();
	
	/* Stop VR devices: */
	if(numActiveClients>0)
		deviceManager->stop();
	}
	
	/* Disable tracker update notification: */
	deviceManager->disableTrackerUpdateNotification();
	}
コード例 #2
0
void* KinectServer::listeningThreadMethod(void)
{
    Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
    // Threads::Thread::setCancelType(Threads::Thread::CANCEL_ASYNCHRONOUS);

    while(true)
    {
        /* Wait for the next incoming connection: */
        Comm::TCPPipe* newClientSocket=0;
        try
        {
#ifdef VERBOSE
            std::cout<<"KinectServer: Waiting for client connection"<<std::endl<<std::flush;
#endif
            newClientSocket=new Comm::TCPPipe(listeningSocket);
#ifdef VERBOSE
            std::cout<<"KinectServer: Connecting new client from host "<<newClientSocket->getPeerHostName()<<", port "<<newClientSocket->getPeerPortId()<<std::endl<<std::flush;
#endif
        }
        catch(std::runtime_error err)
        {
            std::cerr<<"KinectServer: Caught exception "<<err.what()<<" while waiting for new client connection"<<std::endl;
        }

        try
        {
            /* Send stream initialization states to the new client: */
#ifdef VERBOSE
            std::cout<<"KinectServer: Sending stream headers to new client"<<std::endl<<std::flush;
#endif
            newClientSocket->write<unsigned int>(0x12345678U);
            newClientSocket->write<unsigned int>(numCameras);
            for(unsigned i=0; i<numCameras; ++i)
                cameraStates[i]->writeHeaders(*newClientSocket);
            newClientSocket->flush();

            /* Lock the client list and append the new client: */
#ifdef VERBOSE
            std::cout<<"KinectServer: Adding new client to list of clients"<<std::endl<<std::flush;
#endif
            {
                Threads::Mutex::Lock clientListLock(clientListMutex);
                clients.push_back(newClientSocket);
            }
        }
        catch(std::runtime_error err)
        {
            std::cerr<<"KinectServer: Disconnecting new client due to exception "<<err.what()<<std::endl<<std::flush;
            delete newClientSocket;
        }
        catch(...)
        {
            std::cerr<<"KinectServer: Disconnecting new client due to spurious exception; terminating"<<std::endl<<std::flush;
            delete newClientSocket;
            throw;
        }
    }

    return 0;
}
コード例 #3
0
ファイル: VRDeviceServer.cpp プロジェクト: jrevote/3DA-Vrui
void* VRDeviceServer::listenThreadMethod(void)
	{
	/* Enable immediate cancellation of this thread: */
	Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
	Threads::Thread::setCancelType(Threads::Thread::CANCEL_ASYNCHRONOUS);
	
	while(true)
		{
		/* Wait for the next incoming connection: */
		#ifdef VERBOSE
		printf("VRDeviceServer: Waiting for client connection\n");
		fflush(stdout);
		#endif
		Comm::TCPSocket clientSocket=listenSocket.accept();
		
		/* Connect the new client: */
		#ifdef VERBOSE
		try
			{
			printf("VRDeviceServer: Connecting new client from %s, port %d\n",clientSocket.getPeerHostname().c_str(),clientSocket.getPeerPortId());
			fflush(stdout);
			}
		catch(std::runtime_error error)
			{
			printf("VRDeviceServer: Connecting new client from %s, port %d\n",clientSocket.getPeerAddress().c_str(),clientSocket.getPeerPortId());
			fflush(stdout);
			}
		#endif
		{
		Threads::Mutex::Lock clientListLock(clientListMutex);
		ClientData* newClient=new ClientData(clientSocket);
		clientList.push_back(newClient);
		newClient->communicationThread.start(this,&VRDeviceServer::clientCommunicationThreadMethod,newClient);
		}
		}
	
	return 0;
	}
コード例 #4
0
ファイル: VRDeviceServer.cpp プロジェクト: jrevote/3DA-Vrui
void* VRDeviceServer::clientCommunicationThreadMethod(VRDeviceServer::ClientData* clientData)
	{
	/* Enable immediate cancellation of this thread: */
	Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
	Threads::Thread::setCancelType(Threads::Thread::CANCEL_ASYNCHRONOUS);
	
	Vrui::VRDevicePipe& pipe=clientData->pipe;
	
	enum State
		{
		START,CONNECTED,ACTIVE,STREAMING,FINISH
		};
	
	try
		{
		/* Execute client communication protocol state machine: */
		State state=START; // Current client state
		while(state!=FINISH)
			{
			if(clientData->streaming)
				{
				/* Wait for next tracker update: */
				trackerUpdateCompleteCond.wait();
				
				deviceManager->lockState();
				try
					{
					/* Send packet reply message: */
					pipe.writeMessage(Vrui::VRDevicePipe::PACKET_REPLY);
					
					/* Send server state: */
					pipe.writeState(deviceManager->getState());
					}
				catch(std::runtime_error err)
					{
					/* Unlock the device manager's state and throw the exception again: */
					deviceManager->unlockState();
					throw;
					}
				deviceManager->unlockState();
				
				/* Check for messages: */
				if(pipe.getSocket().waitForData(0,0,false))
					{
					switch(pipe.readMessage())
						{
						case Vrui::VRDevicePipe::PACKET_REQUEST:
							/* Ignore message: */
							break;
						
						case Vrui::VRDevicePipe::STOPSTREAM_REQUEST:
							/* Send stopstream reply message: */
							pipe.writeMessage(Vrui::VRDevicePipe::STOPSTREAM_REPLY);
							
							/* Go to active state: */
							clientData->streaming=false;
							state=ACTIVE;
							break;
						
						default:
							state=FINISH;
						}
					}
				}
			else
				{
				Vrui::VRDevicePipe::MessageIdType message=pipe.readMessage();
				switch(state)
					{
					case START:
						switch(message)
							{
							case Vrui::VRDevicePipe::CONNECT_REQUEST:
								/* Send connect reply message: */
								pipe.writeMessage(Vrui::VRDevicePipe::CONNECT_REPLY);
								
								/* Send server layout: */
								pipe.writeLayout(deviceManager->getState());
								
								/* Go to connected state: */
								state=CONNECTED;
								break;
							
							default:
								state=FINISH;
							}
						break;
					
					case CONNECTED:
						switch(message)
							{
							case Vrui::VRDevicePipe::ACTIVATE_REQUEST:
								{
								Threads::Mutex::Lock clientListLock(clientListMutex);
								
								/* Start VR devices if this is the first active client: */
								if(numActiveClients==0)
									deviceManager->start();
								
								/* Activate client: */
								++numActiveClients;
								}
								clientData->active=true;
								
								/* Go to active state: */
								state=ACTIVE;
								break;
							
							default:
								state=FINISH;
							}
						break;
					
					case ACTIVE:
						switch(message)
							{
							case Vrui::VRDevicePipe::PACKET_REQUEST:
								deviceManager->lockState();
								try
									{
									/* Send packet reply message: */
									pipe.writeMessage(Vrui::VRDevicePipe::PACKET_REPLY);
									
									/* Send server state: */
									pipe.writeState(deviceManager->getState());
									}
								catch(std::runtime_error err)
									{
									/* Unlock the device manager's state and throw the exception again: */
									deviceManager->unlockState();
									throw;
									}
								deviceManager->unlockState();
								break;
							
							case Vrui::VRDevicePipe::STARTSTREAM_REQUEST:
								deviceManager->lockState();
								try
									{
									/* Send packet reply message: */
									pipe.writeMessage(Vrui::VRDevicePipe::PACKET_REPLY);
									
									/* Send server state: */
									pipe.writeState(deviceManager->getState());
									}
								catch(std::runtime_error err)
									{
									/* Unlock the device manager's state and throw the exception again: */
									deviceManager->unlockState();
									throw;
									}
								deviceManager->unlockState();
								
								/* Go to streaming state: */
								clientData->streaming=true;
								state=STREAMING;
								break;
							
							case Vrui::VRDevicePipe::DEACTIVATE_REQUEST:
								/* Deactivate client: */
								clientData->active=false;
								{
								Threads::Mutex::Lock clientListLock(clientListMutex);
								--numActiveClients;
								
								/* Stop VR devices if this was the last active client: */
								if(numActiveClients==0)
									deviceManager->stop();
								}
								
								/* Go to connected state: */
								state=CONNECTED;
								break;
							
							default:
								state=FINISH;
							}
						break;
					
					default:
						/* Just to make g++ happy... */
						;
					}
				}
			}
		}
	catch(std::runtime_error err)
		{
		/* Print error message to stderr, but ignore exception otherwise: */
		fprintf(stderr,"VRDeviceServer: Terminating client connection due to exception\n  %s\n",err.what());
		fflush(stderr);
		}
	catch(...)
		{
		/* Just ignore the exception: */
		fprintf(stderr,"VRDeviceServer: Terminating client connection due to spurious exception\n");
		fflush(stderr);
		}
	
	/* Cleanly deactivate client: */
	{
	Threads::Mutex::Lock clientListLock(clientListMutex);
	if(clientData->streaming)
		{
		/* Leave streaming mode: */
		clientData->streaming=false;
		}
	if(clientData->active)
		{
		/* Deactivate client: */
		clientData->active=false;
		--numActiveClients;
		
		/* Stop VR devices if this was the last active client: */
		if(numActiveClients==0)
			deviceManager->stop();
		}
	
	/* Remove client from list: */
	ClientList::iterator c**t;
	for(c**t=clientList.begin();c**t!=clientList.end()&&*c**t!=clientData;++c**t)
		;
	clientList.erase(c**t);
	
	/* Disconnect client: */
	delete clientData;
	}
	
	/* Terminate: */
	#ifdef VERBOSE
	printf("VRDeviceServer: Disconnected client\n");
	fflush(stdout);
	#endif
	
	return 0;
	}
コード例 #5
0
void* VRDeviceServer::streamingThreadMethod(void)
	{
	/* Enable immediate cancellation of this thread: */
	Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
	Threads::Thread::setCancelType(Threads::Thread::CANCEL_ASYNCHRONOUS);
	
	while(true)
		{
		/* Wait for the next update notification from the device manager: */
		trackerUpdateCompleteCond.wait();
		
		/* Lock client list: */
		{
		Threads::Mutex::Lock clientListLock(clientListMutex);
		
		/* Lock the device manager's current state: */
		deviceManager->lockState();
		
		/* Iterate through all clients in streaming mode: */
		std::vector<ClientList::iterator> deadClients;
		for(ClientList::iterator c**t=clientList.begin();c**t!=clientList.end();++c**t)
			{
			/* Lock the client's pipe: */
			Threads::Mutex::Lock clientPipeLock((*c**t)->pipeMutex);
			
			if((*c**t)->streaming)
				{
				try
					{
					/* Send packet reply message: */
					(*c**t)->pipe.writeMessage(Vrui::VRDevicePipe::PACKET_REPLY);
					
					/* Send server state: */
					deviceManager->getState().write((*c**t)->pipe);
					(*c**t)->pipe.flush();
					}
				catch(std::runtime_error err)
					{
					/* Print error message to stderr and mark client for termination: */
					fprintf(stderr,"VRDeviceServer: Terminating client connection due to exception\n  %s\n",err.what());
					fflush(stderr);
					deadClients.push_back(c**t);
					}
				catch(...)
					{
					/* Print error message to stderr and mark client for termination: */
					fprintf(stderr,"VRDeviceServer: Terminating client connection due to spurious exception\n");
					fflush(stderr);
					deadClients.push_back(c**t);
					}
				}
			}
		
		/* Unlock the device manager's state: */
		deviceManager->unlockState();
		
		/* Disconnect all dead clients: */
		for(std::vector<ClientList::iterator>::iterator dcIt=deadClients.begin();dcIt!=deadClients.end();++dcIt)
			{
			/* Stop client communication thread: */
			(**dcIt)->communicationThread.cancel();
			(**dcIt)->communicationThread.join();
			
			/* Cleanly deactivate client: */
			if((**dcIt)->streaming)
				{
				/* Leave streaming mode: */
				(**dcIt)->streaming=false;
				}
			if((**dcIt)->active)
				{
				/* Deactivate client: */
				(**dcIt)->active=false;
				--numActiveClients;
				
				/* Stop VR devices if this was the last active client: */
				if(numActiveClients==0)
					deviceManager->stop();
				}
			delete **dcIt;
			
			/* Remove client from list: */
			clientList.erase(*dcIt);
			}
		}
		}
	
	return 0;
	}
コード例 #6
0
void* KinectServer::streamingThreadMethod(void)
{
    Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
    Threads::Thread::setCancelType(Threads::Thread::CANCEL_DEFERRED);

#ifdef VERBOSE2
    std::cout<<"Meta frame "<<metaFrameIndex;
#endif

    while(true)
    {
        while(numMissingDepthFrames>0||numMissingColorFrames>0)
        {
            /* Find the next missing frame that has just become available: */
            bool foundFrame=false;
            for(unsigned int i=0; !foundFrame&&i<numCameras; ++i)
            {
                if(!cameraStates[i]->hasSentColorFrame&&cameraStates[i]->colorFrames.lockNewValue())
                {
#ifdef VERBOSE2
                    std::cout<<" color "<<i<<", "<<cameraStates[i]->colorFrames.getLockedValue().index<<", "<<cameraStates[i]->colorFrames.getLockedValue().timeStamp<<';';
#endif

                    /* Send the camera's new color frame to all connected clients: */
                    {
                        Threads::Mutex::Lock clientListLock(clientListMutex);
                        unsigned int numClients=clients.size();
                        for(unsigned int j=0; j<numClients; ++j)
                        {
                            try
                            {
                                if(clients[j]->waitForData(Misc::Time(0,0)))
                                {
                                    /* Read the disconnect request: */
                                    clients[j]->read<unsigned int>();

                                    /* Disconnect the client: */
#ifdef VERBOSE
                                    std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<std::endl;
#endif
                                    delete clients[j];
                                    clients.erase(clients.begin()+j);
                                    --numClients;
                                    --j;
                                }
                                else
                                {
#ifdef VVERBOSE
                                    std::cout<<metaFrameIndex<<", "<<i*2+0<<", "<<cameraStates[i]->colorFrames.getLockedValue().timeStamp<<std::endl;
#endif

                                    /* Write the meta frame index and frame identifier: */
                                    clients[j]->write<unsigned int>(metaFrameIndex);
                                    clients[j]->write<unsigned int>(i*2+0);

                                    /* Write the compressed color frame: */
                                    cameraStates[i]->colorFrames.getLockedValue().data.writeToSink(*clients[j]);
                                    clients[j]->flush();
                                }
                            }
                            catch(std::runtime_error err)
                            {
                                std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<" due to exception "<<err.what()<<std::endl;
                                delete clients[j];
                                clients.erase(clients.begin()+j);
                                --numClients;
                                --j;
                            }
                            catch(...)
                            {
                                std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<" due to spurious exception; terminating"<<std::endl;
                                delete clients[j];
                                clients.erase(clients.begin()+j);
                                --numClients;
                                --j;
                                throw;
                            }
                        }
                    }

                    cameraStates[i]->hasSentColorFrame=true;
                    --numMissingColorFrames;
                    foundFrame=true;
                }
                if(!cameraStates[i]->hasSentDepthFrame&&cameraStates[i]->depthFrames.lockNewValue())
                {
#ifdef VERBOSE2
                    std::cout<<" depth "<<i<<", "<<cameraStates[i]->depthFrames.getLockedValue().index<<", "<<cameraStates[i]->depthFrames.getLockedValue().timeStamp<<';';
#endif

                    /* Send the camera's new depth frame to all connected clients: */
                    {
                        Threads::Mutex::Lock clientListLock(clientListMutex);
                        unsigned int numClients=clients.size();
                        for(unsigned int j=0; j<numClients; ++j)
                        {
                            try
                            {
                                /* Check if the client sent a disconnect request: */
                                if(clients[j]->waitForData(Misc::Time(0,0)))
                                {
                                    /* Read the disconnect request: */
                                    clients[j]->read<unsigned int>();

                                    /* Disconnect the client: */
#ifdef VERBOSE
                                    std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<std::endl;
#endif
                                    delete clients[j];
                                    clients.erase(clients.begin()+j);
                                    --numClients;
                                    --j;
                                }
                                else
                                {
#ifdef VVERBOSE
                                    std::cout<<metaFrameIndex<<", "<<i*2+1<<", "<<cameraStates[i]->depthFrames.getLockedValue().timeStamp<<std::endl;
#endif

                                    /* Write the meta frame index and frame identifier: */
                                    clients[j]->write<unsigned int>(metaFrameIndex);
                                    clients[j]->write<unsigned int>(i*2+1);

                                    /* Write the compressed depth frame: */
                                    cameraStates[i]->depthFrames.getLockedValue().data.writeToSink(*clients[j]);
                                    clients[j]->flush();
                                }
                            }
                            catch(std::runtime_error err)
                            {
                                std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<" due to exception "<<err.what()<<std::endl;
                                delete clients[j];
                                clients.erase(clients.begin()+j);
                                --numClients;
                                --j;
                            }
                            catch(...)
                            {
                                std::cerr<<"Disconnecting client from "<<clients[j]->getPeerHostName()<<", port "<<clients[j]->getPeerPortId()<<" due to spurious exception; terminating"<<std::endl;
                                delete clients[j];
                                clients.erase(clients.begin()+j);
                                --numClients;
                                --j;
                                throw;
                            }
                        }
                    }

                    cameraStates[i]->hasSentDepthFrame=true;
                    --numMissingDepthFrames;
                    foundFrame=true;
                }
            }
            if(!foundFrame)
            {
                /* No frames ready; sleep until something becomes available: */
                newFrameCond.wait();
            }
        }

        /* Start a new meta-frame: */
        ++metaFrameIndex;
        for(unsigned int i=0; i<numCameras; ++i)
        {
            cameraStates[i]->hasSentColorFrame=false;
            cameraStates[i]->hasSentDepthFrame=false;
        }
        numMissingColorFrames=numCameras;
        numMissingDepthFrames=numCameras;

#ifdef VERBOSE2
        std::cout<<std::endl;
        std::cout<<"Meta frame "<<metaFrameIndex;
#endif
    }

    return 0;
}