- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스) - Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포 - 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
128 lines
3.8 KiB
C++
128 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
#include <jsi/jsi.h>
|
|
|
|
namespace facebook::react {
|
|
|
|
/*
|
|
* Takes a function and calls it with a reference to a Runtime. The function
|
|
* will be called when it is safe to do so (i.e. it ensures non-concurrent
|
|
* access) and may be invoked asynchronously, depending on the implementation.
|
|
* If you need to access a Runtime, it's encouraged to use a RuntimeExecutor
|
|
* instead of storing a pointer to the Runtime itself, which makes it more
|
|
* difficult to ensure that the Runtime is being accessed safely.
|
|
*/
|
|
using RuntimeExecutor =
|
|
std::function<void(std::function<void(jsi::Runtime& runtime)>&& callback)>;
|
|
|
|
/*
|
|
* The caller can expect that the callback will be executed sometime later on an
|
|
* unspecified thread.
|
|
* Use this method when the caller prefers to not be blocked by executing the
|
|
* `callback`.
|
|
* Note that this method does not provide any guarantees
|
|
* about when the `callback` will be executed (before returning to the caller,
|
|
* after that, or in parallel), the only thing that is guaranteed is that there
|
|
* is no synchronization.
|
|
*/
|
|
inline static void executeAsynchronously(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<void(jsi::Runtime& runtime)>&& callback) noexcept {
|
|
std::thread([callback = std::move(callback), runtimeExecutor]() mutable {
|
|
runtimeExecutor(std::move(callback));
|
|
}).detach();
|
|
}
|
|
|
|
/*
|
|
* Executes a `callback` in a *synchronous* manner using given
|
|
* `RuntimeExecutor`.
|
|
* Use this method when the caller needs to *be blocked* by executing the
|
|
* callback but does not concerned about the particular thread on which the
|
|
* `callback` will be executed.
|
|
*/
|
|
inline static void executeSynchronously_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<void(jsi::Runtime& runtime)>&& callback) noexcept {
|
|
std::mutex mutex;
|
|
mutex.lock();
|
|
|
|
runtimeExecutor(
|
|
[callback = std::move(callback), &mutex](jsi::Runtime& runtime) {
|
|
callback(runtime);
|
|
mutex.unlock();
|
|
});
|
|
|
|
mutex.lock();
|
|
}
|
|
|
|
/*
|
|
* Executes a `callback` in a *synchronous* manner on the same thread using
|
|
* given `RuntimeExecutor`.
|
|
* Use this method when the caller needs to *be blocked* by executing the
|
|
* `callback` and requires that the callback will be executed on the same
|
|
* thread.
|
|
*/
|
|
inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<void(jsi::Runtime& runtime)>&& callback) noexcept {
|
|
// Note: We need the third mutex to get back to the main thread before
|
|
// the lambda is finished (because all mutexes are allocated on the stack).
|
|
|
|
std::mutex mutex1;
|
|
std::mutex mutex2;
|
|
std::mutex mutex3;
|
|
|
|
mutex1.lock();
|
|
mutex2.lock();
|
|
mutex3.lock();
|
|
|
|
jsi::Runtime* runtimePtr;
|
|
|
|
auto threadId = std::this_thread::get_id();
|
|
|
|
runtimeExecutor([&](jsi::Runtime& runtime) {
|
|
runtimePtr = &runtime;
|
|
|
|
if (threadId == std::this_thread::get_id()) {
|
|
// In case of a synchronous call, we should unlock mutexes and return.
|
|
mutex1.unlock();
|
|
mutex3.unlock();
|
|
return;
|
|
}
|
|
|
|
mutex1.unlock();
|
|
// `callback` is called somewhere here.
|
|
mutex2.lock();
|
|
mutex3.unlock();
|
|
});
|
|
|
|
mutex1.lock();
|
|
callback(*runtimePtr);
|
|
mutex2.unlock();
|
|
mutex3.lock();
|
|
}
|
|
|
|
template <typename DataT>
|
|
inline static DataT executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<DataT(jsi::Runtime& runtime)>&& callback) noexcept {
|
|
DataT data;
|
|
|
|
executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
runtimeExecutor,
|
|
[&](jsi::Runtime& runtime) { data = callback(runtime); });
|
|
|
|
return data;
|
|
}
|
|
} // namespace facebook::react
|