From 7d500a428fdbc65631e621f224f8eee7246021d7 Mon Sep 17 00:00:00 2001 From: Hans Date: Tue, 24 Sep 2024 18:39:46 +0800 Subject: [PATCH] refactor: refactor runtime management --- android/cpp-adapter.cpp | 7 +- cpp/helper.h | 6 +- cpp/react-native-jsi-udp.cpp | 131 +++++++++--------- cpp/react-native-jsi-udp.h | 13 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ example/ios/Podfile.lock | 4 +- ios/JsiUdp.mm | 22 +-- 7 files changed, 91 insertions(+), 100 deletions(-) create mode 100644 example/ios/JsiUdpExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/android/cpp-adapter.cpp b/android/cpp-adapter.cpp index a968a73..90a963a 100644 --- a/android/cpp-adapter.cpp +++ b/android/cpp-adapter.cpp @@ -16,12 +16,7 @@ Java_com_jsiudp_JsiUdpModule_nativeInstall(JNIEnv *env, jclass _, jlong jsiPtr, }->cthis()->getCallInvoker() }; - manager = std::make_shared( - *runtime, - [=](std::function &&f) { - jsCallInvoker->invokeAsync(std::move(f)); - } - ); + manager = std::make_shared(runtime, std::move(jsCallInvoker)); } extern "C" diff --git a/cpp/helper.h b/cpp/helper.h index b759b92..86f3a6f 100644 --- a/cpp/helper.h +++ b/cpp/helper.h @@ -11,12 +11,12 @@ #define EXPOSE_FN(RUNTIME, NAME, ARGC, FUNCTION) \ { \ auto NAME = Function::createFromHostFunction( \ - RUNTIME, \ - facebook::jsi::PropNameID::forAscii(RUNTIME, #NAME), \ + (RUNTIME), \ + facebook::jsi::PropNameID::forAscii((RUNTIME), #NAME), \ ARGC, \ FUNCTION \ ); \ - RUNTIME.global().setProperty(RUNTIME, #NAME, std::move(NAME)); \ + (RUNTIME).global().setProperty((RUNTIME), #NAME, std::move(NAME)); \ } #define BIND_METHOD(METHOD) \ diff --git a/cpp/react-native-jsi-udp.cpp b/cpp/react-native-jsi-udp.cpp index 51f937e..0c1fbda 100644 --- a/cpp/react-native-jsi-udp.cpp +++ b/cpp/react-native-jsi-udp.cpp @@ -32,11 +32,10 @@ using namespace facebook::jsi; using namespace facebook::react; -using namespace std; namespace jsiudp { -string error_name(int err) { +std::string error_name(int err) { switch (err) { case EACCES: return "EACCES"; @@ -163,54 +162,54 @@ int setupIface(int fd, struct sockaddr_in6 &addr) { return 0; } -UdpManager::UdpManager(Runtime &jsiRuntime, RunOnJS runOnJS) : _runtime(jsiRuntime), runOnJS(runOnJS) { - EXPOSE_FN(jsiRuntime, datagram_create, 1, BIND_METHOD(UdpManager::create)); - EXPOSE_FN(jsiRuntime, datagram_startWorker, 2, BIND_METHOD(UdpManager::startWorker)); - EXPOSE_FN(jsiRuntime, datagram_bind, 4, BIND_METHOD(UdpManager::bind)); - EXPOSE_FN(jsiRuntime, datagram_send, 5, BIND_METHOD(UdpManager::send)); - EXPOSE_FN(jsiRuntime, datagram_close, 1, BIND_METHOD(UdpManager::close)); - EXPOSE_FN(jsiRuntime, datagram_getOpt, 3, BIND_METHOD(UdpManager::getOpt)); - EXPOSE_FN(jsiRuntime, datagram_setOpt, 5, BIND_METHOD(UdpManager::setOpt)); - EXPOSE_FN(jsiRuntime, datagram_getSockName, 2, BIND_METHOD(UdpManager::getSockName)); - - { - auto global = jsiRuntime.global(); - - global.setProperty(jsiRuntime, "dgc_SOL_SOCKET", static_cast(SOL_SOCKET)); - global.setProperty(jsiRuntime, "dgc_IPPROTO_IP", static_cast(IPPROTO_IP)); - global.setProperty(jsiRuntime, "dgc_IPPROTO_IPV6", static_cast(IPPROTO_IPV6)); - global.setProperty(jsiRuntime, "dgc_SO_REUSEADDR", static_cast(SO_REUSEADDR)); - global.setProperty(jsiRuntime, "dgc_SO_REUSEPORT", static_cast(SO_REUSEPORT)); - global.setProperty(jsiRuntime, "dgc_SO_BROADCAST", static_cast(SO_BROADCAST)); - global.setProperty(jsiRuntime, "dgc_SO_RCVBUF", static_cast(SO_RCVBUF)); - global.setProperty(jsiRuntime, "dgc_SO_SNDBUF", static_cast(SO_SNDBUF)); - global.setProperty(jsiRuntime, "dgc_IP_MULTICAST_TTL", static_cast(IP_MULTICAST_TTL)); - global.setProperty(jsiRuntime, "dgc_IP_MULTICAST_LOOP", static_cast(IP_MULTICAST_LOOP)); - global.setProperty(jsiRuntime, "dgc_IP_ADD_MEMBERSHIP", static_cast(IP_ADD_MEMBERSHIP)); - global.setProperty(jsiRuntime, "dgc_IP_DROP_MEMBERSHIP", static_cast(IP_DROP_MEMBERSHIP)); - global.setProperty(jsiRuntime, "dgc_IP_TTL", static_cast(IP_TTL)); - } - - eventThread = thread(&UdpManager::receiveEvent, this); +UdpManager::UdpManager(Runtime *jsiRuntime, std::shared_ptr callInvoker): _runtime(jsiRuntime), _callInvoker(callInvoker) { + eventThread = std::thread(&UdpManager::receiveEvent, this); + + EXPOSE_FN(*_runtime, datagram_create, 1, BIND_METHOD(UdpManager::create)); + EXPOSE_FN(*_runtime, datagram_startWorker, 2, BIND_METHOD(UdpManager::startWorker)); + EXPOSE_FN(*_runtime, datagram_bind, 4, BIND_METHOD(UdpManager::bind)); + EXPOSE_FN(*_runtime, datagram_send, 5, BIND_METHOD(UdpManager::send)); + EXPOSE_FN(*_runtime, datagram_close, 1, BIND_METHOD(UdpManager::close)); + EXPOSE_FN(*_runtime, datagram_getOpt, 3, BIND_METHOD(UdpManager::getOpt)); + EXPOSE_FN(*_runtime, datagram_setOpt, 5, BIND_METHOD(UdpManager::setOpt)); + EXPOSE_FN(*_runtime, datagram_getSockName, 2, BIND_METHOD(UdpManager::getSockName)); + + auto global = _runtime->global(); + global.setProperty(*_runtime, "dgc_SOL_SOCKET", static_cast(SOL_SOCKET)); + global.setProperty(*_runtime, "dgc_IPPROTO_IP", static_cast(IPPROTO_IP)); + global.setProperty(*_runtime, "dgc_IPPROTO_IPV6", static_cast(IPPROTO_IPV6)); + global.setProperty(*_runtime, "dgc_SO_REUSEADDR", static_cast(SO_REUSEADDR)); + global.setProperty(*_runtime, "dgc_SO_REUSEPORT", static_cast(SO_REUSEPORT)); + global.setProperty(*_runtime, "dgc_SO_BROADCAST", static_cast(SO_BROADCAST)); + global.setProperty(*_runtime, "dgc_SO_RCVBUF", static_cast(SO_RCVBUF)); + global.setProperty(*_runtime, "dgc_SO_SNDBUF", static_cast(SO_SNDBUF)); + global.setProperty(*_runtime, "dgc_IP_MULTICAST_TTL", static_cast(IP_MULTICAST_TTL)); + global.setProperty(*_runtime, "dgc_IP_MULTICAST_LOOP", static_cast(IP_MULTICAST_LOOP)); + global.setProperty(*_runtime, "dgc_IP_ADD_MEMBERSHIP", static_cast(IP_ADD_MEMBERSHIP)); + global.setProperty(*_runtime, "dgc_IP_DROP_MEMBERSHIP", static_cast(IP_DROP_MEMBERSHIP)); + global.setProperty(*_runtime, "dgc_IP_TTL", static_cast(IP_TTL)); } UdpManager::~UdpManager() { - _invalidate = true; - runOnJS = nullptr; - cond.notify_all(); invalidate(); - eventThread.join(); } void UdpManager::invalidate() { - for (auto &entry : running) { - if (entry.second) ::close(entry.first); - } - running.clear(); + _invalidate = true; + cond.notify_all(); + if (eventThread.joinable()) eventThread.join(); for (auto &entry : workers) { if (entry.second.joinable()) entry.second.join(); } + running.clear(); workers.clear(); + eventHandlers.clear(); +} + +void UdpManager::runOnJS(std::function &&f) { + if (_callInvoker) { + _callInvoker->invokeAsync(std::move(f)); + } } JSI_HOST_FUNCTION(UdpManager::create) { @@ -237,7 +236,7 @@ JSI_HOST_FUNCTION(UdpManager::create) { JSI_HOST_FUNCTION(UdpManager::startWorker) { auto fd = static_cast(arguments[0].asNumber()); - auto handler = make_shared(arguments[1].asObject(runtime).asFunction(runtime)); + auto handler = std::make_shared(arguments[1].asObject(runtime).asFunction(runtime)); if (running.count(fd) > 0 && running[fd]) { throw JSError(runtime, "E_ALREADY_RUNNING"); } @@ -247,9 +246,9 @@ JSI_HOST_FUNCTION(UdpManager::startWorker) { workers[fd].join(); } - eventHandlers[fd] = move(handler); + eventHandlers[fd] = std::move(handler); running[fd] = true; - workers[fd] = thread(&UdpManager::workerLoop, this, fd); + workers[fd] = std::thread(&UdpManager::workerLoop, this, fd); return Value::undefined(); } @@ -502,7 +501,7 @@ void UdpManager::receiveEvent() { while (!_invalidate) { std::unique_lock lock(mutex); cond.wait(lock, [this] { return _invalidate || !events.empty(); }); - if (_invalidate || runOnJS == nullptr) { + if (_invalidate) { break; } auto event = events.front(); @@ -511,50 +510,50 @@ void UdpManager::receiveEvent() { if (eventHandlers.count(event.fd) > 0) { runOnJS([this, &event]() { auto handler = eventHandlers[event.fd]; - auto eventObj = Object(_runtime); + auto eventObj = Object(*_runtime); eventObj.setProperty( - _runtime, + *_runtime, "type", String::createFromAscii( - _runtime, + *_runtime, event.type == MESSAGE ? "message" : event.type == ERROR ? "error" : "close" ) ); if (event.type == MESSAGE) { - auto ArrayBuffer = _runtime.global().getPropertyAsFunction(_runtime, "ArrayBuffer"); + auto ArrayBuffer = _runtime->global().getPropertyAsFunction(*_runtime, "ArrayBuffer"); auto arrayBufferObj = ArrayBuffer - .callAsConstructor(_runtime, static_cast(event.data.size())) - .getObject(_runtime); - auto arrayBuffer = arrayBufferObj.getArrayBuffer(_runtime); - memcpy(arrayBuffer.data(_runtime), event.data.c_str(), event.data.size()); + .callAsConstructor(*_runtime, static_cast(event.data.size())) + .getObject(*_runtime); + auto arrayBuffer = arrayBufferObj.getArrayBuffer(*_runtime); + memcpy(arrayBuffer.data(*_runtime), event.data.c_str(), event.data.size()); eventObj.setProperty( - _runtime, + *_runtime, "data", - move(arrayBuffer) + std::move(arrayBuffer) ); eventObj.setProperty( - _runtime, + *_runtime, "family", - String::createFromAscii(_runtime, event.family == AF_INET ? "IPv4" : "IPv6") + String::createFromAscii(*_runtime, event.family == AF_INET ? "IPv4" : "IPv6") ); eventObj.setProperty( - _runtime, + *_runtime, "address", - String::createFromAscii(_runtime, event.address) + String::createFromAscii(*_runtime, event.address) ); eventObj.setProperty( - _runtime, + *_runtime, "port", static_cast(event.port) ); } else if (event.type == ERROR) { - auto Error = _runtime.global().getPropertyAsFunction(_runtime, "Error"); + auto Error = _runtime->global().getPropertyAsFunction(*_runtime, "Error"); auto errorObj = Error - .callAsConstructor(_runtime, String::createFromAscii(_runtime, event.data)) - .getObject(_runtime); - eventObj.setProperty(_runtime, "error", errorObj); + .callAsConstructor(*_runtime, String::createFromAscii(*_runtime, event.data)) + .getObject(*_runtime); + eventObj.setProperty(*_runtime, "error", errorObj); } - handler->call(_runtime, eventObj); + handler->call(*_runtime, eventObj); }); } } @@ -588,7 +587,7 @@ void UdpManager::workerLoop(int fd) { sendEvent({ fd, MESSAGE, - string(buffer, recvn), + std::string(buffer, recvn), in_addr.sin_family, inet_ntoa(in_addr.sin_addr), ntohs(in_addr.sin_port) @@ -596,9 +595,7 @@ void UdpManager::workerLoop(int fd) { } ::close(fd); - if (!_invalidate) { - sendEvent({ fd, CLOSE, "", 0, "", 0 }); - } + sendEvent({ fd, CLOSE, "", 0, "", 0 }); delete[] buffer; } diff --git a/cpp/react-native-jsi-udp.h b/cpp/react-native-jsi-udp.h index 2da22a1..f86887b 100644 --- a/cpp/react-native-jsi-udp.h +++ b/cpp/react-native-jsi-udp.h @@ -32,8 +32,6 @@ #endif namespace jsiudp { - typedef std::function &&)> RunOnJS; - enum EventType { MESSAGE, ERROR, @@ -51,14 +49,17 @@ namespace jsiudp { class UdpManager { public: - UdpManager(facebook::jsi::Runtime &jsiRuntime, RunOnJS runOnJS); + UdpManager( + facebook::jsi::Runtime *jsiRuntime, + std::shared_ptr callInvoker + ); ~UdpManager(); void invalidate(); protected: - facebook::jsi::Runtime &_runtime; - RunOnJS runOnJS; + facebook::jsi::Runtime *_runtime; + std::shared_ptr _callInvoker; std::map workers; std::map running; std::atomic _invalidate = false; @@ -74,6 +75,8 @@ namespace jsiudp { JSI_HOST_FUNCTION(close); JSI_HOST_FUNCTION(getSockName); + void runOnJS(std::function &&f); + void workerLoop(int fd); void sendEvent(Event event); void receiveEvent(); diff --git a/example/ios/JsiUdpExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/JsiUdpExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/JsiUdpExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 459dceb..721d3f9 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -329,7 +329,7 @@ PODS: - React-jsinspector (0.71.19) - React-logger (0.71.19): - glog - - react-native-jsi-udp (1.1.2): + - react-native-jsi-udp (1.1.3): - React - React-callinvoker - React-Core @@ -608,7 +608,7 @@ SPEC CHECKSUMS: React-jsiexecutor: 7263801e44e004967685dd40672bfcedcda00834 React-jsinspector: e591d9ecb571456fc929ee10409d8847a442d6a7 React-logger: 70ddbe0e07179c8adb94c4bffc36c6abc952d3d4 - react-native-jsi-udp: 910504621aec0e3e78260258156300a3f803898d + react-native-jsi-udp: 4d745134ab79fdea1090e412f04bcaba71af3a4c React-perflogger: 0ba097528e325435aca94b32b5330f58f6acb6fb React-RCTActionSheet: 805b3a83f3dd7ae5a1213ea9df0ed748eeb74b85 React-RCTAnimation: 2a0233681dee47e468302b8233652b35b68329cb diff --git a/ios/JsiUdp.mm b/ios/JsiUdp.mm index 78192d2..7bbf3fe 100644 --- a/ios/JsiUdp.mm +++ b/ios/JsiUdp.mm @@ -14,8 +14,9 @@ @implementation JsiUdp std::shared_ptr _manager; - (void)invalidate { - if (_manager != nullptr) + if (_manager) { _manager->invalidate(); + } } - (void)setBridge:(RCTBridge *)bridge { @@ -30,24 +31,14 @@ void installApi( std::shared_ptr callInvoker, facebook::jsi::Runtime *runtime ) { - _manager = std::make_shared( - *runtime, - [=](std::function &&f) { - callInvoker->invokeAsync(std::move(f)); - } - ); - NSLog(@"JsiUdp installed"); + _manager = std::make_shared(runtime, std::move(callInvoker)); } RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) { RCTCxxBridge *cxxBridge = (RCTCxxBridge *)_bridge; if (cxxBridge.runtime != nullptr) { - auto callInvoker = cxxBridge.jsCallInvoker; - facebook::jsi::Runtime *jsRuntime = - (facebook::jsi::Runtime *)cxxBridge.runtime; - - installApi(callInvoker, jsRuntime); + installApi(cxxBridge.jsCallInvoker, (facebook::jsi::Runtime *)cxxBridge.runtime); return @(true); } return @(false); @@ -59,10 +50,7 @@ void installApi( (const facebook::react::ObjCTurboModule::InitParams &)params { RCTCxxBridge *cxxBridge = (RCTCxxBridge *)_bridge; - auto callInvoker = cxxBridge.jsCallInvoker; - facebook::jsi::Runtime *jsRuntime = (facebook::jsi::Runtime *)cxxBridge.runtime; - - installApi(callInvoker, jsRuntime); + installApi(cxxBridge.jsCallInvoker, (facebook::jsi::Runtime *)cxxBridge.runtime); return std::make_shared(params); }