drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
IOThreadStorage.h
Go to the documentation of this file.
1
14
15#pragma once
16
18#include <trantor/utils/NonCopyable.h>
19#include <memory>
20#include <vector>
21#include <limits>
22#include <functional>
23
24namespace drogon
25{
59template <typename C>
60class IOThreadStorage : public trantor::NonCopyable
61{
62 public:
63 using ValueType = C;
64 using InitCallback = std::function<void(ValueType &, size_t)>;
65
66 template <typename... Args>
67 IOThreadStorage(Args &&...args)
68 {
69 static_assert(std::is_constructible<C, Args &&...>::value,
70 "Unable to construct storage with given signature");
71 size_t numThreads = app().getThreadNum();
72 assert(numThreads > 0 &&
73 numThreads != (std::numeric_limits<size_t>::max)());
74 // set the size to numThreads+1 to enable access to this in the main
75 // thread.
76 storage_.reserve(numThreads + 1);
77
78 for (size_t i = 0; i <= numThreads; ++i)
79 {
80 storage_.emplace_back(std::forward<Args>(args)...);
81 }
82 }
83
84 void init(const InitCallback &initCB)
85 {
86 for (size_t i = 0; i < storage_.size(); ++i)
87 {
88 initCB(storage_[i], i);
89 }
90 }
91
97 inline ValueType &getThreadData()
98 {
99 size_t idx = app().getCurrentThreadIndex();
100 assert(idx < storage_.size());
101 return storage_[idx];
102 }
103
104 inline const ValueType &getThreadData() const
105 {
106 size_t idx = app().getCurrentThreadIndex();
107 assert(idx < storage_.size());
108 return storage_[idx];
109 }
110
116 inline void setThreadData(const ValueType &newData)
117 {
118 size_t idx = app().getCurrentThreadIndex();
119 assert(idx < storage_.size());
120 storage_[idx] = newData;
121 }
122
123 inline void setThreadData(ValueType &&newData)
124 {
125 size_t idx = app().getCurrentThreadIndex();
126 assert(idx < storage_.size());
127 storage_[idx] = std::move(newData);
128 }
129
130 inline ValueType *operator->()
131 {
132 size_t idx = app().getCurrentThreadIndex();
133 assert(idx < storage_.size());
134 return &storage_[idx];
135 }
136
137 inline ValueType &operator*()
138 {
139 return getThreadData();
140 }
141
142 inline const ValueType *operator->() const
143 {
144 size_t idx = app().getCurrentThreadIndex();
145 assert(idx < storage_.size());
146 return &storage_[idx];
147 }
148
149 inline const ValueType &operator*() const
150 {
151 return getThreadData();
152 }
153
154 private:
155 std::vector<ValueType> storage_;
156};
157
158inline trantor::EventLoop *getIOThreadStorageLoop(size_t index) noexcept(false)
159{
160 if (index > drogon::app().getThreadNum())
161 {
162 throw std::out_of_range("Event loop index is out of range");
163 }
164 if (index == drogon::app().getThreadNum())
165 return drogon::app().getLoop();
166 return drogon::app().getIOLoop(index);
167}
168} // namespace drogon
virtual trantor::EventLoop * getIOLoop(size_t id) const =0
Get an IO loop with id. E.g. 0 <= id < #Total thread-loops.
virtual size_t getThreadNum() const =0
Get the number of threads for IO event loops.
virtual size_t getCurrentThreadIndex() const =0
Get the Current Thread Index whose range is [0, the total number of IO threads].
virtual trantor::EventLoop * getLoop() const =0
Get the main event loop of the framework;.
void setThreadData(const ValueType &newData)
Sets the thread data for the current thread.
Definition IOThreadStorage.h:116
ValueType & getThreadData()
Get the thread storage associate with the current thread.
Definition IOThreadStorage.h:97
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
HttpAppFramework & app()
A wrapper of the instance() method.
Definition HttpAppFramework.h:1656