| 23 | using namespace sock ; |
| 24 | |
| 25 | void ReceiverThread::Run() |
| 26 | { |
| 27 | // While this thread is alive, keep checking for incoming messages |
| 28 | // and executing them. These messages could be coming in from a remote socket |
| 29 | // or from an embedded connection. If we're executing on the client thread |
| 30 | // for an embedded connection (the "sycnhronous" model) then this thread is shut down |
| 31 | // and it's the client's responsibility to check for incoming messages by calling |
| 32 | // "GetIncomingCommands" periodically. |
| 33 | |
| 34 | // Record the time of the last message we received and keep polling |
| 35 | // for a little after at a high speed, before sleeping. |
| 36 | // The reason we track this is because calling "Sleep(0)" gives us maximum |
| 37 | // performance (on towers-of-hanoi calling Sleep(1) instead slows execution down |
| 38 | // by a factor of 80!), but calling "Sleep(0)" means we're stuck in a tight loop checking |
| 39 | // messages continually. If we're using Soar through a command line interface (for instance) |
| 40 | // then the CPU would be 100% loaded all of the time, even if the user wasn't typing anything. |
| 41 | // This method of switching between Sleep(0) and a true sleep means we get maximum performance |
| 42 | // during a run (when messages are flying back and forth) but when the user stops doing anything |
| 43 | // the CPU quickly drops off to 0% usage as we sleep a lot. |
| 44 | // The other option would be to have a notification system where we sleep until a command |
| 45 | // comes in, but building that in a cross platform fashion isn't something we want to tackle right now. |
| 46 | clock_t last = 0 ; |
| 47 | |
| 48 | // How long to wait before sleeping (currently 1 sec) |
| 49 | clock_t delay = CLOCKS_PER_SEC ; |
| 50 | |
| 51 | // clock_t report = 0 ; |
| 52 | |
| 53 | while (!m_QuitNow) |
| 54 | { |
| 55 | #ifdef _DEBUG |
| 56 | /* |
| 57 | // Every so often report that we're alive |
| 58 | if (clock() - report > CLOCKS_PER_SEC * 3) |
| 59 | { |
| 60 | report = clock() ; |
| 61 | sml::PrintDebugFormat("ReceiverThread::Run alive") ; |
| 62 | } |
| 63 | */ |
| 64 | #endif |
| 65 | // Receive any incoming commands and execute them |
| 66 | bool receivedMessage = m_ConnectionManager->ReceiveAllMessages() ; |
| 67 | |
| 68 | if (receivedMessage) |
| 69 | { |
| 70 | // Record the time of the last incoming message |
| 71 | last = clock() ; |
| 72 | } |
| 73 | |
| 74 | clock_t current = clock() ; |
| 75 | |
| 76 | // If it's been a while since the last incoming message |
| 77 | // then start sleeping a reasonable amount. |
| 78 | // Sleep(0) just allows other threads to run before we continue |
| 79 | // to execute. |
| 80 | if (current - last > delay) |
| 81 | { |
| 82 | sml::Sleep(0, 5) ; |
nothing calls this directly
no test coverage detected