Надстройка узла, использующая процесс узла libuv и uv_async_send, не завершается

У меня есть требование вызвать функцию Javascript из надстройки узла. Аддон будет иметь фоновый поток, который работает непрерывно, так что это не совсем классическое требование к асинхронному рабочему, использующему async_queue_work. Я думаю, что uv_async_send больше подходит для этого сценария. Я хочу поместить функцию в цикл событий узла, которая будет выполняться, как только узел освободится. Эта функция должна выполняться в основном потоке узла.

Для начала у меня есть очень простой аддон, и я экспериментирую с uv_queue_work против uv_async_send. Я могу заставить оба работать, но в случае uv_async_send процесс узла никогда не завершается.

узел-uv.cc

#include <node.h>
#include <uv.h>

using namespace v8;

static void Runner(uv_work_t *req)
{
    printf("Async work running!\n");
}

static void RunDone(uv_work_t *req, int status)
{
    delete req;
    printf("Async work done!\n");
}

static void Runner2(uv_async_t* handle) {
    printf("Got async send!\n");
}

void Start(const FunctionCallbackInfo<Value>& args)
{
    printf("In run async\n");

    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    uv_work_t *req = (uv_work_t*)malloc(sizeof(uv_work_t));

    /// Example using uv_queue_work (working fine)
    printf("Queue work\n");
    uv_queue_work(uv_default_loop(), req, &Runner, &RunDone);

    uv_async_t *handle = (uv_async_t*)malloc(sizeof(uv_async_t));
    uv_async_init(uv_default_loop(), handle, &Runner2);

    /// Example using uv_async_send (node does not terminate)
    printf("Async send\n");
    uv_async_send(handle);
}

void Init(Handle<Object> exports, Handle<Object> module)
{
    NODE_SET_METHOD(exports, "start", Start);
}

NODE_MODULE(node_uv, Init)

вывод

$ node test
calling addon
In run async
Queue work
Async send
Async work running!
called addon
Got async send!
Async work done!

(процесс на этом этапе не прекращается)

Полный пример проекта находится здесь: https://github.com/jugglingcats/node-uv

Любая помощь высоко ценится.


person jugglingcats    schedule 12.05.2017    source источник


Ответы (1)


Проблема была в том, что я не позвонил uv_close!! Должно быть что-то простое.

исправлен метод обратного вызова

static void Runner2(uv_async_t* handle) {
    printf("Got async send! %d\n", n++);
    uv_close((uv_handle_t *)handle, NULL);
}

Соответствующие документы: https://nikhilm.github.io/uvbook/threads.html

Исправлен проект github: https://github.com/jugglingcats/node-uv/tree/working

person jugglingcats    schedule 12.05.2017