Skip to content

Commit

Permalink
Merge pull request #714 from Chilledheart/harmony_fix_broken_start_st…
Browse files Browse the repository at this point in the history
…op_worker

harmony: fix broken start/stop worker
  • Loading branch information
Chilledheart authored Jan 31, 2024
2 parents e69a7b6 + beed2ae commit 76a1acb
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 32 deletions.
2 changes: 1 addition & 1 deletion harmony/entry/src/main/cpp/types/libyass/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export const getCipherStrings: () => string[];
export const getTimeout: () => number;
export const init: () => void;
export const destroy: () => void;
export const startWorker: (cb: (err_code: number) => void) => void;
export const startWorker: (cb: (err_msg: string) => void) => void;
export const stopWorker: (cb: () => void) => void;
8 changes: 4 additions & 4 deletions harmony/entry/src/main/ets/pages/DetailPage.ets
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ struct DetailPage {

onStartClicked() {
this.state = StartState.STARTING;
yass.startWorker((error_code: number) => {
hilog.info(0x0000, 'yass', 'started %d', error_code);
if (error_code == 0) {
yass.startWorker((err_msg: string) => {
hilog.info(0x0000, 'yass', 'started %s', err_msg);
if (err_msg == '') {
this.state = StartState.STARTED;
AlertDialog.show({ message: 'The start is successful' })
} else {
this.state = StartState.STOPPED;
AlertDialog.show({ message: 'The start failed' })
AlertDialog.show({ message: 'The start failed: ' + err_msg })
}
})
}
Expand Down
95 changes: 68 additions & 27 deletions src/harmony/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,39 +433,63 @@ static napi_value stopTun2proxy(napi_env env, napi_callback_info info) {

static constexpr char kAsyncStartWorkerResourceName[] = "Thread-safe StartWorker";

static void startWorkerCallingJS(napi_env env, napi_value js_cb, void *context, void *data) {
napi_ref thiz_ref = reinterpret_cast<napi_ref>(context);
static void startWorkerCallingJS(napi_env env, napi_value /*js_cb*/, void *context, void *data) {
napi_ref cb_ref = reinterpret_cast<napi_ref>(context);

int err_code = reinterpret_cast<uintptr_t>(data);
std::unique_ptr<asio::error_code> ec(reinterpret_cast<asio::error_code*>(data));
std::ostringstream ss;
if (*ec) {
ss << *ec;
}
std::string ec_str = ss.str();

if (env == nullptr) {
LOG(WARNING) << "null env";
return;
}

napi_value thiz;
napi_status status = napi_get_reference_value(env, thiz_ref, &thiz);
napi_value global;
auto status = napi_get_global(env, &global);
if (status != napi_ok) {
LOG(WARNING) << "napi_get_global: " << status;
return;
}

napi_value cb;
status = napi_get_reference_value(env, cb_ref, &cb);
if (status != napi_ok) {
LOG(WARNING) << "napi_get_reference_value: " << status;
return;
}

napi_value error_code;
status = napi_create_int32(env, err_code, &error_code);
napi_valuetype type;
status = napi_typeof(env, cb, &type);
if (status != napi_ok) {
LOG(WARNING) << "napi_typeof failed: " << status;
return;
}

if (type != napi_function) {
LOG(WARNING) << "napi_typeof unexpected: " << type;
return;
}

napi_value err_msg;
status = napi_create_string_utf8(env, ec_str.c_str(), NAPI_AUTO_LENGTH, &err_msg);
if (status != napi_ok) {
LOG(WARNING) << "napi_create_int32: " << status;
return;
}

napi_value result;
napi_value argv[] = { error_code };
status = napi_call_function(env, thiz, js_cb, std::size(argv), argv, &result);
napi_value argv[] = { err_msg };
status = napi_call_function(env, global, cb, std::size(argv), argv, &result);
if (status != napi_ok) {
LOG(WARNING) << "napi_call_function: " << status;
return;
}

status = napi_delete_reference(env, thiz_ref);
status = napi_delete_reference(env, cb_ref);
if (status != napi_ok) {
LOG(WARNING) << "napi_delete_reference: " << status;
return;
Expand All @@ -479,8 +503,7 @@ static napi_value startWorker(napi_env env, napi_callback_info info) {

napi_value args[1] {};
size_t argc = std::size(args);
napi_value thiz;
status = napi_get_cb_info(env, info, &argc, args, &thiz, nullptr);
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (status != napi_ok || argc != std::size(args)) {
napi_throw_error(env, nullptr, "napi_get_cb_info failed");
return nullptr;
Expand All @@ -499,8 +522,8 @@ static napi_value startWorker(napi_env env, napi_callback_info info) {
return nullptr;
}

napi_ref thiz_ref;
status = napi_create_reference(env, thiz, 1, &thiz_ref);
napi_ref cb_ref;
status = napi_create_reference(env, cb, 1, &cb_ref);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "napi_create_reference failed");
return nullptr;
Expand All @@ -518,7 +541,7 @@ static napi_value startWorker(napi_env env, napi_callback_info info) {

// Create a thread-safe N-API callback function correspond to the C/C++ callback function
status = napi_create_threadsafe_function(env, cb, nullptr, work_name, 0, 1, nullptr,
nullptr, thiz_ref, startWorkerCallingJS, // the C/C++ callback function
nullptr, cb_ref, startWorkerCallingJS, // the C/C++ callback function
&startWorkerCallbackFunc // out: the asynchronous thread-safe JavaScript function
);
if (status != napi_ok) {
Expand All @@ -536,7 +559,7 @@ static napi_value startWorker(napi_env env, napi_callback_info info) {
LOG(WARNING) << "napi_acquire_threadsafe_function: " << status;
}

status = napi_call_threadsafe_function(startWorkerCallbackFunc, (void*)(uintptr_t)ec.value(), napi_tsfn_blocking);
status = napi_call_threadsafe_function(startWorkerCallbackFunc, new asio::error_code(ec), napi_tsfn_blocking);
if (status != napi_ok) {
LOG(WARNING) << "napi_call_threadsafe_function: " << status;
}
Expand All @@ -551,28 +574,47 @@ static napi_value startWorker(napi_env env, napi_callback_info info) {

static constexpr char kAsyncStopWorkerResourceName[] = "Thread-safe StopWorker";

static void stopWorkerCallingJS(napi_env env, napi_value js_cb, void *context, void *data) {
napi_ref thiz_ref = reinterpret_cast<napi_ref>(context);
static void stopWorkerCallingJS(napi_env env, napi_value /*js_cb*/, void *context, void *data) {
napi_ref cb_ref = reinterpret_cast<napi_ref>(context);

if (env == nullptr) {
LOG(WARNING) << "null env";
return;
}

napi_value thiz;
napi_status status = napi_get_reference_value(env, thiz_ref, &thiz);
napi_value global;
auto status = napi_get_global(env, &global);
if (status != napi_ok) {
LOG(WARNING) << "napi_get_global: " << status;
return;
}

napi_value cb;
status = napi_get_reference_value(env, cb_ref, &cb);
if (status != napi_ok) {
LOG(WARNING) << "napi_get_reference_value: " << status;
return;
}

status = napi_call_function(env, thiz, js_cb, 0, nullptr, nullptr);
napi_valuetype type;
status = napi_typeof(env, cb, &type);
if (status != napi_ok) {
LOG(WARNING) << "napi_typeof failed: " << status;
return;
}

if (type != napi_function) {
LOG(WARNING) << "napi_typeof unexpected: " << type;
return;
}

status = napi_call_function(env, global, cb, 0, nullptr, nullptr);
if (status != napi_ok) {
LOG(WARNING) << "napi_call_function: " << status;
return;
}

status = napi_delete_reference(env, thiz_ref);
status = napi_delete_reference(env, cb_ref);
if (status != napi_ok) {
LOG(WARNING) << "napi_delete_reference: " << status;
return;
Expand All @@ -584,8 +626,7 @@ static napi_value stopWorker(napi_env env, napi_callback_info info) {

napi_value args[1] {};
size_t argc = std::size(args);
napi_value thiz;
status = napi_get_cb_info(env, info, &argc, args, &thiz, nullptr);
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (status != napi_ok || argc != std::size(args)) {
napi_throw_error(env, nullptr, "napi_get_cb_info failed");
return nullptr;
Expand All @@ -604,8 +645,8 @@ static napi_value stopWorker(napi_env env, napi_callback_info info) {
return nullptr;
}

napi_ref thiz_ref;
status = napi_create_reference(env, thiz, 1, &thiz_ref);
napi_ref cb_ref;
status = napi_create_reference(env, cb, 1, &cb_ref);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "napi_create_reference failed");
return nullptr;
Expand All @@ -623,7 +664,7 @@ static napi_value stopWorker(napi_env env, napi_callback_info info) {

// Create a thread-safe N-API callback function correspond to the C/C++ callback function
status = napi_create_threadsafe_function(env, cb, nullptr, work_name, 0, 1, nullptr,
nullptr, thiz_ref, stopWorkerCallingJS, // the C/C++ callback function
nullptr, cb_ref, stopWorkerCallingJS, // the C/C++ callback function
&stopWorkerCallbackFunc // out: the asynchronous thread-safe JavaScript function
);
if (status != napi_ok) {
Expand Down

0 comments on commit 76a1acb

Please sign in to comment.