From: <he...@us...> - 2009-10-31 09:39:50
|
Revision: 96 http://simspark.svn.sourceforge.net/simspark/?rev=96&view=rev Author: hedayat Date: 2009-10-31 09:39:27 +0000 (Sat, 31 Oct 2009) Log Message: ----------- Add SO_REUSEADDR option to the Socket class and use it in simspark Send senses after receiving action commands from the agents Modified Paths: -------------- trunk/spark/ChangeLog trunk/spark/RELEASE trunk/spark/lib/oxygen/simulationserver/agentcontrol.cpp trunk/spark/lib/oxygen/simulationserver/agentcontrol.h trunk/spark/lib/oxygen/simulationserver/netcontrol.cpp trunk/spark/lib/oxygen/simulationserver/simulationserver.cpp trunk/spark/lib/oxygen/simulationserver/simulationserver.h trunk/spark/utility/rcssnet/socket.cpp trunk/spark/utility/rcssnet/socket.hpp Modified: trunk/spark/ChangeLog =================================================================== --- trunk/spark/ChangeLog 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/ChangeLog 2009-10-31 09:39:27 UTC (rev 96) @@ -1,3 +1,24 @@ +2009-10-31 Hedayat Vatankhah <he...@gr...> + + * lib/oxygen/simulationserver/simulationserver.h: + * lib/oxygen/simulationserver/simulationserver.cpp: + - prevent a deadlock case (on exit) in multi-threaded mode + + * lib/oxygen/simulationserver/agentcontrol.h: + * lib/oxygen/simulationserver/agentcontrol.cpp: + - send senses in SenseAgent method, so that they'll be sent after receiving + commands from the agents. this will ensure that any commands sent after + sending senses will be executed in the next cycle, which results in a + more deterministic behaviour + +2009-10-30 Hedayat Vatankhah <he...@gr...> + + * lib/oxygen/simulationserver/netcontrol.cpp (NetControl::InitSimulation): + - try to set REUSEADDR flag to reuse local addresses. + + * utility/rcssnet/socket.cpp (Socket::setReuseAddr): + - added the new function + 2009-08-25 Marian Buchta <mar...@gm...> * plugin/openglsyswx/CMakeLists.txt: Modified: trunk/spark/RELEASE =================================================================== --- trunk/spark/RELEASE 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/RELEASE 2009-10-31 09:39:27 UTC (rev 96) @@ -1,15 +1,17 @@ -RELEASE News of simspark-0.1.2 +RELEASE News of simspark-0.1.3 (in progress) -This release brings some bugfixes, better performance and also better Windows -support. A Windows installer will be available too. This is the first version -which runs in multi-threaded mode by default. The multi-threaded mode is still -in early stages, and it can be improved cosiderably in future. +SOME INTERESTING COMMENTS! Main changes of this release are: - - improved Windows support, including Windows Installer. - - Multi-threaded mode now works, and is the default mode when running simspark - - Performance improvements - - Fixed a bug in networking code, which were introduced in 0.1.1 + - Compilation fixes + - Improved Windows support + - Simspark should always accept connections. No more "Connection refused" + messages and the need to wait for simspark's network port to be freed! + - Simspark will now collect received commands right before sending + sense data of the last cycle. So, any commands which is sent by agents + after receiving new sense data will be executed in the next cycle, not the + current one. This results in a more deterministic behavior, and agents' + efficiency should not change between remote and local runs considerably. You can get the package on the Simspark page on SourceForge at http://sourceforge.net/projects/simspark/ Modified: trunk/spark/lib/oxygen/simulationserver/agentcontrol.cpp =================================================================== --- trunk/spark/lib/oxygen/simulationserver/agentcontrol.cpp 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/lib/oxygen/simulationserver/agentcontrol.cpp 2009-10-31 09:39:27 UTC (rev 96) @@ -51,6 +51,10 @@ void AgentControl::ClientConnect(shared_ptr<Client> client) { + // Make sure that there is enough space in sense message cache vector + if (client->id >= mClientSenses.size()) + mClientSenses.resize(client->id+1); + if (mGameControlServer.get() == 0) { return; @@ -61,6 +65,8 @@ void AgentControl::ClientDisconnect(shared_ptr<Client> client) { + mClientSenses[client->id].clear(); + if (mGameControlServer.get() == 0) { return; @@ -124,6 +130,23 @@ } } +void AgentControl::SenseAgent() +{ + int clientID; + for ( + TAddrMap::iterator iter = mClients.begin(); + iter != mClients.end(); + ++iter + ) + { + clientID = iter->second->id; + if (!mClientSenses[clientID].empty()) + { + SendClientMessage(iter->second, mClientSenses[clientID]); + } + } +} + void AgentControl::EndCycle() { NetControl::EndCycle(); @@ -146,17 +169,14 @@ return; } - // generate senses for all agents and send them to the - // corresponding net clients - int idx = 0; - vector<string> sensesArray(mClients.size()); + // generate senses for all agents for ( TAddrMap::iterator iter = mClients.begin(); iter != mClients.end(); - ++iter, idx++ + ++iter ) { - shared_ptr<Client>& client = (*iter).second; + const shared_ptr<Client> &client = (*iter).second; shared_ptr<AgentAspect> agent = mGameControlServer->GetAgentAspect(client->id); @@ -166,27 +186,12 @@ } shared_ptr<PredicateList> senseList = agent->QueryPerceptors(); - sensesArray[idx] = parser->Generate(senseList); - if (sensesArray[idx].empty()) + mClientSenses[client->id] = parser->Generate(senseList); + if (mClientSenses[client->id].empty()) { continue; } - mNetMessage->PrepareToSend(sensesArray[idx]); + mNetMessage->PrepareToSend(mClientSenses[client->id]); } - - // sending the senses - idx = 0; - for ( - TAddrMap::iterator iter = mClients.begin(); - iter != mClients.end(); - ++iter, idx++ - ) - { - if (!sensesArray[idx].empty()) - { - SendClientMessage(iter->second, sensesArray[idx]); - } - - } } Modified: trunk/spark/lib/oxygen/simulationserver/agentcontrol.h =================================================================== --- trunk/spark/lib/oxygen/simulationserver/agentcontrol.h 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/lib/oxygen/simulationserver/agentcontrol.h 2009-10-31 09:39:27 UTC (rev 96) @@ -47,7 +47,10 @@ GameControlServer */ virtual void StartCycle(); - /** generates and sends sense updates to all connected agents */ + /** sends sense updates to all connected agents */ + virtual void SenseAgent(); + + /** generates sense updates for all connected agents */ virtual void EndCycle(); protected: @@ -56,6 +59,8 @@ protected: /** cached reference to the GameControlServer */ CachedPath<GameControlServer> mGameControlServer; + + std::vector<std::string> mClientSenses; }; DECLARE_CLASS(AgentControl); Modified: trunk/spark/lib/oxygen/simulationserver/netcontrol.cpp =================================================================== --- trunk/spark/lib/oxygen/simulationserver/netcontrol.cpp 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/lib/oxygen/simulationserver/netcontrol.cpp 2009-10-31 09:39:27 UTC (rev 96) @@ -159,6 +159,15 @@ return; } + ret = mSocket->setReuseAddr(true); + + if (ret < 0) + { + GetLog()->Warning() + << "(NetControl) failed to enable reuse of server socket " + << "with '" << strerror(errno) << "'\n"; + } + try { mSocket->bind(mLocalAddr); Modified: trunk/spark/lib/oxygen/simulationserver/simulationserver.cpp =================================================================== --- trunk/spark/lib/oxygen/simulationserver/simulationserver.cpp 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/lib/oxygen/simulationserver/simulationserver.cpp 2009-10-31 09:39:27 UTC (rev 96) @@ -45,7 +45,8 @@ } SimulationServer::SimulationServer() : - Node(), mAdjustSpeed(false), mMaxStepsPerCycle(3), mThreadBarrier(0) + Node(), mAdjustSpeed(false), mExitThreads(false), mMaxStepsPerCycle(3), + mThreadBarrier(0) { mSimTime = 0.0f; mSimStep = 0.2f; @@ -422,14 +423,15 @@ shared_ptr<SimControlNode> renderControl = GetControlNode("RenderControl"); float initDelta, finalDelta; - while (true) + while (!mExitThreads) { ++mCycle; mThreadBarrier->wait(); + if (mExit) + mExitThreads = true; + // Wait for SimControlNodes' acts at the begining of a cycle mThreadBarrier->wait(); - if (mExit) // this check should be here so that all threads will quit - break; finalDelta = initDelta = mSumDeltaTime; mSceneServer->PrePhysicsUpdate(mSimStep); @@ -452,6 +454,7 @@ if (renderControl && renderControl->GetTime() - mSimTime < 0.005f ) renderControl->EndCycle(); + mThreadBarrier->wait(); mSumDeltaTime -= initDelta - finalDelta; } @@ -473,7 +476,7 @@ bool isRenderControl = (controlNode->GetName() == "RenderControl"); bool newCycle = false; - while ( true ) + while (!mExitThreads) { mThreadBarrier->wait(); newCycle = false; @@ -486,8 +489,6 @@ controlNode->SetSimTime(mSimTime); } mThreadBarrier->wait(); - if (mExit) - break; if (isInputControl) { Modified: trunk/spark/lib/oxygen/simulationserver/simulationserver.h =================================================================== --- trunk/spark/lib/oxygen/simulationserver/simulationserver.h 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/lib/oxygen/simulationserver/simulationserver.h 2009-10-31 09:39:27 UTC (rev 96) @@ -220,6 +220,11 @@ /** skips physical simulation for some time to catch up real time */ bool mAdjustSpeed; + /** in multi-threaded mode, this indicates that all threads should be + * terminated. + */ + bool mExitThreads; + /** determines the number of allowed steps per cycle when mAdjustSpeed is true */ int mMaxStepsPerCycle; Modified: trunk/spark/utility/rcssnet/socket.cpp =================================================================== --- trunk/spark/utility/rcssnet/socket.cpp 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/utility/rcssnet/socket.cpp 2009-10-31 09:39:27 UTC (rev 96) @@ -304,7 +304,22 @@ return -1; } - Socket::SocketDesc + int + Socket::setReuseAddr( bool on ) + { + if( isOpen() ) + { + int doreuse = on; + return setsockopt( getFD(), SOL_SOCKET, + SO_REUSEADDR, + (const char*)&doreuse, + sizeof( int ) ); + } + errno = EPERM; + return -1; + } + + Socket::SocketDesc Socket::getFD() const { return ( isOpen() ? *(m_handle.get()) : Socket::INVALIDSOCKET ); } Modified: trunk/spark/utility/rcssnet/socket.hpp =================================================================== --- trunk/spark/utility/rcssnet/socket.hpp 2009-10-26 07:24:44 UTC (rev 95) +++ trunk/spark/utility/rcssnet/socket.hpp 2009-10-31 09:39:27 UTC (rev 96) @@ -95,6 +95,9 @@ int setBroadcast( bool on = true ); + int + setReuseAddr( bool on = true ); + SocketDesc getFD() const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |