Go through all connections and read any incoming commands from the sockets. The messages are sent to the callback registered with the connection when it was created (ReceivedCall currently). Those calls could take a long time to execute (e.g. a call to Run Soar). Returns true if we received at least one message.
| 217 | // Those calls could take a long time to execute (e.g. a call to Run Soar). |
| 218 | // Returns true if we received at least one message. |
| 219 | bool ConnectionManager::ReceiveAllMessages() |
| 220 | { |
| 221 | int index = 0 ; |
| 222 | bool receivedOneMessage = false ; |
| 223 | |
| 224 | // We need to search this list of connections and call each in turn. |
| 225 | // But we also want to allow the listener thread to add new connections while we're doing this. |
| 226 | // (E.g. we might want to attach a debugger to a process that's already executing a "run" command inside "receiveMessages"). |
| 227 | // So we use this slightly cumbersome approach of looking up the connection based on an integer index. |
| 228 | // The lookup is thread safe and if the connection list changes between lookups that's fine as this function |
| 229 | // will return NULL once we go out of bounds. (You could argue that we might miss calling a connection on a particular pass using this method |
| 230 | // but that should be ok). |
| 231 | Connection* pConnection = GetConnectionByIndex(index++) ; |
| 232 | |
| 233 | while (pConnection) |
| 234 | { |
| 235 | // Check to see if this connection has already been closed |
| 236 | // (which includes if the other side has dropped its half of the socket) |
| 237 | if (!pConnection->IsClosed()) |
| 238 | { |
| 239 | receivedOneMessage = pConnection->ReceiveMessages(true) || receivedOneMessage ; |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | // If the connection has closed, delete it from the list of active connections |
| 244 | RemoveConnection(pConnection) ; |
| 245 | |
| 246 | // Remove any events that this connection is listening to |
| 247 | KernelSML* pKernelSML = static_cast<KernelSML*>(pConnection->GetUserData()); |
| 248 | pKernelSML->RemoveAllListeners(pConnection) ; |
| 249 | |
| 250 | // Not clear that we can just delete connections as we might be inside a connection callback |
| 251 | // when the shutdown comes. So for safety, move connections to a closed list instead of deleting. |
| 252 | // For now this will leak the connection object. Later if we are confident we can delete this list. |
| 253 | //delete pConnection ; |
| 254 | m_ClosedConnections.push_back(pConnection) ; |
| 255 | |
| 256 | // Since we just removed this connection we should look up the same index value again |
| 257 | // so we don't skip any. This isn't really that important. |
| 258 | index-- ; |
| 259 | } |
| 260 | |
| 261 | // Get the next connection (will return NULL once we reach the end of the list) |
| 262 | pConnection = GetConnectionByIndex(index++) ; |
| 263 | } |
| 264 | |
| 265 | // So far we don't have some sort of shutdown message the remote connections |
| 266 | // can send, but if we decide to implement it this allows us to return it. |
| 267 | return receivedOneMessage ; |
| 268 | } |
| 269 | |
| 270 | int ConnectionManager::GetListenerPort() |
| 271 | { |
nothing calls this directly
no test coverage detected