/// <summary> /// Process the messages received from the KCD, if any. /// </summary> private static void ProcessKcdMessages() { // If we were not notified, bail out quickly. if (!WmKcdState.EventFlag) { return; } // Clear the notification flag. WmKcdState.EventFlag = false; // Get the messages. List <KcdControlMsg> controlList = new List <KcdControlMsg>(); List <KcdAnpMsg> anpList = new List <KcdAnpMsg>(); Wm.KcdBroker.GetMessagesForWm(out controlList, out anpList); KLogging.Log("ProcessKcdMessages(), anpList.Count = " + anpList.Count); // Process the messages. foreach (KcdControlMsg m in controlList) { ProcessKcdControlMsg(m); } foreach (KcdAnpMsg m in anpList) { ProcessKcdAnpMsg(m); } }
/// <summary> /// This method is called when the workspace manager has stopped. /// The WM is serialized and the application is told to quit. /// </summary> private static void HandlePostStop() { KLogging.Log("WmSm: " + KwmStrings.Kwm + " has stopped."); Wm.MainStatus = WmMainStatus.Stopped; Wm.Serialize(); Program.RequestAppExit(); }
/// <summary> /// Upgrade the database schema if required. /// </summary> private void UpgradeDb(UInt32 version) { KLogging.Log("Upgrading database schema from version " + version); m_db.BeginTransaction(); UpdateDbVersion(LatestDbVersion); m_db.CommitTransaction(); }
/// <summary> /// Process an ANP message received from the KCD. /// </summary> private static void ProcessKcdAnpMsg(KcdAnpMsg m) { KLogging.Log("ProcessKcdAnpMsg() called"); // We're stopping. Bail out. if (StopFlag) { return; } // The KCD specified does not exist. Bail out. if (!Wm.KcdTree.ContainsKey(m.KcdID)) { return; } // The KCD is not connected. Bail out. WmKcd kcd = Wm.KcdTree[m.KcdID]; if (kcd.ConnStatus != KcdConnStatus.Connected) { return; } // Process the message according to its type. try { if (m.Msg.Type == KAnp.KANP_RES_FAIL && m.Msg.Elements[0].UInt32 == KAnp.KANP_RES_FAIL_BACKEND) { throw new Exception("backend error: " + m.Msg.Elements[1].String); } else if (m.IsReply()) { ProcessKcdAnpReply(kcd, m.Msg); } else if (m.IsEvent()) { ProcessKcdAnpEvent(kcd, m.Msg); } else { throw new Exception("received unexpected ANP message type (" + m.Msg.Type + ")"); } } catch (Exception ex) { HandleTroublesomeKcd(kcd, ex); } }
/// <summary> /// Create the initial database schema. /// </summary> private void CreateSchema() { KLogging.Log("Creating database schema."); m_db.BeginTransaction(); String s = "CREATE TABLE 'db_version' ('version' INT PRIMARY KEY); " + "INSERT INTO db_version (version) VALUES (" + LatestDbVersion + "); " + "CREATE TABLE 'serialization' ('name' VARCHAR PRIMARY KEY, 'data' BLOB); " + "CREATE TABLE 'kws_list' ('kws_id' INT PRIMARY KEY, 'name' VARCHAR); " + "CREATE TABLE 'kanp_events' ('kws_id' INT, 'evt_id' INT, 'evt_data' BLOB, 'status' INT); " + "CREATE TABLE 'eanp_events' ('kws_id' INT, 'evt_id' INT, 'uuid' BLOB, 'evt_data' BLOB); " + "CREATE UNIQUE INDEX 'kanp_events_index_1' ON 'kanp_events' ('kws_id', 'evt_id'); " + "CREATE UNIQUE INDEX 'kanp_events_index_2' ON 'kanp_events' ('kws_id', 'status', 'evt_id'); " + "CREATE UNIQUE INDEX 'eanp_events_index_1' ON 'eanp_events' ('kws_id', 'evt_id'); "; m_db.ExecNQ(s); m_db.CommitTransaction(); }
/// <summary> /// Run once through the bowels of the state machine. /// </summary> private static void RunPass() { // Reset the next run date to the maximum. During the processing of this // method, the next run date will lower itself as needed. m_nextRunDate = DateTime.MaxValue; // We're stopped, nothing to do. if (Wm.MainStatus == WmMainStatus.Stopped) { KLogging.Log("WmSm: " + KwmStrings.Kwm + " is stopped, nothing to do."); } // Try to stop. else if (Wm.MainStatus == WmMainStatus.Stopping && TryStop()) { HandlePostStop(); } // Perform regular processing. else { // Serialize the WM if needed. SerializeWmIfNeeded(); // Process the workspace state machines. ProcessKwsStateMachines(); // Process the workspaces to remove. ProcessKwsToRemove(); // Process the KCDs state changes. ProcessKcdState(); // Recompute the KCD event processing quench. RecomputeKcdQuenching(); // Process the KCD messages. ProcessKcdMessages(); } }
/// <summary> /// Run the workspace manager state machine. /// </summary> private static void Run(String who) { KLogging.Log("WmSm: Run() called by " + who); try { // Avoid reentrance. if (m_runningFlag) { KLogging.Log("WmSm: already running, bailing out."); return; } m_runningFlag = true; // Loop until our state stabilize. LockNotif(); while (WantToRunNow()) { RunPass(); } UnlockNotif(); // Schedule the next timer event appropriately. ScheduleTimerEvent(); // We're no longer running the WM. m_runningFlag = false; } // We cannot recover from these errors. catch (Exception ex) { KBase.HandleException(ex, true); } }