Пример #1
0
SharedJello::~SharedJello(void)
	{
	if(pipe!=0&&!communicationThread.isJoined())
		{
		/* Ask the server to disconnect: */
		{
		Threads::Mutex::Lock pipeLock(pipeMutex);
		writeMessage(DISCONNECT_REQUEST,*pipe);
		pipe->flush();
		}
		
		/* Wait until the communication thread receives the disconnect reply and terminates: */
		communicationThread.join();
		}
	
	/* Close the server pipe: */
	pipe=0;
	
	/* Delete the crystal and renderer triple-buffers: */
	for(int i=0;i<3;++i)
		{
		delete renderers[i];
		delete crystals[i];
		}
	
	/* Delete all atom draggers: */
	for(AtomDraggerList::iterator adIt=atomDraggers.begin();adIt!=atomDraggers.end();++adIt)
		delete *adIt;
	
	/* Delete the user interface: */
	delete mainMenu;
	delete settingsDialog;
	}
Пример #2
0
SharedJello::~SharedJello(void)
	{
	if(pipe!=0)
		{
		{
		/* Ask the server to disconnect: */
		Threads::Mutex::Lock pipeLock(pipe->getMutex());
		pipe->writeMessage(SharedJelloPipe::DISCONNECT_REQUEST);
		pipe->flushWrite();
		pipe->shutdown(false,true);
		}
		}
	
	/* Wait until the communication thread receives the disconnect reply and terminates: */
	communicationThread.join();
	
	/* Close the server pipe: */
	delete pipe;
	
	/* Delete the crystal and renderer triple-buffer: */
	for(int i=0;i<3;++i)
		{
		delete renderers[i];
		delete crystals[i];
		}
	
	/* Delete all atom draggers: */
	for(AtomDraggerList::iterator adIt=atomDraggers.begin();adIt!=atomDraggers.end();++adIt)
		delete *adIt;
	
	/* Delete the user interface: */
	delete mainMenu;
	delete settingsDialog;
	}
Пример #3
0
void SharedJello::sendParamUpdate(void)
	{
	/* Send a parameter state update to the server: */
	Threads::Mutex::Lock pipeLock(pipeMutex);
	
	writeMessage(CLIENT_PARAMUPDATE,*pipe);
	pipe->write<Scalar>(atomMass);
	pipe->write<Scalar>(attenuation);
	pipe->write<Scalar>(gravity);
	
	pipe->flush();
	}
Пример #4
0
void SharedJello::sendParamUpdate(void)
	{
	/* Send a parameter state update to the server: */
	{
	Threads::Mutex::Lock pipeLock(pipe->getMutex());
	pipe->writeMessage(SharedJelloPipe::CLIENT_PARAMUPDATE);
	pipe->write<Scalar>(atomMass);
	pipe->write<Scalar>(attenuation);
	pipe->write<Scalar>(gravity);
	
	pipe->flushWrite();
	}
	}
Пример #5
0
void ProviderAgent::_writeResponse(Message* message)
{
    PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_writeResponse");

    CIMMessage* response = dynamic_cast<CIMMessage*>(message);
    PEGASUS_ASSERT(response != 0);

    //
    // Write the response message to the pipe
    //
    try
    {
        // Use Mutex to prevent concurrent writes to the same pipe
        AutoMutex pipeLock(_pipeToServerMutex);

        AnonymousPipe::Status writeStatus =
            _pipeToServer->writeMessage(response);

        if (writeStatus != AnonymousPipe::STATUS_SUCCESS)
        {
            PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL1,
                "Error writing response to pipe.");
            Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
                MessageLoaderParms(
                    "ProviderManager.ProviderAgent.ProviderAgent."
                        "CIMSERVER_COMMUNICATION_FAILED",
                    "cimprovagt \"$0\" communication with CIM Server failed.  "
                        "Exiting.",
                    _agentId));
            _terminating = true;
        }
    }
    catch (...)
    {
        PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL1,
            "Caught exception while writing response.");
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
            MessageLoaderParms(
                "ProviderManager.ProviderAgent.ProviderAgent."
                    "CIMSERVER_COMMUNICATION_FAILED",
                "cimprovagt \"$0\" communication with CIM Server failed.  "
                    "Exiting.",
                _agentId));
        _terminating = true;
    }

    PEG_METHOD_EXIT();
}
Пример #6
0
void SharedJelloServer::sendServerUpdate(void)
	{
	/* Lock the client state list: */
	Threads::Mutex::Lock clientStateListLock(clientStateListMutex);
	
	/* Go through all client states: */
	for(ClientStateList::iterator cslIt=clientStates.begin();cslIt!=clientStates.end();++cslIt)
		{
		ClientState* cs=*cslIt;
		if(cs->connected)
			{
			try
				{
				Threads::Mutex::Lock pipeLock(cs->pipeMutex);
				
				if(cs->parameterVersion!=parameterVersion)
					{
					/* Send a parameter update message: */
					writeMessage(SERVER_PARAMUPDATE,*cs->pipe);
					cs->pipe->write<Scalar>(crystal.getAtomMass());
					cs->pipe->write<Scalar>(crystal.getAttenuation());
					cs->pipe->write<Scalar>(crystal.getGravity());
					cs->parameterVersion=parameterVersion;
					}
				
				/* Send a server update message: */
				writeMessage(SERVER_UPDATE,*cs->pipe);
				
				/* Send the crystal's state: */
				crystal.writeAtomStates(*cs->pipe);
				
				cs->pipe->flush();
				}
			catch(...)
				{
				/* Ignore write errors; let the client communication thread handle them */
				}
			}
		}
	}
