Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion deps/node/src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,16 @@ std::string GetExecPath(const std::vector<std::string>& argv) {
return exec_path;
}

std::unique_ptr<node::ChannelHolder> ChannelHolder::instance;

void ChannelHolder::Init() {
channel_ = Channel::New(uv_promise_.get_future(), "embedder");
}

std::shared_ptr<Port> ChannelHolder::GetPort() {
return channel_.port1;
}

Environment::Environment(IsolateData* isolate_data,
Local<Context> context,
const std::vector<std::string>& args,
Expand Down Expand Up @@ -359,7 +369,15 @@ Environment::Environment(IsolateData* isolate_data,
}

#if defined(LWNODE)
channel_ = Channel::New(uv_promise_.get_future(), "embedder");
if (ChannelHolder::instance != nullptr) {
// channel.port1 is already being used.
channel_ = ChannelHolder::instance->channel_;
uv_promise_ = std::move(ChannelHolder::instance->uv_promise_);
ChannelHolder::instance.reset();
} else {
channel_ = Channel::New(uv_promise_.get_future(), "embedder");
}

main_message_port_ =
new MainMessagePort(channel_.port2, std::move(uv_promise_));
loop_holder_ = new LoopHolderUV(isolate_data->event_loop());
Expand Down
13 changes: 13 additions & 0 deletions deps/node/src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,19 @@ class Environment : public MemoryRetainer {
#endif
};

class ChannelHolder {
public:
ChannelHolder() = default;
void Init();
std::shared_ptr<Port> GetPort();
static std::unique_ptr<node::ChannelHolder> instance;

private:
std::promise<uv_loop_t*> uv_promise_;
Channel channel_;
friend class Environment;
};

} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Expand Down
4 changes: 4 additions & 0 deletions deps/node/src/node_errors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ static std::string GetErrorSource(Isolate* isolate,
sourceline.c_str());
CHECK_GT(buf.size(), 0);

// @lwnode
start = std::min(start, (int)sourceline.length());
end = std::min(end, (int)sourceline.length());

constexpr int kUnderlineBufsize = 1020;
char underline_buf[kUnderlineBufsize + 4];
int off = 0;
Expand Down
14 changes: 13 additions & 1 deletion deps/node/src/node_main_lw_runner-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ class LoopStrategy : public MainLoopStrategy {

class LWNodeMainRunner {
public:
LWNodeMainRunner() { ChannelHolder::instance.reset(); }

~LWNodeMainRunner() {
LWNODE_DEV_LOG("[LWNodeMainRunner::~LWNodeMainRunner]");
}
Expand Down Expand Up @@ -233,7 +235,17 @@ class LWNodeMainRunner {
}

std::shared_ptr<Port> GetPort() {
CHECK_NOT_NULL(environment_);
if (environment_ == nullptr) {
if (ChannelHolder::instance == nullptr) {
ChannelHolder::instance = std::make_unique<ChannelHolder>();
ChannelHolder::instance->Init();
}
return ChannelHolder::instance->GetPort();
} else {
if (ChannelHolder::instance) {
ChannelHolder::instance.reset();
}
}
return environment_->GetPort();
}

Expand Down
4 changes: 2 additions & 2 deletions include/lwnode/lwnode-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
#pragma once

#define LWNODE_VERSION_MAJOR 1
#define LWNODE_VERSION_MINOR 0
#define LWNODE_VERSION_MINOR 1
#define LWNODE_VERSION_PATCH 9
#define LWNODE_VERSION_TAG "v1.0.9"
#define LWNODE_VERSION_TAG "v1.1.9"
44 changes: 44 additions & 0 deletions test/embedding/embedtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,50 @@ TEST0(Embedtest, MessagePort2_Post_Many_JS_First) {
EXPECT_EQ(count1, 10);
}

TEST0(Embedtest, MessagePort2_Post_JS_First) {
int count1 = 0;

auto runtime = std::make_shared<lwnode::Runtime>();

// 1. Set OnMessage before starting the runtime
auto port2 = runtime->GetPort();
port2->OnMessage([&](const MessageEvent* event) {
count1++;
if (event->data() == "ping") {
auto extra = std::to_string(count1);
std::cout << getTimestamp() << " NS pong " + extra << std::endl;
port2->PostMessage(MessageEvent::New("pong " + extra));
} else {
std::cout << getTimestamp() << " NS ping" << std::endl;
port2->PostMessage(MessageEvent::New("ping"));
}
});

// 2. Start the runtime
std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-05-message-port-first.js";
std::string path = (std::filesystem::current_path() / script).string();

const bool post_first = true;
char* args[] = {const_cast<char*>(""),
const_cast<char*>(path.c_str()),
const_cast<char*>(std::to_string(post_first).c_str())};

std::thread worker = std::thread(
[&](std::promise<void>&& promise) mutable {
runtime->Start(COUNT_OF(args), args, std::move(promise));
},
std::move(promise));

// 3. Wait for the entry script to run
init_future.wait();

worker.join();

EXPECT_EQ(count1, 1);
}

TEST0(Embedtest, Restart) {
TEST_SKIP("This is not yet production-ready.");

Expand Down
31 changes: 31 additions & 0 deletions test/embedding/test-05-message-port-first.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const lwnode = process.lwnode;
const port = process.lwnode.port;
const post_first = +process.argv[2];

lwnode.ref();

function getTimestamp() {
const now = new Date();
return now.toISOString().slice(14, 23);
}

lwnode.postMessage(`ping`);

const stop_count = 1;
let count = 0;

lwnode.onmessage = async (event) => {
if (stop_count <= ++count) {
console.log(`${getTimestamp()} JS stop`);
lwnode.unref();
return;
}

if (event.data == "ping") {
console.log(`${getTimestamp()} JS pong`);
lwnode.postMessage(`pong ${count}`);
} else {
console.log(`${getTimestamp()} JS ping`);
lwnode.postMessage(`ping`);
}
};