从子线程访问指针

从我的草坪上离开

我有一个看起来像这样的结构:

struct Work {
  uv_work_t requst;
  Local<Promise::Resolver> resolver;
};

然后,我有了使用imagemagick裁剪图像的方法:

void MagickNode::Crop(const FunctionCallbackInfo<Value> &args) {
  // Create a promise
  Local<Promise::Resolver> resolver = v8::Promise::Resolver::New(i.isolate);
  args.GetReturnValue().Set(resolver->GetPromise());

  // Create a worker
  Work *work = new Work();
  work->requst.data = work;
  work->resolver = resolver;

  // Do work
  uv_queue_work(uv_default_loop(), &work->requst, [](uv_work_t *req) {
    // Do the heavy lifting
  }, WorkVoidComplete);
}

该过程完成后,我想兑现承诺。我在这里做的:

void MagickNode::WorkVoidComplete(uv_work_t *req, int status) {
  // Setup the required items
  Isolate *isolate = Isolate::GetCurrent();
  v8::HandleScope handleScope(isolate);
  Work *work = static_cast<Work *>(req->data);

  // Resolve the promise
  work->resolver->Resolve(Undefined(isolate));
  delete work;
}

问题在于,work->resolver->Resolve运行时会出现细分错误我认为这是因为在父线程上创建它时,它是从线程执行的,这使我无法访问。

如何获得访问权限并运行该行?

如果我将那行移到方法的末尾MagickNode::Crop,它会正确运行,并且会调用promise。

小吃

WorkVoidComplete实际上,将在循环线程中被调用。这里的问题是您使用的是Local<T>手柄而不是Persistent<T>手柄。

MagickNode::Crop关闭范围关闭时,将释放本地句柄。

更改结构以使用v8::Persistent<Promise::Resolver>将解决此问题。请注意,使用永久引用句柄完成操作后,必须通过调用手动释放它Reset()

class Work {
 public:
  Work(Isolate* i, Local<Promise::Resolver> r)
    : isolate_(i) {
      resolver_.Reset(i, r);
    }

  ~Work() {
    resolver_.Reset();
  }

  inline uv_work_t* request() { return &request_; }
  inline Isolate* isolate() { return isolate_; }
  inline Local<Promise::Resolver> resolver() {
    return resolver_.Get(isolate_);
  }

 private:
  Isolate* isolate_;
  Persistent<Promise::Resolver> resolver_;
  uv_work_t request_;
};

void Something(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();

  Local<Promise::Resolver> resolver =
    v8::Promise::Resolver::New(context).ToLocalChecked();

  Work* work = new Work(isolate, resolver);
  work->request()->data = work;
  uv_queue_work(uv_default_loop(), work->request(), DoWork, WorkComplete);

  args.GetReturnValue().Set(resolver->GetPromise());
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章