Пример #7
0
void SharedJello::frame(void)
	{
	/* Check if there was a parameter update since the last frame: */
	if(parameterVersion!=newParameterVersion)
		{
		/* Update the settings dialog: */
		updateSettingsDialog();
		parameterVersion=newParameterVersion;
		}
	
	/* Check if there was a server state update since the last frame: */
	if(lockedIndex!=mostRecentIndex)
		{
		/* Deactivate the previously locked crystal state: */
		renderers[lockedIndex]->setActive(false);
		
		/* Lock the most recent crystal state: */
		lockedIndex=mostRecentIndex;
		
		/* Activate the previously locked crystal state: */
		renderers[lockedIndex]->setActive(true);
		}
	
	/* Send a state update to the server: */
	{
	Threads::Mutex::Lock pipeLock(pipe->getMutex());
	pipe->writeMessage(SharedJelloPipe::CLIENT_UPDATE);
	pipe->write<int>(atomDraggers.size());
	for(AtomDraggerList::iterator adIt=atomDraggers.begin();adIt!=atomDraggers.end();++adIt)
		{
		pipe->write<unsigned int>((*adIt)->draggerID);
		pipe->write<int>((*adIt)->draggerRayBased?1:0);
		pipe->writePoint((*adIt)->draggerRay.getOrigin());
		pipe->writeVector((*adIt)->draggerRay.getDirection());
		pipe->writeONTransform((*adIt)->draggerTransformation);
		pipe->write<char>((*adIt)->active?char(1):char(0));
		}
	pipe->flushWrite();
	}
	}
Пример #8
0
void SharedJello::frame(void)
	{
	/* Check if there was a parameter update since the last frame: */
	if(parameterVersion!=newParameterVersion)
		{
		/* Update the settings dialog: */
		updateSettingsDialog();
		parameterVersion=newParameterVersion;
		}
	
	/* Check if there was a server state update since the last frame: */
	if(lockedIndex!=mostRecentIndex)
		{
		/* Deactivate the previously locked crystal state: */
		renderers[lockedIndex]->setActive(false);
		
		/* Lock the most recent crystal state: */
		lockedIndex=mostRecentIndex;
		
		/* Activate the previously locked crystal state: */
		renderers[lockedIndex]->setActive(true);
		}
	
	/* Send a state update to the server: */
	{
	Threads::Mutex::Lock pipeLock(pipeMutex);
	writeMessage(CLIENT_UPDATE,*pipe);
	pipe->write<Card>(atomDraggers.size());
	for(AtomDraggerList::iterator adIt=atomDraggers.begin();adIt!=atomDraggers.end();++adIt)
		{
		pipe->write<Card>((*adIt)->draggerID);
		pipe->write<Byte>((*adIt)->draggerRayBased?1:0);
		write((*adIt)->draggerRay,*pipe);
		write((*adIt)->draggerTransformation,*pipe);
		pipe->write<Byte>((*adIt)->active?1:0);
		}
	pipe->flush();
	}
	}
