On Sun, Sep 2, 2012 at 8:34 AM, Navaneeth KN <[email protected]> wrote:
> Hello,
>
> I have created a sample code that reporduces the problem.
>
> Code - https://gist.github.com/3595299
>
> Please download it and run it. If you run it without any modification, you
> should see the problems. Currently loop is iterating till 1000 and it is
> failing for me. In my friend's computer it was working fine for 1000
> iterations. He modified it to a larger value to get the failure. So you
> might need to change that number to get a failure.
>
> Here is what the code does.
>
> * Calls "process" function 1000 times from JS.
> * "process" function UnWraps the class instance from V8 and assign that to
> the workerdata instance.
> * Call uv_queue_work.
> * Worker thread will read a handle from the queue after acquiring a mutex.
> This handle will be removed from the queue.
> * After doing the work, handle will be returned back to the queue. This will
> also happen after acquiring a mutex.
>
> I got double free errors and segfault. But this is random and sometimes the
> whole thing just works. In the "test.js", I have commented out calls to
> "sleep". Uncommenting this seems to fix the issue.
>
> I am wondering why this happens. Any help would be great.
>
> I am using Node v0.8.8 on Arch Linux.

It's a thread safety issue but it's got nothing to do with mutexes:
the JS object gets garbage collected while the work request is
running. You need something like the patch below to make it safe.

diff --git a/mutex-test.cc b/mutex-test.cc
index 3953a4d..3605612 100644
--- a/mutex-test.cc
+++ b/mutex-test.cc
@@ -39,6 +39,8 @@ public:

   NativeLibrary* GetHandle();
   void ReturnHandle(NativeLibrary* handle);
+  void Ref() { node::ObjectWrap::Ref(); }
+  void Unref() { node::ObjectWrap::Unref(); }

 private:
   Foo()
@@ -142,6 +144,7 @@ void after_work(uv_work_t *req)
       data->callback->Call(Context::GetCurrent()->Global(), 2, argv);
     }

+    data->clazz->Unref();
     data->callback.Dispose();
     delete data;
     data = NULL;
@@ -184,6 +187,7 @@ Handle<Value> Foo::Process(const Arguments& args)
   data->request.data = data;
   data->callback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
   data->clazz = ObjectWrap::Unwrap<Foo>(args.This());
+  data->clazz->Ref();

   uv_queue_work(uv_default_loop(), &data->request,
perform_work_async, after_work);

On a side note, Foo::~Foo() needs to call uv_mutex_destroy().

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to