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
3 changes: 1 addition & 2 deletions deps/message-port/message-port.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,10 @@ class EXPORT_API Port {
void OnMessage(const OnMessageCallback& callback);
void Unref();

Port();
~Port();

private:
Port();

Result PostMessageAsync(std::shared_ptr<MessageEvent> event);

struct Internal;
Expand Down
17 changes: 13 additions & 4 deletions deps/node/src/lwnode/lwnode-public.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class Runtime::Internal {
Internal() {
LWNODE_DEV_LOG("[Runtime::Internal::Internal] new");

// Ensure that builtin file is loaded before initializing node.
native_module::initializeLWNodeBuiltinFile();
init_future_ = init_promise_.get_future();
runner_.SetInitPromise(std::move(init_promise_));
}

std::pair<bool, int> Init(int argc, char** argv) {
Expand Down Expand Up @@ -149,6 +149,8 @@ class Runtime::Internal {
Runtime::Configuration config_;
std::atomic<State> state_{State::kNotInitialized};
std::mutex stop_mutex_;
std::promise<void> init_promise_;
std::future<void> init_future_;
};

/**************************************************************************
Expand All @@ -168,7 +170,7 @@ Runtime::~Runtime() {
LWNODE_DEV_LOG("[Runtime::~Runtime]");
}

int Runtime::Start(int argc, char** argv, std::promise<void>&& promise) {
int Runtime::Start(int argc, char** argv) {
LWNODE_PERF_LOG("[Runtime::Start]");
LWNODE_DEV_LOG("[Runtime] version: %s", LWNODE_VERSION_TAG);
#if defined(NDEBUG)
Expand All @@ -177,7 +179,6 @@ int Runtime::Start(int argc, char** argv, std::promise<void>&& promise) {
LWNODE_DEV_LOG("[Runtime] debug mode");
#endif

internal_->runner_.SetInitPromise(std::move(promise));
std::pair<bool, int> init_result = internal_->Init(argc, argv);

if (init_result.first) {
Expand All @@ -199,6 +200,14 @@ std::shared_ptr<Port> Runtime::GetPort() {
return internal_->runner_.GetPort();
}

std::future_status Runtime::WaitForReady(int64_t ms) {
if (ms < 0) {
internal_->init_future_.wait();
return std::future_status::ready;
}
return internal_->init_future_.wait_for(std::chrono::milliseconds(ms));
}

/**************************************************************************
* Runtime::Configuration class
**************************************************************************/
Expand Down
5 changes: 2 additions & 3 deletions deps/node/src/node_main_lw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ int main(int argc, char* argv[]) {
// FIXME: Fix Runtime::Init() call to ensure environment initialization
// before running the loop, Runtime::Run(). This workaround passes a
// promise directly to know when that is.
std::promise<void> promise;

if (lwnode::ParseAULEvent(argc, argv)) {
if (!lwnode::InitScriptRootPath()) {
Expand All @@ -85,9 +84,9 @@ int main(int argc, char* argv[]) {

char* args[] = {
const_cast<char*>(""), const_cast<char*>("index.js"), nullptr};
return runtime.Start(2, args, std::move(promise));
return runtime.Start(2, args);
}

// started by command line
return runtime.Start(argc, argv, std::move(promise));
return runtime.Start(argc, argv);
}
4 changes: 3 additions & 1 deletion deps/node/src/node_main_lw_runner-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ class LWNodeMainRunner {
}

std::shared_ptr<Port> GetPort() {
CHECK_NOT_NULL(environment_);
if (!environment_) {
return std::make_shared<Port>();
}
return environment_->GetPort();
}

Expand Down
7 changes: 2 additions & 5 deletions examples/tizen/message-port/src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ int main(int argc, char* argv[]) {
dlog_print(
DLOG_INFO, APP_LOG_TAG, "[Native] message-port example app started...");

std::promise<void> promise;
std::future<void> init_future = promise.get_future();

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

std::thread t([&]() {
Expand All @@ -36,13 +33,13 @@ int main(int argc, char* argv[]) {
const_cast<char*>(""), const_cast<char*>("index.js"), nullptr};

dlog_print(DLOG_INFO, APP_LOG_TAG, "[Native] runtime.Start() called...");
runtime->Start(2, args, std::move(promise));
runtime->Start(2, args);

dlog_print(DLOG_INFO, APP_LOG_TAG, "[Native] end thread");
});

// Wait until the js script is initialized to get the port.
init_future.wait();
runtime->WaitForReady();

std::shared_ptr<Port> port = runtime->GetPort();

Expand Down
26 changes: 21 additions & 5 deletions include/lwnode/lwnode-public.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,36 @@ class LWNODE_EXPORT Runtime {
* @param argc - Argument count.
* @param argv - Argument vector. The element should be the starting file
* name of the application.
* @param promise - Promise object. It will be set when the runtime
* initialization is complete.
* @return Returns the exit code of the runtime.
**/
int Start(int argc, char** argv, std::promise<void>&& promise);
int Start(int argc, char** argv);

/**
* Stop the runtime. You can use this function to stop the runtime from another
* thread.
* Stop the runtime. You can use this function to stop the runtime from
* another thread.
**/
void Stop();

/**
* Get the message port instance.
*
* @return Returns the shared pointer of the message port instance. If the
* runtime is not ready, it returns the unavailable port instance. Otherwise,
* it returns the shared pointer of the available message port instance.
*
**/
std::shared_ptr<Port> GetPort();

/**
* Wait until the runtime is ready.
*
* @param ms - Timeout in milliseconds. If it is negative, it waits
* indefinitely.
* @return Returns the status of the future object. If it is ready, the
* runtime is ready.
**/
std::future_status WaitForReady(int64_t ms = -1);

private:
class Internal;
Internal* internal_ = nullptr;
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 @@ -18,5 +18,5 @@

#define LWNODE_VERSION_MAJOR 1
#define LWNODE_VERSION_MINOR 0
#define LWNODE_VERSION_PATCH 11
#define LWNODE_VERSION_TAG "v1.0.11"
#define LWNODE_VERSION_PATCH 12
#define LWNODE_VERSION_TAG "v1.0.12"
3 changes: 1 addition & 2 deletions include/lwnode/message-port.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,10 @@ class EXPORT_API Port {
void OnMessage(const OnMessageCallback& callback);
void Unref();

Port();
~Port();

private:
Port();

Result PostMessageAsync(std::shared_ptr<MessageEvent> event);

struct Internal;
Expand Down
54 changes: 18 additions & 36 deletions test/embedding/embedtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ std::string getTimestamp() {
TEST0(Embedtest, MessagePort2_Post_Many_JS_First) {
auto runtime = std::make_shared<lwnode::Runtime>();

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-02-message-port-many.js";
std::string path = (std::filesystem::current_path() / script).string();

Expand All @@ -42,13 +40,10 @@ TEST0(Embedtest, MessagePort2_Post_Many_JS_First) {
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));
std::thread worker =
std::thread([&]() mutable { runtime->Start(COUNT_OF(args), args); });

init_future.wait();
runtime->WaitForReady();

int count1 = 0;

Expand Down Expand Up @@ -83,22 +78,18 @@ TEST0(Embedtest, Restart) {
for (int i = 0; i < 3; i++) {
auto runtime = std::make_shared<lwnode::Runtime>();

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-21-runtime-hello.js";
std::string path = (std::filesystem::current_path() / script).string();

char* args[] = {const_cast<char*>(""), const_cast<char*>(path.c_str())};

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

init_future.wait();
runtime->WaitForReady();
worker.join();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Expand All @@ -113,8 +104,6 @@ TEST0(Embedtest, RestartAfterStop) {
for (int i = 0; i < 3; i++) {
auto runtime = std::make_shared<lwnode::Runtime>();

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-22-runtime-heartbeat.js";
std::string path = (std::filesystem::current_path() / script).string();

Expand All @@ -124,15 +113,13 @@ TEST0(Embedtest, RestartAfterStop) {
const_cast<char*>(path.c_str())};

std::cout << ++count << "Thread " << std::endl;
std::thread worker = std::thread(
[&](std::promise<void>&& promise) mutable {
std::cout << count << " Start " << std::endl;
runtime->Start(COUNT_OF(args), args, std::move(promise));
std::cout << count << " /Start " << std::endl;
},
std::move(promise));
std::thread worker = std::thread([&]() mutable {
std::cout << count << " Start " << std::endl;
runtime->Start(COUNT_OF(args), args);
std::cout << count << " /Start " << std::endl;
});

init_future.wait();
runtime->WaitForReady();

std::this_thread::sleep_for(std::chrono::seconds(3));
runtime->Stop();
Expand All @@ -146,8 +133,6 @@ TEST0(Embedtest, RestartAfterStop) {
TEST(Embedtest, MessagePortErrorAfterRegisterOnMessage, 5000) {
auto runtime = std::make_shared<lwnode::Runtime>();

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-04-message-port-error.js";
std::string path = (std::filesystem::current_path() / script).string();

Expand All @@ -156,13 +141,10 @@ TEST(Embedtest, MessagePortErrorAfterRegisterOnMessage, 5000) {
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));
std::thread worker =
std::thread([&]() mutable { runtime->Start(COUNT_OF(args), args); });

init_future.wait();
runtime->WaitForReady();

int count1 = 0;

Expand Down
39 changes: 27 additions & 12 deletions test/embedding/example.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <chrono>
#include <filesystem>
#include <future>
#include <iostream>
Expand All @@ -18,26 +19,40 @@ int main(int argc, char* argv[]) {
}
auto runtime = std::make_shared<lwnode::Runtime>(std::move(configuration));

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-01-message-port-basic.js";
std::string path = (std::filesystem::current_path() / script).string();
char* args[] = {const_cast<char*>(""), const_cast<char*>(path.c_str())};

std::thread worker = std::thread(
[&](std::promise<void>&& promise) mutable {
// FIXME: Fix Runtime::Init() call to ensure environment initialization
// before running the loop, Runtime::Run(). This workaround passes a
// promise directly to know when that is.
auto result = runtime->Start(COUNT_OF(args), args, std::move(promise));
std::cout << "result: " << result << std::endl;
},
std::move(promise));
std::thread worker = std::thread([&]() mutable {
// FIXME: Fix Runtime::Init() call to ensure environment initialization
// before running the loop, Runtime::Run(). This workaround passes a
// promise directly to know when that is.
int result = 0;
do {
std::cout << "start runtime" << std::endl;
result = runtime->Start(COUNT_OF(args), args);
std::cout << "result: " << result << std::endl;

init_future.wait();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
} while (result == 100);
});

while (true) {
std::future_status status = runtime->WaitForReady(50);
if (status == std::future_status::timeout) {
std::cout << "runtime is not ready: timeout" << std::endl;
} else if (status == std::future_status::deferred) {
std::cout << "runtime is not ready: deferred" << std::endl;
} else if (status == std::future_status::ready) {
std::cout << "runtime is ready" << std::endl;
break;
}
}

int count1 = 0;
auto port2 = runtime->GetPort();
std::cout << "done get port" << std::endl;

port2->OnMessage([&](const MessageEvent* event) {
std::cout << event->data() << std::endl;
count1++;
Expand Down
11 changes: 3 additions & 8 deletions test/embedding/message-port-sync.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,14 @@ std::string CallMethod(Port* port, const std::string& function) {
int main(int argc, char* argv[]) {
auto runtime = std::make_shared<lwnode::Runtime>();

std::promise<void> promise;
std::future<void> init_future = promise.get_future();
const char* script = "test/embedding/test-03-message-port-sync.js";
std::string path = (std::filesystem::current_path() / script).string();
char* args[] = {const_cast<char*>(""), const_cast<char*>(path.c_str())};

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

init_future.wait();
runtime->WaitForReady();

auto port2 = runtime->GetPort();
port2->OnMessage([&](const MessageEvent* event) {
Expand Down
Loading