| 44 | } |
| 45 | |
| 46 | Connection_Receiver_Handle sml_CreateEmbeddedConnection(Connection_Sender_Handle hSenderConnection, ProcessMessageFunction pProcessMessage, int connectionType, int portToListenOn) |
| 47 | { |
| 48 | bool synch = (connectionType == SML_SYNCH_CONNECTION) ; |
| 49 | |
| 50 | // Create a connection object which we'll use to talk back to this sender |
| 51 | EmbeddedConnection* pConnection = synch ? |
| 52 | EmbeddedConnectionSynch::CreateEmbeddedConnectionSynch() : |
| 53 | EmbeddedConnectionAsynch::CreateEmbeddedConnectionAsynch() ; |
| 54 | |
| 55 | // For debugging, record that this connection object is from kernel to client. |
| 56 | // The client will also have a Connection object which will not have this flag set. |
| 57 | pConnection->SetIsKernelSide(true) ; |
| 58 | |
| 59 | // Record our kernel object with this connection. |
| 60 | KernelSML* pKernelSML = KernelSML::CreateKernelSML(portToListenOn) ; |
| 61 | pConnection->SetUserData(pKernelSML) ; |
| 62 | |
| 63 | // If this is a synchronous connection then commands will execute on the embedded client's thread |
| 64 | // and we don't use the receiver thread. (Why not? If we allowed it to run then we'd have to (a) |
| 65 | // sychronize execution between the two threads and (b) sometimes Soar would be running in the client's thread and |
| 66 | // sometimes in the receiver's thread (depending on where "run" came from) and that could easily introduce a lot of |
| 67 | // complicated bugs or where performance would be different depending on whether you pressed "run" in the environment or "run" in a |
| 68 | // remote debugger). |
| 69 | if (!pConnection->IsAsynchronous()) |
| 70 | { |
| 71 | pKernelSML->StopReceiverThread() ; |
| 72 | } |
| 73 | |
| 74 | // Register for "calls" from the client. |
| 75 | pConnection->RegisterCallback(ReceivedCall, NULL, sml_Names::kDocType_Call, true) ; |
| 76 | |
| 77 | // The original sender is a receiver to us so we need to reverse the type. |
| 78 | pConnection->AttachConnectionInternal(reinterpret_cast<Connection_Receiver_Handle>(hSenderConnection), pProcessMessage) ; |
| 79 | |
| 80 | // Record this as one of the active connections |
| 81 | // Must only do this after the pConnection object has been fully initialized |
| 82 | // as the receiver thread may access it once it has been added to this list. |
| 83 | pKernelSML->AddConnection(pConnection) ; |
| 84 | |
| 85 | return reinterpret_cast<Connection_Receiver_Handle>(pConnection) ; |
| 86 | } |
| 87 | |
| 88 | ElementXML_Handle sml_ProcessMessage(Connection_Receiver_Handle hReceiverConnection, ElementXML_Handle hIncomingMsg, int action) |
| 89 | { |
no test coverage detected