Stroika Library
3.0d16
Help-Home
Loading...
Searching...
No Matches
SharedStaticData.h
1
/*
2
* Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3
*/
4
#ifndef _Stroika_Foundation_Execution_SharedStaticData_h_
5
#define _Stroika_Foundation_Execution_SharedStaticData_h_ 1
6
7
#include "Stroika/Foundation/StroikaPreComp.h"
8
9
#include <mutex>
10
11
#include "Stroika/Foundation/Common/Common.h"
12
#include "
Stroika/Foundation/Execution/SpinLock.h
"
13
#include "Stroika/Foundation/Memory/Common.h"
14
15
/**
16
* \note Code-Status: <a href="Code-Status.md#Alpha">Alpha</a>
17
*
18
* TODO:
19
* @todo See about static buffer style from ModuleInit - so no NEW operation!
20
*
21
* @todo use static inline members, but right now that causes VS2k17 compiler to crash
22
*
23
* @todo Need example use somewhere, and document why this instaed of c++ magic initializers... (and if not good reason, deprecate)
24
*/
25
26
namespace
Stroika::Foundation::Execution
{
27
28
/**
29
* SharedStaticData<T> is used to safely create a copy of static data shared among various users
30
* in a thread safe way, and where the shared data goes away when the last reference does, and where
31
* the shared data is lazy constructed.
32
*
33
* This is very similar to have a single static variable of type T, except that instead of
34
* having T constructed at global execution time, and destroyed at global object destruction time,
35
* it happens when the first owner comes into existence and when the last owner goes out of existence.
36
*
37
* For example - if the shared data object creates threads, it can be a problem having this destroyed in
38
* a static (file scope) lifetime.
39
*
40
* \note This is also similar to the @see ModuleInit<> template, except that this is intended to give the
41
* user tighter control over lifetime of the shared data.
42
*
43
* \note Why use this instead of member function returning reference to local static object?
44
* Only real difference here is that this 'shared static' object will be auto-deleted
45
* when the last reference to it is destroyed (as opposed to after we start exiting main for static
46
* data member)
47
*
48
* This can be important, if, for example, the shared object contains Thread objects.
49
*
50
*
51
* \par Example Usage (from HealthFrameWorksServer)
52
* \code
53
* class AuditLogSink {
54
* ...
55
* private:
56
* struct SharedData_;
57
* Execution::SharedStaticData<SharedData_> fSharedData_;
58
* };
59
* struct AuditLogSink::SharedData_ {
60
* Execution::Thread::Ptr fCleanupThread;
61
*
62
* SharedData_ ()
63
* : fCleanupThread (Thread::New (&AuditLogSink::SimpleCleanupThread_))
64
* {
65
* fCleanupThread.SetThreadPriority (Thread::Priority::eLowest);
66
* fCleanupThread.SetThreadName ("AuditTrailCleanupThread"sv);
67
* fCleanupThread.Start ();
68
* }
69
* ~SharedData_ ()
70
* {
71
* fCleanupThread.AbortAndWaitForDone ();
72
* }
73
* };
74
* \endcode
75
*
76
* So then on the first AuditLogSink construction - we construct the cleanup thread, and on the last the
77
* thread is shutdown. If these objects are all created after main, this assures the thread startup/cleanup
78
* is all done after the start of main and before it completes.
79
*
80
* \note Since this object is in its 'default initialized' state with all zeros, it is safe to use before
81
* the start of main (), and doesn't require the complicated inter-depependency managment of the
82
* @ModuleInit code.
83
*/
84
template
<
typename
T>
85
class
SharedStaticData
{
86
public
:
87
/**
88
*/
89
SharedStaticData
();
90
SharedStaticData
(
const
SharedStaticData
&) =
delete
;
91
92
public
:
93
~SharedStaticData
();
94
95
public
:
96
SharedStaticData
& operator= (
const
SharedStaticData
&) =
delete
;
97
98
public
:
99
/**
100
* Return value guaranteed lifetime at least as long as 'this' object.
101
*
102
* Note - though THIS is fully threadsafe, use of the reference T& is only as threadsafe as T itself.
103
*/
104
nonvirtual T&
Get
();
105
nonvirtual
const
T&
Get
()
const
;
106
107
private
:
108
// nb. use mutex instead of atomic<> because must lock sOnceObj_ at same time (block subsequent callers while constructing)
109
inline
static
conditional_t<kSpinLock_IsFasterThan_mutex, SpinLock, mutex> sMutex_{};
110
inline
static
unsigned
int
sCountUses_{};
111
inline
static
T* sOnceObj_{};
112
// alignas (alignof (T)) byte fOnceObj_Storage_[sizeof (T)]; // avoid actual memory allocation call - since only one of these
113
};
114
115
}
116
117
/*
118
********************************************************************************
119
***************************** Implementation Details ***************************
120
********************************************************************************
121
*/
122
#include "SharedStaticData.inl"
123
124
#endif
/*_Stroika_Foundation_Execution_SharedStaticData_h_*/
SpinLock.h
Stroika::Foundation::Execution::SharedStaticData
Definition
SharedStaticData.h:85
Stroika::Foundation::Execution::SharedStaticData::Get
nonvirtual T & Get()
Definition
SharedStaticData.inl:38
Stroika::Foundation::Execution
Definition
SDKString.inl:7
Library
Sources
Stroika
Foundation
Execution
SharedStaticData.h
Generated by
1.9.8