diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4f1ef1a..b2d0e49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,11 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
-
-## [8.4.1] - 2019-06-05
### Changed
- Caching the program/processor start time and calculating the uptime from those values instead of polling the crestron processor
+
+## [8.4.1] - 2019-06-05
+### Added
+ - Adding features to IcdEnvironment for tracking program initialization state
+
## [8.4.0] - 2019-05-15
### Added
- Added GUID utils for generating seeded GUIDs
diff --git a/ICD.Common.Utils/IcdEnvironment.cs b/ICD.Common.Utils/IcdEnvironment.cs
index f0d6a36..1804ed5 100644
--- a/ICD.Common.Utils/IcdEnvironment.cs
+++ b/ICD.Common.Utils/IcdEnvironment.cs
@@ -1,4 +1,6 @@
using System;
+using ICD.Common.Properties;
+using ICD.Common.Utils.Extensions;
namespace ICD.Common.Utils
{
@@ -54,5 +56,41 @@ namespace ICD.Common.Utils
public static event ProgramStatusCallback OnProgramStatusEvent;
public static event EthernetEventCallback OnEthernetEvent;
+
+ ///
+ /// Raised when the program has completed initialization.
+ ///
+ public static event EventHandler OnProgramInitializationComplete;
+
+ private static readonly SafeCriticalSection s_ProgramInitializationSection = new SafeCriticalSection();
+ private static bool s_ProgramInitializationComplete;
+
+ ///
+ /// Returns true if the program has been flagged as completely initialized.
+ ///
+ public static bool ProgramIsInitialized { get { return s_ProgramInitializationSection.Execute(() => s_ProgramInitializationComplete); } }
+
+ ///
+ /// Called by the program entry point to signify that the program initialization is complete.
+ ///
+ [PublicAPI]
+ public static void SetProgramInitializationComplete()
+ {
+ s_ProgramInitializationSection.Enter();
+
+ try
+ {
+ if (s_ProgramInitializationComplete)
+ return;
+
+ s_ProgramInitializationComplete = true;
+ }
+ finally
+ {
+ s_ProgramInitializationSection.Leave();
+ }
+
+ OnProgramInitializationComplete.Raise(null);
+ }
}
}