Skip to content

Commit

Permalink
refactor: refactor runtime management
Browse files Browse the repository at this point in the history
  • Loading branch information
hans00 committed Sep 24, 2024
1 parent 49b1e88 commit 7d500a4
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 100 deletions.
7 changes: 1 addition & 6 deletions android/cpp-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ Java_com_jsiudp_JsiUdpModule_nativeInstall(JNIEnv *env, jclass _, jlong jsiPtr,
}->cthis()->getCallInvoker()
};

manager = std::make_shared<jsiudp::UdpManager>(
*runtime,
[=](std::function<void()> &&f) {
jsCallInvoker->invokeAsync(std::move(f));
}
);
manager = std::make_shared<jsiudp::UdpManager>(runtime, std::move(jsCallInvoker));
}

extern "C"
Expand Down
6 changes: 3 additions & 3 deletions cpp/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
131 changes: 64 additions & 67 deletions cpp/react-native-jsi-udp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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<int>(SOL_SOCKET));
global.setProperty(jsiRuntime, "dgc_IPPROTO_IP", static_cast<int>(IPPROTO_IP));
global.setProperty(jsiRuntime, "dgc_IPPROTO_IPV6", static_cast<int>(IPPROTO_IPV6));
global.setProperty(jsiRuntime, "dgc_SO_REUSEADDR", static_cast<int>(SO_REUSEADDR));
global.setProperty(jsiRuntime, "dgc_SO_REUSEPORT", static_cast<int>(SO_REUSEPORT));
global.setProperty(jsiRuntime, "dgc_SO_BROADCAST", static_cast<int>(SO_BROADCAST));
global.setProperty(jsiRuntime, "dgc_SO_RCVBUF", static_cast<int>(SO_RCVBUF));
global.setProperty(jsiRuntime, "dgc_SO_SNDBUF", static_cast<int>(SO_SNDBUF));
global.setProperty(jsiRuntime, "dgc_IP_MULTICAST_TTL", static_cast<int>(IP_MULTICAST_TTL));
global.setProperty(jsiRuntime, "dgc_IP_MULTICAST_LOOP", static_cast<int>(IP_MULTICAST_LOOP));
global.setProperty(jsiRuntime, "dgc_IP_ADD_MEMBERSHIP", static_cast<int>(IP_ADD_MEMBERSHIP));
global.setProperty(jsiRuntime, "dgc_IP_DROP_MEMBERSHIP", static_cast<int>(IP_DROP_MEMBERSHIP));
global.setProperty(jsiRuntime, "dgc_IP_TTL", static_cast<int>(IP_TTL));
}

