Skip to content

Commit

Permalink
[DOC] Singletons section (#1540)
Browse files Browse the repository at this point in the history
* singleton section added

* singletons documentation section added

* singletons.md added to mkdocs.yml

* warning fixed

* formating fix

* singletons description addded

* [doc] description of singletons added

* Update singletons.md

---------

Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com>
  • Loading branch information
2 people authored and msieben committed Jun 20, 2024
1 parent 3a2ee47 commit 08fb8d9
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
62 changes: 62 additions & 0 deletions docs/utils/singletons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## 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.

## 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<MessageUnit>::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<OpenCDMAccessor>::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`.

## disposing singletons

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.
```cpp
OpenCDMAccessor(const TCHAR domainName[])
: _refCount(1)
, _domain(domainName)
, _engine(Core::ProxyType<RPC::InvokeServerType<1, 0, 4>>::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 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<OpenCDMAccessor>::Dispose();
}
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 08fb8d9

Please sign in to comment.