Пример #9
0
void* SharedJelloServer::clientCommunicationThreadMethod(SharedJelloServer::ClientState* clientState)
	{
	/* Enable immediate cancellation of this thread: */
	Threads::Thread::setCancelState(Threads::Thread::CANCEL_ENABLE);
	// Threads::Thread::setCancelType(Threads::Thread::CANCEL_ASYNCHRONOUS);
	
	Comm::NetPipe& pipe=*(clientState->pipe);
	Threads::Mutex& pipeMutex=clientState->pipeMutex;
	
	try
		{
		/* Connect the client by sending the size of the Jell-O crystal: */
		{
		Threads::Mutex::Lock pipeLock(pipeMutex);
		writeMessage(CONNECT_REPLY,pipe);
		write(crystal.getDomain().min,pipe);
		write(crystal.getDomain().max,pipe);
		Card numAtoms[3];
		for(int i=0;i<3;++i)
			numAtoms[i]=crystal.getNumAtoms()[i];
		pipe.write(numAtoms,3);
		pipe.flush();
		}
		
		/* Mark the client as connected: */
		{
		Threads::Mutex::Lock clientStateListLock(clientStateListMutex);
		clientState->connected=true;
		}
		
		#ifdef VERBOSE
		std::cout<<"SharedJelloServer: Connection to client from host "<<pipe.getPeerHostName()<<", port "<<pipe.getPeerPortId()<<" established"<<std::endl<<std::flush;
		#endif
		
		/* Run the client communication protocol machine: */
		bool goOn=true;
		while(goOn)
			{
			/* Wait for and handle the next message: */
			switch(readMessage(pipe))
				{
				case CLIENT_PARAMUPDATE:
					/* Update the simulation parameter set: */
					{
					Threads::Mutex::Lock parameterLock(parameterMutex);
					++newParameterVersion;
					newAtomMass=pipe.read<Scalar>();
					newAttenuation=pipe.read<Scalar>();
					newGravity=pipe.read<Scalar>();
					}
					break;
				
				case CLIENT_UPDATE:
					{
					/* Lock the next free client update slot: */
					ClientState::StateUpdate& su=clientState->stateUpdates.startNewValue();
					
					/* Process the client update message: */
					unsigned int newNumDraggers=pipe.read<Card>();
					if(newNumDraggers!=su.numDraggers)
						{
						delete[] su.draggerStates;
						su.numDraggers=newNumDraggers;
						su.draggerStates=su.numDraggers!=0?new ClientState::StateUpdate::DraggerState[su.numDraggers]:0;
						}
					
					for(unsigned int draggerIndex=0;draggerIndex<su.numDraggers;++draggerIndex)
						{
						su.draggerStates[draggerIndex].id=pipe.read<Card>();
						su.draggerStates[draggerIndex].rayBased=pipe.read<Byte>()!=0;
						SharedJelloProtocol::read(su.draggerStates[draggerIndex].ray,pipe);
						SharedJelloProtocol::read(su.draggerStates[draggerIndex].transform,pipe);
						su.draggerStates[draggerIndex].active=pipe.read<Byte>()!=0;
						}

					/* Mark the client update slot as most recent: */
					clientState->stateUpdates.postNewValue();
					break;
					}
				
				case DISCONNECT_REQUEST:
					/* Send a disconnect reply: */
					{
					Threads::Mutex::Lock pipeLock(pipeMutex);
					writeMessage(DISCONNECT_REPLY,pipe);
					pipe.flush();
					}
					
					goOn=false;
					
					break;
				
				default:
					Misc::throwStdErr("Protocol error in client communication");
				}
			}
		}
	catch(std::runtime_error err)
		{
		/* Ignore any connection errors; just disconnect the client */
		std::cerr<<"SharedJelloServer: Disconnecting client due to exception "<<err.what()<<std::endl<<std::flush;
		}
	
	/******************************************************************************************
	Disconnect the client by removing it from the list and deleting the client state structure:
	******************************************************************************************/
	
	#ifdef VERBOSE
	std::cout<<"SharedJelloServer: Disconnecting client from host "<<pipe.getPeerHostName()<<", port "<<pipe.getPeerPortId()<<std::endl<<std::flush;
	#endif
	
	{
	/* Lock the client state list: */
	Threads::Mutex::Lock clientStateListLock(clientStateListMutex);
	
	/* Unlock all atoms held by the client: */
	for(ClientState::AtomLockMap::Iterator alIt=clientState->atomLocks.begin();!alIt.isFinished();++alIt)
		crystal.unlockAtom(alIt->getDest().draggedAtom);
	
	/* Find this client's state in the list: */
	ClientStateList::iterator cslIt;
	for(cslIt=clientStates.begin();cslIt!=clientStates.end()&&*cslIt!=clientState;++cslIt)
		;
	
	/* Remove the client state from the list: */
	clientStates.erase(cslIt);
	
	/* Delete the client state object: */
	delete clientState;
	}
	
	return 0;
	}
