workers: initial implementation by petkaantonov · Pull Request #2133 · nodejs/node

@petkaantonov - I tested your "Fix use-after-free" patch on Linux with valgrind as per the instructions here. It appears to work correctly.

You may consider getting rid of the async WorkerContext reaper on the main thread and adopting something like this instead which I think is easier to understand and should put less of a burden on the main thread since it would no longer have to poll the WorkerContext queue:

void WorkerContext::RunWorkerThread(void* arg) {
  WorkerContext* worker = static_cast<WorkerContext*>(arg);
  worker->Run();
  ...wait on a libuv condition variable signalled by 
     owner thread at end of WorkerContext::Dispose()...
  delete worker;
}

Unfortunately the Mac OSX BADF/select problem mentioned in the last PR still exists. I think it's a libuv issue. There's also an unrelated linux issue outlined below.

Using the latest workers implementation as of 1e0b6b1fd5fc93986d056798f47804d0a15a9bec and this patch:

--- a/test/workers/test-crypto.js
+++ b/test/workers/test-crypto.js
@@ -33,3 +33,3 @@ var tests = [

-var parallelism = 4;
+var parallelism = 8;
 var testsPerThread = Math.ceil(tests.length / parallelism);

running this command repeatedly:

./iojs --experimental-workers test/workers/test-crypto.js

on a 4 core Linux VM it experiences this error roughly once per 50 runs:

/opt/iojs-workers-implementation/test/common.js:484
  throw e;
        ^
Error: Running test/parallel/test-crypto-stream.js inside worker failed:
AssertionError: false == true
    at Decipheriv.end (/opt/iojs-workers-implementation/test/parallel/test-crypto-stream.js:52:5)
    at Decipheriv.<anonymous> (/opt/iojs-workers-implementation/test/common.js:371:15)
    at emitOne (events.js:82:20)
    at Decipheriv.emit (events.js:169:7)
    at done (_stream_transform.js:178:19)
    at _stream_transform.js:119:9
    at Decipheriv.Cipher._flush (crypto.js:160:5)
    at Decipheriv.<anonymous> (_stream_transform.js:118:12)
    at Decipheriv.g (events.js:260:16)
    at emitNone (events.js:67:13)
    at Worker.<anonymous> (/opt/iojs-workers-implementation/test/common.js:477:14)
    at emitOne (events.js:77:13)
    at Worker.emit (events.js:169:7)
    at onerror (worker.js:61:18)
    at WorkerBinding.workerContext._onmessage (worker.js:75:16)

on a 4 core Mac it experiences these errors roughly once per 20 runs:

 /opt/iojs-workers-implementation/test/common.js:484
   throw e;
         ^
 Error: Running test/parallel/test-crypto-hmac.js inside worker failed:
 Error: EBADF: bad file descriptor, close
     at Error (native)
     at Object.fs.closeSync (fs.js:518:18)
     at Object.fs.readFileSync (fs.js:445:21)
     at Object.Module._extensions..js (module.js:447:20)
     at Module.load (module.js:355:32)
     at Function.Module._load (module.js:310:12)
     at Function.Module.runMain (module.js:471:10)
     at process._runMain (node.js:68:18)
     at Worker.<anonymous> (/opt/iojs-workers-implementation/test/common.js:477:14)
     at emitOne (events.js:77:13)
     at Worker.emit (events.js:169:7)
     at onerror (worker.js:61:18)
     at WorkerBinding.workerContext._onmessage (worker.js:75:16)
 (node) crypto.createCredentials is deprecated. Use tls.createSecureContext instead.
 <Buffer 0c 1e e9 6b 67 d3 29 f7 94 26 87 51 bb 05 53 3f>
 Assertion failed: (r == 1), function uv__stream_osx_interrupt_select, file ../deps/uv/src/unix/stream.c, line 127.
 Abort trap: 6

Ignore the deprecation lines - they are of no consequence to this issue.