Example #1
0
        /// <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();
            }
        }
Example #2
0
        /// <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();
        }
Example #3
0
 /// <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;
 }
Example #4
0
 /// <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);
 }
Example #5
0
        /// <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;
        }
Example #6
0
        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;
        }
Example #7
0
        /// <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);
            }
        }
Example #8
0
 public KmodThreadNotif(WmKmodBroker broker, KmodThreadCommand command)
 {
     m_broker  = broker;
     m_command = command;
 }
Example #9
0
        /// <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);
                }
            }
        }
Example #10
0
 /// <summary>
 /// Post the next command.
 /// </summary>
 public void PostCommand(KmodThreadCommand command)
 {
     m_commandQueue.Enqueue(command);
 }