/// <summary> /// Handle the KMOD connection result. /// </summary> private void HandleConnectResult() { try { // Get an element reader and read the tool info. K3pElementReader reader = new K3pElementReader(m_curThread.GetNextK3pElement); UInt32 ins = reader.Ins(); if (ins != K3p.KMO_COGITO_ERGO_SUM) { throw new Exception("unexpected reply to KMOD connect command"); } (new K3p.kmo_tool_info()).FromElementReader(reader); // We have received the connect results. m_curThread.HaveConnectResultFlag = true; // We no longer have a command. m_curCommand = null; // If we have a transaction, start it. if (m_curTransaction != null) { StartCurrentTransaction(); } } catch (Exception ex) { Killall(ex); } RequestRun(); }
/// <summary> /// Execute the current transaction with the reason specified to obtain /// the next user command. /// </summary> private void GetNextUserCommand(KmodTransactionReason reason) { Debug.Assert(IsTransactionExecuting()); Debug.Assert(IsThreadReadyForUserCommand()); // Remember the previous command posted by the user. KmodThreadCommand prevCmd = m_curCommand; try { // Call Run(). Note that the transaction may be cancelled // or finished during that time. m_curTransaction.Run(reason); // If the transaction is still executing and the user hasn't // posted another command or if the transaction has explicitly // been marked finished, the transaction is completed. if ((IsTransactionExecuting() && (m_curCommand == null || m_curCommand == prevCmd)) || (m_curTransaction != null && m_curTransaction.Status == KmodTransactionStatus.Finished)) { EndCurrentTransaction(); RequestRun(); } } // The transaction has failed. Kill everything and request a run. catch (Exception ex) { Killall(ex); RequestRun(); } }
/// <summary> /// Stop the KMOD thread if it is running. The current command is cleared. /// </summary> private void StopKmodThread() { if (m_curThread != null) { m_curThread.RequestCancellation(); } m_curCommand = null; }
/// <summary> /// Start the KMOD thread and send it the connect command. /// </summary> private void StartKmodThread() { Debug.Assert(m_curThread == null); Debug.Assert(m_curCommand == null); m_curThread = new KmodThread(this); m_curThread.Start(); m_curCommand = new KmodThreadCommand(m_curThread, new K3p.k3p_connect(), true); m_curThread.PostToWorker(m_curCommand); }
/// <summary> /// Set the current transaction status to finished, clear the current /// transaction and command. /// </summary> private void EndCurrentTransaction() { if (m_curTransaction != null) { m_curTransaction.Status = KmodTransactionStatus.Finished; m_curTransaction = null; } m_curCommand = null; }
public void PostTransactionCommand(KmodTransaction transaction, K3pMsg msg, bool haveResultFlag) { Debug.Assert(transaction == m_curTransaction); Debug.Assert(IsTransactionExecuting()); Debug.Assert(IsThreadReadyForUserCommand()); KmodThreadCommand cmd = new KmodThreadCommand(m_curThread, msg, haveResultFlag); m_curThread.PostToWorker(cmd); m_curCommand = haveResultFlag ? cmd : null; }
/// <summary> /// Called when a KMOD thread notification is received. /// </summary> public void OnThreadNotification(KmodThreadCommand command) { // We're don't care about this notification anymore. if (command != m_curCommand) { return; } // The result of the command is ready. m_curCommand.ResultReadyFlag = true; // This is the notification for the connection. if (m_curCommand.Msg is K3p.k3p_connect) { HandleConnectResult(); } // This is the notification for the user's command. else { GetNextUserCommand(KmodTransactionReason.CommandResult); } }
public KmodThreadNotif(WmKmodBroker broker, KmodThreadCommand command) { m_broker = broker; m_command = command; }
/// <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> /// Post the next command. /// </summary> public void PostCommand(KmodThreadCommand command) { m_commandQueue.Enqueue(command); }
/// <summary> /// Stop the KMOD thread if it is running. The current command is cleared. /// </summary> private void StopKmodThread() { if (m_curThread != null) m_curThread.RequestCancellation(); m_curCommand = null; }
/// <summary> /// Handle the KMOD connection result. /// </summary> private void HandleConnectResult() { try { // Get an element reader and read the tool info. K3pElementReader reader = new K3pElementReader(m_curThread.GetNextK3pElement); UInt32 ins = reader.Ins(); if (ins != K3p.KMO_COGITO_ERGO_SUM) throw new Exception("unexpected reply to KMOD connect command"); (new K3p.kmo_tool_info()).FromElementReader(reader); // We have received the connect results. m_curThread.HaveConnectResultFlag = true; // We no longer have a command. m_curCommand = null; // If we have a transaction, start it. if (m_curTransaction != null) StartCurrentTransaction(); } catch (Exception ex) { Killall(ex); } RequestRun(); }
/// <summary> /// Called when a KMOD thread notification is received. /// </summary> public void OnThreadNotification(KmodThreadCommand command) { // We're don't care about this notification anymore. if (command != m_curCommand) return; // The result of the command is ready. m_curCommand.ResultReadyFlag = true; // This is the notification for the connection. if (m_curCommand.Msg is K3p.k3p_connect) HandleConnectResult(); // This is the notification for the user's command. else GetNextUserCommand(KmodTransactionReason.CommandResult); }