16 #ifndef INCLUDE_NN_NLIB_HANDLEMAKER_H_ 17 #define INCLUDE_NN_NLIB_HANDLEMAKER_H_ 23 namespace handle_maker {
46 return body->IsHandleBodyEnabled();
51 static const size_t size = HBODY::N;
59 int32_t transaction_count;
67 mask =
static_cast<int32_t
>(
reinterpret_cast<uintptr_t
>(&mask));
70 mask |= (1L << (20 + 2));
85 #define NLIB_HANDLETABLE_INITIALIZER {0, 0, 0, {{0, 0, nullptr}}} 102 handle_table_ =
nullptr;
108 : ptr_(ptr), handle_table_(handle_table) {}
111 NLIB_NOEXCEPT NLIB_EXCLUDES(*ptr->item) NLIB_ACQUIRE(*ptr->item)
112 NLIB_NO_THREAD_SAFETY_ANALYSIS {
115 handle_table_ = handle_table;
116 handle_maker::LockHandleBody<HBODY>(ptr->item);
119 detail::HandleData<HBODY>* ptr_;
126 template<
class HBODY>
128 int32_t old_handle = ptr_->handle;
129 if (old_handle != 0) {
138 template<
class HBODY>
140 #if (defined(__GLIBCXX__) && __GLIBCXX__ >= 20140911) || \ 141 defined(_LIBCPP_VERSION) 158 handle = (handle ^ ptr_->mask) >> 2;
159 return static_cast<size_t>(handle) & (N - 1);
162 if (++ptr_->base_count == 1024 * 1024) ptr_->base_count = 0;
163 uint32_t salt =
static_cast<uint32_t
>(ptr_->base_count);
164 salt |= ((salt + 1) << 10) | ((salt + 2) << 20);
165 uint32_t handle =
static_cast<uint32_t
>(idx + (salt * N));
166 return static_cast<int>((handle << 2) ^ ptr_->mask);
169 NLIB_NOEXCEPT NLIB_REQUIRES(*data->item) NLIB_RELEASE(*data->item)
170 NLIB_NO_THREAD_SAFETY_ANALYSIS {
171 HBODY* x = data->item;
172 handle_maker::UnlockHandleBody<HBODY>(data->item);
177 handle_maker::DestroyHandleBody<HBODY>(x);
187 template<
class HBODY>
191 template<
class HBODY>
196 int32_t expected = 0;
197 int32_t mask = detail::GenerateHandleMakerMask();
203 detail::HandleData<HBODY>* data;
206 idx = (ptr_->cur) & (N - 1);
208 data = &ptr_->table[idx];
209 int32_t expected = 0;
213 size_t from = idx + 1;
214 for (; idx < N; ++idx) {
215 data = &ptr_->table[idx];
219 goto CREATE_HANDLE_SUCCESS;
222 for (idx = 0; idx < from; ++idx) {
223 data = &ptr_->table[idx];
227 goto CREATE_HANDLE_SUCCESS;
230 for (; idx < N; ++idx) {
231 data = &ptr_->table[idx];
235 goto CREATE_HANDLE_SUCCESS;
238 for (idx = 0; idx < from; ++idx) {
239 data = &ptr_->table[idx];
243 goto CREATE_HANDLE_SUCCESS;
250 CREATE_HANDLE_SUCCESS:
252 data->handle = this->GetHandleFromIdx(idx);
254 *handle = data->handle;
258 template<
class HBODY>
264 detail::HandleData<HBODY>* data;
270 idx = this->GetIdxFromHandle(handle);
275 data = &ptr_->table[idx];
277 if (old_cnt <= 0)
return EBADF;
282 if (old_cnt <= 0)
return EBADF;
285 access->Init(data, ptr_);
294 template<
class HBODY>
304 #endif // INCLUDE_NN_NLIB_HANDLEMAKER_H_ A total number of handles that access the HBODY type can be obtained through the data member size of ...
void LockHandleBody(HBODY *body) noexcept
Called when the HandleAccess<HBODY> object is given by HandleMaker<HBODY>::GetHandleAccess().
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
void UnlockHandleBody(HBODY *body) noexcept
Called when the HandleAccess object is destroyed.
A class supporting the implementation of handles with a 32-bit integer value.
void DestroyHandleBody(HBODY *body) noexcept
Called from the HandleMaker object to destroy a handle instance.
bool IsHandleBodyEnabled(HBODY *body) noexcept
Returns if the handle instance is valid or not.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
A table referencing handle instances used by the HandlerMaker class.
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
A file that contains the configuration information for each development environment.
TimeSpan operator*(int i, const TimeSpan &rhs) noexcept
Increases rhs by a factor of i.
An accessor class that can access the handle instance as if it is a pointer. It becomes available aft...
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
constexpr HandleAccess() noexcept
Instantiates the object with default parameters (default constructor).
#define NLIB_STATIC_ASSERT(exp)
Defines a static assertion. Uses static_assert if it is available for use.