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 \ 106 HandleAccess<HBODY> tmp(ptr_, handle_table_);
108 handle_table_ =
nullptr;
113 HandleAccess(detail::HandleData<HBODY>* ptr, HandleTable<HBODY>* handle_table)
NLIB_NOEXCEPT 115 handle_table_(handle_table) {}
117 Init(detail::HandleData<HBODY>* ptr, HandleTable<HBODY>* handle_table)
NLIB_NOEXCEPT 118 NLIB_EXCLUDES(*ptr->item) NLIB_ACQUIRE(*ptr->item) NLIB_NO_THREAD_SAFETY_ANALYSIS {
121 handle_table_ = handle_table;
122 handle_maker::LockHandleBody<HBODY>(ptr->item);
125 detail::HandleData<HBODY>* ptr_;
126 HandleTable<HBODY>* handle_table_;
128 friend class HandleMaker<HBODY>;
132 template<
class HBODY>
134 int32_t old_handle = ptr_->handle;
135 if (old_handle != 0) {
144 template<
class HBODY>
146 #if (defined(__GLIBCXX__) && __GLIBCXX__ >= 20140911) || defined(_LIBCPP_VERSION) 162 handle = (handle ^ ptr_->mask) >> 2;
163 return static_cast<size_t>(handle) & (N - 1);
166 if (++ptr_->base_count == 1024 * 1024) ptr_->base_count = 0;
167 uint32_t salt =
static_cast<uint32_t
>(ptr_->base_count);
168 salt |= ((salt + 1) << 10) | ((salt + 2) << 20);
169 uint32_t handle =
static_cast<uint32_t
>(idx + (salt * N));
170 return static_cast<int>((handle << 2) ^ ptr_->mask);
173 NLIB_REQUIRES(*data->item) NLIB_RELEASE(*data->item) NLIB_NO_THREAD_SAFETY_ANALYSIS {
174 HBODY* x = data->item;
175 handle_maker::UnlockHandleBody<HBODY>(data->item);
180 handle_maker::DestroyHandleBody<HBODY>(x);
185 HandleTable<HBODY>* ptr_;
186 friend class HandleAccess<HBODY>;
190 template<
class HBODY>
194 template<
class HBODY>
199 int32_t expected = 0;
200 int32_t mask = detail::GenerateHandleMakerMask();
206 detail::HandleData<HBODY>* data;
209 idx = (ptr_->cur) & (N - 1);
211 data = &ptr_->table[idx];
212 int32_t expected = 0;
216 size_t from = idx + 1;
217 for (; idx < N; ++idx) {
218 data = &ptr_->table[idx];
222 goto CREATE_HANDLE_SUCCESS;
225 for (idx = 0; idx < from; ++idx) {
226 data = &ptr_->table[idx];
230 goto CREATE_HANDLE_SUCCESS;
233 for (; idx < N; ++idx) {
234 data = &ptr_->table[idx];
238 goto CREATE_HANDLE_SUCCESS;
241 for (idx = 0; idx < from; ++idx) {
242 data = &ptr_->table[idx];
246 goto CREATE_HANDLE_SUCCESS;
253 CREATE_HANDLE_SUCCESS:
255 data->handle = this->GetHandleFromIdx(idx);
257 *handle = data->handle;
261 template<
class HBODY>
267 detail::HandleData<HBODY>* data;
273 idx = this->GetIdxFromHandle(handle);
278 data = &ptr_->table[idx];
280 if (old_cnt <= 0)
return EBADF;
285 if (old_cnt <= 0)
return EBADF;
288 access->Init(data, ptr_);
297 template<
class HBODY>
307 #endif // INCLUDE_NN_NLIB_HANDLEMAKER_H_ size_t型のstatic constのデータメンバsizeを通してHBODY型へアクセスするハンドルの総数を得ることができま...
void LockHandleBody(HBODY *body) noexcept
HandleAccess<HBODY>オブジェクトがHandleMaker<HBODY>::GetHandleAccess()により与えられる際に呼び出され...
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
void UnlockHandleBody(HBODY *body) noexcept
HandleAccess<HBODY>オブジェクトのデストラクト時に実行されます。
32bit整数値を持つハンドルの実装を支援するクラスです。
void DestroyHandleBody(HBODY *body) noexcept
HandleMakerオブジェクトからハンドルの実体を解体する際に呼び出されます。
bool IsHandleBodyEnabled(HBODY *body) noexcept
ハンドルの実体が有効かどうかを返します。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
HandlerMakerクラスが利用するハンドルの実体への参照テーブルです。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
TimeSpan operator*(int i, const TimeSpan &rhs) noexcept
rhs を i 倍します。
ハンドル実体に対してポインタのようにアクセスできるアクセサクラスです。HandlerMakerクラスにより設定さ...
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
constexpr HandleAccess() noexcept
デフォルトコンストラクタです。
#define NLIB_STATIC_ASSERT(exp)
静的アサートが定義されます。利用可能であればstatic_assertを利用します。