/// <summary> /// Exchange messages with Outlook. /// </summary> private void ChatWithOutlook() { Debug.Assert(m_msgQueue.Count == 0); Debug.Assert(m_chattingFlag); try { AnpTransport transport = new AnpTransport(m_outlookSock); while (true) { if (!transport.isReceiving) transport.beginRecv(); if (!transport.isSending && m_msgQueue.Count != 0) transport.sendMsg(m_msgQueue.Dequeue()); SelectSockets select = new SelectSockets(); select.AddRead(m_outlookSock); if (transport.isSending) select.AddWrite(m_outlookSock); Block(select); transport.doXfer(); if (transport.doneReceiving) { OutlookUiThreadMsg msg = new OutlookUiThreadMsg(m_broker, OutlookBrokerMsgType.ReceivedMsg); msg.Msg = transport.getRecv(); PostToUI(msg); } } } catch (Exception ex) { m_chattingFlag = false; CloseOutlookSock(); m_msgQueue.Clear(); if (ex is WorkerCancellationException) throw; OutlookUiThreadMsg msg = new OutlookUiThreadMsg(m_broker, OutlookBrokerMsgType.Disconnected); msg.Ex = ex; PostToUI(msg); } }
/// <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); } } }
/// <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); }