/// <summary> /// Update the select set specified with the socket of the tunnel. /// </summary> public void UpdateSelect(SelectSockets select) { Debug.Assert(transport.isReceiving || transport.doneReceiving); if (transport.isSending) { select.AddWrite(tunnel.Sock); } if (transport.isReceiving && !transport.doneReceiving) { select.AddRead(tunnel.Sock); } }
/// <summary> /// Run one pass of the main loop. /// </summary> private void RunPass() { // Wait for a command. while (m_commandQueue.Count == 0) { Block(new SelectSockets()); } // Get the next command. KmodThreadCommand command = m_commandQueue.Dequeue(); // Send the command. m_transport.sendMsg(command.Msg); while (true) { m_transport.doXfer(); if (!m_transport.isSending) { break; } SelectSockets select = new SelectSockets(); select.AddWrite(m_kmodSock); Block(select); } // We're done. if (!command.HaveResultFlag) { return; } // Wait for the results or the next command. bool firstFlag = true; while (m_commandQueue.Count == 0) { if (!m_transport.isReceiving) { m_transport.beginRecv(); } m_transport.doXfer(); // Push the next result. if (m_transport.doneReceiving) { lock (Mon) { m_elementQueue.Enqueue(m_transport.getRecv()); Monitor.Pulse(Mon); } // Send the notification that results are ready for this command. if (firstFlag) { firstFlag = false; PostToUI(new KmodThreadNotif(m_broker, command)); } } // Wait for the next result or the next command. else { SelectSockets select = new SelectSockets(); select.AddRead(m_kmodSock); Block(select); } } }