From 89006bf0e8227144b8a52af821c2d9a4a72a8bdd Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 28 Feb 2024 13:05:32 +0100 Subject: [PATCH 1/8] singleton section added --- docs/utils/singletons.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/utils/singletons.md diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md new file mode 100644 index 0000000000..1b46ff05f0 --- /dev/null +++ b/docs/utils/singletons.md @@ -0,0 +1,7 @@ +## Disposing singletons + + When a singleton uses a socket it must open the connection before registering itself in the singleton list (so do this in the constructor of the singleton type) to make sure it gets cleanup before the resource monitor singleton is destructed + + When a singleton uses itself (via the instance method) or any other singleton during destruction be very careful (at least when that is a singleton type) to make sure it does not create a new singleton by accident. + + A client lib dispose should not call Singleton::Dispose but only clean up its own internal singletons \ No newline at end of file From b5e4262c313d6597dd222064381badd12646c129 Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 6 Mar 2024 10:26:03 +0100 Subject: [PATCH 2/8] singletons documentation section added --- docs/utils/singletons.md | 43 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index 1b46ff05f0..a00d977f78 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -1,7 +1,42 @@ -## Disposing singletons +## Using and disposing singletons - When a singleton uses a socket it must open the connection before registering itself in the singleton list (so do this in the constructor of the singleton type) to make sure it gets cleanup before the resource monitor singleton is destructed +When creating and using singletons, there are a few things to bear in mind. If they are handled incorrectly, problems with memory, the creation of overmapped copies of them and also the incorrect order of their destruction can occur. - When a singleton uses itself (via the instance method) or any other singleton during destruction be very careful (at least when that is a singleton type) to make sure it does not create a new singleton by accident. +Singletons that use sockets should connect to them before they are registered in the singletons list. This is therefore best done in their constructor. If the connection occurs too late, the singleton may not be cleaned up before the Resource Monitor destructor is called. +Here is an example of making sure a socket connection is opened in the OpenCDMAccessor singleton constructor. +```cpp +OpenCDMAccessor(const TCHAR domainName[]) + : _refCount(1) + , _domain(domainName) + , _engine(Core::ProxyType>::Create()) + , _client() + , _remote(nullptr) + , _adminLock() + , _signal(false, true) + , _interested(0) + , _sessionKeys() + { + TRACE_L1("Trying to open an OCDM connection @ %s\n", domainName); + Reconnect(); // make sure ResourceMonitor singleton is created before OpenCDMAccessor so the destruction order is correct + } +``` + +When a singleton uses itself (via the instance method) or any other singleton during destruction be very careful to make sure it does not create a new singleton by accident. - A client lib dispose should not call Singleton::Dispose but only clean up its own internal singletons \ No newline at end of file +A client library dispose method should not call `Core::Singleton::Dispose()` but only clean up its own internal singletons. +!!!warning + `Core::Singleton::Dispose()` dispose of all singletons in the singletons list. + +Calling this method on a particular singleton will dispose of them all. Instead, we should use `Core::SingletonType<>::Dispose()` with the appropriate type of singleton we want to dispose of specified, or write our own `Dispose()` which will not dispose of all remaining singletons. +Below is an example of how you SHOULD NOT dispose of a singleton! +```cpp +void opencdm_dispose() { + Core::Singleton::Dispose(); +} +``` +And here an example of the RIGHT way to dispose of a singleton. +```cpp +void opencdm_dispose() { + Core::SingletonType::Dispose(); +} +``` From f12b2fef5d5d2b044a2e44012682208ff0b0f77e Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 6 Mar 2024 10:37:16 +0100 Subject: [PATCH 3/8] singletons.md added to mkdocs.yml --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 85117a1137..9bd3939600 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -50,6 +50,7 @@ nav: - Timers: utils/timers.md - Web Requests: utils/web.md - Sockets: utils/sockets.md + - Singletons: utils/singletons.md - Processes: utils/processes.md - Client Development: - Introduction: client/intro.md From 356491a30fe72c907a38caafb66e8b814330acb9 Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 6 Mar 2024 10:43:08 +0100 Subject: [PATCH 4/8] warning fixed --- docs/utils/singletons.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index a00d977f78..ac99d60082 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -25,9 +25,10 @@ When a singleton uses itself (via the instance method) or any other singleton du A client library dispose method should not call `Core::Singleton::Dispose()` but only clean up its own internal singletons. !!!warning - `Core::Singleton::Dispose()` dispose of all singletons in the singletons list. + `Core::Singleton::Dispose()` dispose of all singletons in the singletons list. Calling this method on a particular singleton will dispose of them all. Instead, we should use `Core::SingletonType<>::Dispose()` with the appropriate type of singleton we want to dispose of specified, or write our own `Dispose()` which will not dispose of all remaining singletons. + Below is an example of how you SHOULD NOT dispose of a singleton! ```cpp void opencdm_dispose() { From 638f0ffaacb1aa3e685e4651a1664d517d15b074 Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 6 Mar 2024 10:46:32 +0100 Subject: [PATCH 5/8] formating fix --- docs/utils/singletons.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index ac99d60082..5548b03266 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -15,10 +15,10 @@ OpenCDMAccessor(const TCHAR domainName[]) , _signal(false, true) , _interested(0) , _sessionKeys() - { - TRACE_L1("Trying to open an OCDM connection @ %s\n", domainName); - Reconnect(); // make sure ResourceMonitor singleton is created before OpenCDMAccessor so the destruction order is correct - } +{ + TRACE_L1("Trying to open an OCDM connection @ %s\n", domainName); + Reconnect(); // make sure ResourceMonitor singleton is created before OpenCDMAccessor so the destruction order is correct +} ``` When a singleton uses itself (via the instance method) or any other singleton during destruction be very careful to make sure it does not create a new singleton by accident. From 35ceba82e6d170922efcdd7ce9ffdb9de3a68d0b Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Thu, 21 Mar 2024 17:29:29 +0100 Subject: [PATCH 6/8] singletons description addded --- docs/utils/singletons.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index 5548b03266..1c495c4b01 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -1,3 +1,5 @@ +## What is singleton and why it is used +The Singleton pattern is a design pattern that restricts the instantiation of a class to a single instance. It ensures that only one instance of the class exists throughout the runtime of the program and provides a global point of access to that instance. In addition, they allow for lazy allocation and initialization, whereas global variables will always consume resources. Examples of using singletons can be found in ThunderClientLibraries repository. ## Using and disposing singletons When creating and using singletons, there are a few things to bear in mind. If they are handled incorrectly, problems with memory, the creation of overmapped copies of them and also the incorrect order of their destruction can occur. From e58eeabb15709878d318898a4d513cf1c853e962 Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Mon, 6 May 2024 08:14:05 +0200 Subject: [PATCH 7/8] [doc] description of singletons added --- docs/utils/singletons.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index 1c495c4b01..1cbf7e07b8 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -1,5 +1,11 @@ ## What is singleton and why it is used The Singleton pattern is a design pattern that restricts the instantiation of a class to a single instance. It ensures that only one instance of the class exists throughout the runtime of the program and provides a global point of access to that instance. In addition, they allow for lazy allocation and initialization, whereas global variables will always consume resources. Examples of using singletons can be found in ThunderClientLibraries repository. + +## Differences between Singleton and SingletonType +The `Singleton` class serves as a base for implementing singleton objects, featuring a templated constructor to handle instance initialization and a virtual method for retrieving the implementing class name. It internally manages singleton instances through a `SingletonList`. +`SingletonType` is a templated class designed to streamline the implementation of singleton objects in Thunder. It is intended to be used as a base class for concrete singleton classes and implements constructors and destructors to handle registration and unregistration of singleton instances within the `SingletonList`. +In summary, while both classes facilitate the implementation of singleton objects, Singleton provides basic functionality, while SingletonType extends this functionality to offer more robust management and control over singleton instances. + ## Using and disposing singletons When creating and using singletons, there are a few things to bear in mind. If they are handled incorrectly, problems with memory, the creation of overmapped copies of them and also the incorrect order of their destruction can occur. From eaf3ae77db5a182d9ddd24409908589ebecabfd2 Mon Sep 17 00:00:00 2001 From: MFransen69 <39826971+MFransen69@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:35:41 +0200 Subject: [PATCH 8/8] Update singletons.md --- docs/utils/singletons.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md index 1cbf7e07b8..19240d936b 100644 --- a/docs/utils/singletons.md +++ b/docs/utils/singletons.md @@ -1,14 +1,25 @@ ## What is singleton and why it is used The Singleton pattern is a design pattern that restricts the instantiation of a class to a single instance. It ensures that only one instance of the class exists throughout the runtime of the program and provides a global point of access to that instance. In addition, they allow for lazy allocation and initialization, whereas global variables will always consume resources. Examples of using singletons can be found in ThunderClientLibraries repository. -## Differences between Singleton and SingletonType -The `Singleton` class serves as a base for implementing singleton objects, featuring a templated constructor to handle instance initialization and a virtual method for retrieving the implementing class name. It internally manages singleton instances through a `SingletonList`. -`SingletonType` is a templated class designed to streamline the implementation of singleton objects in Thunder. It is intended to be used as a base class for concrete singleton classes and implements constructors and destructors to handle registration and unregistration of singleton instances within the `SingletonList`. -In summary, while both classes facilitate the implementation of singleton objects, Singleton provides basic functionality, while SingletonType extends this functionality to offer more robust management and control over singleton instances. +## Singleton and SingletonType +The `SingletonType` class can be used to make a class a singleton get access to an instance (which creates one if that was not done before): +```cpp +Core::SingletonType::Instance() +``` +If a parameter is required for the construction of the class that should be a singleton, Create can be used (and after that access to the singleton instance can be done using the Instance method): +```cpp +Core::SingletonType::Create(connector.c_str()); +``` +`SingletonType` is a templated class designed to streamline the implementation of singleton objects in Thunder. It is intended to be used as a base class for concrete singleton classes and implements constructors and destructors to handle registration and unregistration of singleton instances within a `SingletonList`. -## Using and disposing singletons +## disposing singletons -When creating and using singletons, there are a few things to bear in mind. If they are handled incorrectly, problems with memory, the creation of overmapped copies of them and also the incorrect order of their destruction can occur. +In general a singleton can be disposed using the Dispose method. Please note was will be highlighted below that calling Instance after Dispose might create a new instance of the Singleton. +All created Singletons cann be disposed at once with: +```cpp +Thunder::Core::Singleton::Dispose(); +``` +This should typically done at the end of an application fully based on the Thunder framework to cleanup all Singletons. As will be highlighted below if it is in a Library based on the Thunder framework you need to be more careful and not call the general Dispose but only cleanup what you created. Singletons that use sockets should connect to them before they are registered in the singletons list. This is therefore best done in their constructor. If the connection occurs too late, the singleton may not be cleaned up before the Resource Monitor destructor is called. Here is an example of making sure a socket connection is opened in the OpenCDMAccessor singleton constructor.