eventThread = thread(&UdpManager::receiveEvent, this);
UdpManager::UdpManager(Runtime *jsiRuntime, std::shared_ptr<CallInvoker> 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<int>(SOL_SOCKET));
global.setProperty(*_runtime, "dgc_IPPROTO_IP", static_cast<int>(IPPROTO_IP));
global.setProperty(*_runtime, "dgc_IPPROTO_IPV6", static_cast<int>(IPPROTO_IPV6));
global.setProperty(*_runtime, "dgc_SO_REUSEADDR", static_cast<int>(SO_REUSEADDR));
global.setProperty(*_runtime, "dgc_SO_REUSEPORT", static_cast<int>(SO_REUSEPORT));
global.setProperty(*_runtime, "dgc_SO_BROADCAST", static_cast<int>(SO_BROADCAST));
global.setProperty(*_runtime, "dgc_SO_RCVBUF", static_cast<int>(SO_RCVBUF));
global.setProperty(*_runtime, "dgc_SO_SNDBUF", static_cast<int>(SO_SNDBUF));
global.setProperty(*_runtime, "dgc_IP_MULTICAST_TTL", static_cast<int>(IP_MULTICAST_TTL));
global.setProperty(*_runtime, "dgc_IP_MULTICAST_LOOP", static_cast<int>(IP_MULTICAST_LOOP));
global.setProperty(*_runtime, "dgc_IP_ADD_MEMBERSHIP", static_cast<int>(IP_ADD_MEMBERSHIP));
global.setProperty(*_runtime, "dgc_IP_DROP_MEMBERSHIP", static_cast<int>(IP_DROP_MEMBERSHIP));
global.setProperty(*_runtime, "dgc_IP_TTL", static_cast<int>(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<void()> &&f) {
if (_callInvoker) {
_callInvoker->invokeAsync(std::move(f));
}
}

JSI_HOST_FUNCTION(UdpManager::create) {
Expand All @@ -237,7 +236,7 @@ JSI_HOST_FUNCTION(UdpManager::create) {

JSI_HOST_FUNCTION(UdpManager::startWorker) {
auto fd = static_cast<int>(arguments[0].asNumber());
auto handler = make_shared<Function>(arguments[1].asObject(runtime).asFunction(runtime));
auto handler = std::make_shared<Function>(arguments[1].asObject(runtime).asFunction(runtime));
if (running.count(fd) > 0 && running[fd]) {
throw JSError(runtime, "E_ALREADY_RUNNING");
}
Expand All @@ -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();
}
Expand Down Expand Up @@ -502,7 +501,7 @@ void UdpManager::receiveEvent() {
while (!_invalidate) {
std::unique_lock<std::mutex> lock(mutex);
cond.wait(lock, [this] { return _invalidate || !events.empty(); });
if (_invalidate || runOnJS == nullptr) {
if (_invalidate) {
break;
}
auto event = events.front();
Expand All @@ -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<int>(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<int>(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<int>(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);
});
}
}
Expand Down Expand Up @@ -588,17 +587,15 @@ 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)
});
}

::close(fd);
if (!_invalidate) {
sendEvent({ fd, CLOSE, "", 0, "", 0 });
}
sendEvent({ fd, CLOSE, "", 0, "", 0 });
delete[] buffer;
}

Expand Down
13 changes: 8 additions & 5 deletions cpp/react-native-jsi-udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
#endif

namespace jsiudp {
typedef std::function<void(std::function<void()> &&)> RunOnJS;

enum EventType {
MESSAGE,
ERROR,
Expand All @@ -51,14 +49,17 @@ namespace jsiudp {

class UdpManager {
public:
UdpManager(facebook::jsi::Runtime &jsiRuntime, RunOnJS runOnJS);
UdpManager(
facebook::jsi::Runtime *jsiRuntime,
std::shared_ptr<facebook::react::CallInvoker> callInvoker
);
~UdpManager();

void invalidate();

protected:
facebook::jsi::Runtime &_runtime;
RunOnJS runOnJS;
facebook::jsi::Runtime *_runtime;
std::shared_ptr<facebook::react::CallInvoker> _callInvoker;
std::map<int, std::thread> workers;
std::map<int, bool> running;
std::atomic<bool> _invalidate = false;
Expand All @@ -74,6 +75,8 @@ namespace jsiudp {
JSI_HOST_FUNCTION(close);
JSI_HOST_FUNCTION(getSockName);

void runOnJS(std::function<void()> &&f);

void workerLoop(int fd);
void sendEvent(Event event);
void receiveEvent();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 5 additions & 17 deletions ios/JsiUdp.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ @implementation JsiUdp
std::shared_ptr<jsiudp::UdpManager> _manager;

- (void)invalidate {
if (_manager != nullptr)
if (_manager) {
_manager->invalidate();
}
}

- (void)setBridge:(RCTBridge *)bridge {
Expand All @@ -30,24 +31,14 @@ void installApi(
std::shared_ptr<facebook::react::CallInvoker> callInvoker,
facebook::jsi::Runtime *runtime
) {
_manager = std::make_shared<jsiudp::UdpManager>(
*runtime,
[=](std::function<void()> &&f) {
callInvoker->invokeAsync(std::move(f));
}
);
NSLog(@"JsiUdp installed");
_manager = std::make_shared<jsiudp::UdpManager>(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);
Expand All @@ -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<facebook::react::NativeJsiUdpSpecJSI>(params);
}
Expand Down

0 comments on commit 7d500a4

Please sign in to comment.