Пример #10
0
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)
			{
			/* Read the next message from the client: */
			Vrui::VRDevicePipe::MessageIdType message=pipe.readMessage();
			
			/* Handle the message based on the current state: */
			switch(state)
				{
				case START:
					switch(message)
						{
						case Vrui::VRDevicePipe::CONNECT_REQUEST:
							{
							/* Read client's protocol version number: */
							unsigned int clientProtocolVersion=pipe.read<unsigned int>();
							
							/* Lock the pipe for writing: */
							Threads::Mutex::Lock pipeLock(clientData->pipeMutex);
							
							/* Send connect reply message: */
							pipe.writeMessage(Vrui::VRDevicePipe::CONNECT_REPLY);
							if(clientProtocolVersion>Vrui::VRDevicePipe::protocolVersionNumber)
								clientProtocolVersion=Vrui::VRDevicePipe::protocolVersionNumber;
							pipe.write<unsigned int>(clientProtocolVersion);
							
							/* Send server layout: */
							deviceManager->getState().writeLayout(pipe);
							pipe.flush();
							}
							
							/* Go to connected state: */
							state=CONNECTED;
							break;
						
						default:
							state=FINISH;
						}
					break;
				
				case CONNECTED:
					switch(message)
						{
						case Vrui::VRDevicePipe::ACTIVATE_REQUEST:
							{
							/* Lock the client list: */
							Threads::Mutex::Lock clientListLock(clientListMutex);
							
							/* Start VR devices if this is the first active client: */
							if(numActiveClients==0)
								deviceManager->start();
							
							/* Activate the client: */
							clientData->active=true;
							++numActiveClients;
							}
							
							/* Go to active state: */
							state=ACTIVE;
							break;
						
						default:
							state=FINISH;
						}
					break;
				
				case ACTIVE:
					switch(message)
						{
						case Vrui::VRDevicePipe::PACKET_REQUEST:
						case Vrui::VRDevicePipe::STARTSTREAM_REQUEST:
							deviceManager->lockState();
							try
								{
								/* Lock the pipe for writing: */
								Threads::Mutex::Lock pipeLock(clientData->pipeMutex);
								
								if(message==Vrui::VRDevicePipe::STARTSTREAM_REQUEST)
									{
									/* Enable streaming: */
									clientData->streaming=true;
									}
								
								/* Send packet reply message: */
								pipe.writeMessage(Vrui::VRDevicePipe::PACKET_REPLY);
								
								/* Send server state: */
								deviceManager->getState().write(pipe);
								pipe.flush();
								}
							catch(...)
								{
								/* Unlock the device manager's state and throw the exception again: */
								deviceManager->unlockState();
								throw;
								}
							deviceManager->unlockState();
							
							if(message==Vrui::VRDevicePipe::STARTSTREAM_REQUEST)
								state=STREAMING;
							
							break;
						
						case Vrui::VRDevicePipe::DEACTIVATE_REQUEST:
							{
							/* Lock the client list: */
							Threads::Mutex::Lock clientListLock(clientListMutex);
							
							/* Deactivate client: */
							clientData->active=false;
							--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;
				
				case STREAMING:
					switch(message)
						{
						case Vrui::VRDevicePipe::PACKET_REQUEST:
							/* Ignore message: */
							break;
						
						case Vrui::VRDevicePipe::STOPSTREAM_REQUEST:
							{
							/* Lock the pipe for writing: */
							Threads::Mutex::Lock pipeLock(clientData->pipeMutex);
							
							/* Disable streaming: */
							clientData->streaming=false;
							
							/* Send stopstream reply message: */
							pipe.writeMessage(Vrui::VRDevicePipe::STOPSTREAM_REPLY);
							pipe.flush();
							}
							
							/* Go to active state: */
							state=ACTIVE;
							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;
	}