From c7c22e3db1c826bcfb2bc66651ec480aae0d4ae0 Mon Sep 17 00:00:00 2001 From: yo mama Date: Sat, 4 Apr 2015 01:00:59 -0700 Subject: first --- node_modules/webworker-threads/.npmignore | 3 + node_modules/webworker-threads/AUTHORS | 5 + node_modules/webworker-threads/CHANGES.md | 73 ++ node_modules/webworker-threads/LICENSE | 40 + node_modules/webworker-threads/README.md | 465 +++++++++ node_modules/webworker-threads/TODO.md | 6 + .../benchmark/b00_fibonacci_server_no_threads.js | 27 + .../benchmark/b01_fibonacci_server_threads.js | 42 + .../benchmark/b02_fibonacci_server_threads_pool.js | 36 + .../benchmark/b03_fibonacci_server_clustered.js | 39 + .../webworker-threads/benchmark/b04_only_quick.js | 14 + node_modules/webworker-threads/benchmark/doubles.c | 637 ++++++++++++ node_modules/webworker-threads/benchmark/pi.c | 155 +++ node_modules/webworker-threads/benchmark/pi.js | 50 + node_modules/webworker-threads/benchmark/pi.rb | 39 + .../webworker-threads/benchmark/pi_precompiled.js | 50 + node_modules/webworker-threads/binding.gyp | 17 + node_modules/webworker-threads/build/Makefile | 332 +++++++ .../Release/.deps/Release/WebWorkerThreads.node.d | 1 + .../Release/obj.target/WebWorkerThreads.node.d | 1 + .../WebWorkerThreads/src/WebWorkerThreads.o.d | 41 + .../build/Release/WebWorkerThreads.node | Bin 0 -> 92361 bytes .../webworker-threads/build/Release/linker.lock | 0 .../build/Release/obj.target/WebWorkerThreads.node | Bin 0 -> 92361 bytes .../WebWorkerThreads/src/WebWorkerThreads.o | Bin 0 -> 111912 bytes .../build/WebWorkerThreads.target.mk | 128 +++ .../webworker-threads/build/binding.Makefile | 6 + node_modules/webworker-threads/build/config.gypi | 114 +++ .../webworker-threads/deps/minifier/bin/minify | Bin 0 -> 13488 bytes .../webworker-threads/deps/minifier/src/minify.c | 432 +++++++++ .../webworker-threads/deps/minifier/src/test | Bin 0 -> 8736 bytes .../deps/minifier/src/test.include.c | 14 + .../deps/minifier/src/test_minifier.c | 8 + node_modules/webworker-threads/examples/demo.js | 31 + .../webworker-threads/examples/ex01_basic.js | 63 ++ .../webworker-threads/examples/ex01_basic.md | 94 ++ .../webworker-threads/examples/ex02_events.js | 54 ++ .../webworker-threads/examples/ex02_events.md | 73 ++ .../webworker-threads/examples/ex03_ping_pong.js | 57 ++ .../webworker-threads/examples/ex03_ping_pong.md | 80 ++ .../webworker-threads/examples/ex04_main.js | 40 + .../webworker-threads/examples/ex04_main.md | 51 + .../webworker-threads/examples/ex04_worker.js | 15 + .../webworker-threads/examples/ex04_worker.md | 18 + .../webworker-threads/examples/ex05_pool.js | 52 + .../webworker-threads/examples/ex05_pool.md | 63 ++ .../webworker-threads/examples/ex06_complex.js | 39 + .../webworker-threads/examples/ex06_jason.js | 42 + .../webworker-threads/examples/ex06_jason.md | 61 ++ .../webworker-threads/examples/fiveThreads.ls | 15 + .../examples/multiThreadEvented.ls | 15 + .../examples/quickIntro_blocking.js | 13 + .../examples/quickIntro_evented_childThreadCode.js | 7 + .../examples/quickIntro_fiveThreads.js | 21 + .../webworker-threads/examples/quickIntro_loop.js | 4 + .../examples/quickIntro_multiThread.js | 16 + .../examples/quickIntro_multiThreadEvented.js | 30 + .../examples/quickIntro_oneThread.js | 17 + .../examples/quickIntro_oneThreadEvented.js | 18 + node_modules/webworker-threads/package.json | 70 ++ node_modules/webworker-threads/package.ls | 41 + .../webworker-threads/src/WebWorkerThreads.cc | 955 ++++++++++++++++++ node_modules/webworker-threads/src/bson.cc | 1016 ++++++++++++++++++++ node_modules/webworker-threads/src/bson.h | 277 ++++++ node_modules/webworker-threads/src/createPool.js | 169 ++++ node_modules/webworker-threads/src/createPool.js.c | 1 + node_modules/webworker-threads/src/createPool.ls | 107 +++ node_modules/webworker-threads/src/events.js | 53 + node_modules/webworker-threads/src/events.js.c | 1 + node_modules/webworker-threads/src/events.ls | 29 + node_modules/webworker-threads/src/jslib.cc | 177 ++++ node_modules/webworker-threads/src/load.js | 19 + node_modules/webworker-threads/src/load.js.c | 1 + node_modules/webworker-threads/src/load.ls | 9 + .../webworker-threads/src/queues_a_gogo.cc | 160 +++ .../webworker-threads/src/thread_nextTick.js | 29 + .../webworker-threads/src/thread_nextTick.js.c | 1 + .../webworker-threads/src/thread_nextTick.ls | 19 + node_modules/webworker-threads/src/worker.js | 46 + node_modules/webworker-threads/src/worker.js.c | 1 + node_modules/webworker-threads/src/worker.ls | 18 + node_modules/webworker-threads/test.ls | 18 + node_modules/webworker-threads/test/ab.js | 96 ++ .../test/test00_run_once_and_destroy.js | 27 + .../test/test01_loop_as_fast_as_possible.js | 84 ++ .../test/test02_loop_as_fast_as_possible.js | 32 + .../test/test03_infiniteLoopFunction.js | 32 + .../test/test04_gc_versus_not_gc.js | 44 + .../test/test05_debugLeaksNoCallbacks.js | 32 + .../test/test06_throw_from_the_thread.js | 12 + .../webworker-threads/test/test07_sigkill.js | 24 + .../webworker-threads/test/test08_sigkill_leaks.js | 30 + .../test/test09_throw_from_the_callback.js | 15 + .../test/test10_node_nextTick_speed.js | 35 + .../test/test11_multi_callbacks.js | 38 + .../test/test12_precompiled_vs_normal.js | 42 + .../test/test13_thread_nextTick_speed.js | 31 + .../webworker-threads/test/test14_emit_once.js | 20 + .../test/test15_emit_ping_pong.js | 31 + .../test/test16_syntax_error_in_the_thread.js | 13 + .../webworker-threads/test/test17_pool_pi.js | 67 ++ .../test/test18_pool_any_as_fast_as_possible.js | 47 + .../test/test19_pool_emit_any_all.js | 37 + .../test/test20_removeAllListeners.js | 23 + .../test/test21_emit_ping_pong_big_string.js | 32 + .../test/test22_create_destroy_loop.js | 25 + .../test/test23_create_destroy_loop.js | 25 + node_modules/webworker-threads/test/test24_puts.js | 17 + .../webworker-threads/test/test25_delete_puts.js | 23 + .../test/test26_puts_with_many_args.js | 18 + .../test/test27_puts_event_loop.js | 14 + .../test/test28_puts_nextTick_loop.js | 14 + .../test/test29_puts_callback_loop.js | 14 + 113 files changed, 7975 insertions(+) create mode 100644 node_modules/webworker-threads/.npmignore create mode 100644 node_modules/webworker-threads/AUTHORS create mode 100644 node_modules/webworker-threads/CHANGES.md create mode 100644 node_modules/webworker-threads/LICENSE create mode 100644 node_modules/webworker-threads/README.md create mode 100644 node_modules/webworker-threads/TODO.md create mode 100644 node_modules/webworker-threads/benchmark/b00_fibonacci_server_no_threads.js create mode 100644 node_modules/webworker-threads/benchmark/b01_fibonacci_server_threads.js create mode 100644 node_modules/webworker-threads/benchmark/b02_fibonacci_server_threads_pool.js create mode 100644 node_modules/webworker-threads/benchmark/b03_fibonacci_server_clustered.js create mode 100644 node_modules/webworker-threads/benchmark/b04_only_quick.js create mode 100644 node_modules/webworker-threads/benchmark/doubles.c create mode 100644 node_modules/webworker-threads/benchmark/pi.c create mode 100755 node_modules/webworker-threads/benchmark/pi.js create mode 100755 node_modules/webworker-threads/benchmark/pi.rb create mode 100644 node_modules/webworker-threads/benchmark/pi_precompiled.js create mode 100644 node_modules/webworker-threads/binding.gyp create mode 100644 node_modules/webworker-threads/build/Makefile create mode 100644 node_modules/webworker-threads/build/Release/.deps/Release/WebWorkerThreads.node.d create mode 100644 node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads.node.d create mode 100644 node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o.d create mode 100755 node_modules/webworker-threads/build/Release/WebWorkerThreads.node create mode 100644 node_modules/webworker-threads/build/Release/linker.lock create mode 100755 node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads.node create mode 100644 node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o create mode 100644 node_modules/webworker-threads/build/WebWorkerThreads.target.mk create mode 100644 node_modules/webworker-threads/build/binding.Makefile create mode 100644 node_modules/webworker-threads/build/config.gypi create mode 100755 node_modules/webworker-threads/deps/minifier/bin/minify create mode 100644 node_modules/webworker-threads/deps/minifier/src/minify.c create mode 100755 node_modules/webworker-threads/deps/minifier/src/test create mode 100644 node_modules/webworker-threads/deps/minifier/src/test.include.c create mode 100644 node_modules/webworker-threads/deps/minifier/src/test_minifier.c create mode 100644 node_modules/webworker-threads/examples/demo.js create mode 100644 node_modules/webworker-threads/examples/ex01_basic.js create mode 100644 node_modules/webworker-threads/examples/ex01_basic.md create mode 100644 node_modules/webworker-threads/examples/ex02_events.js create mode 100644 node_modules/webworker-threads/examples/ex02_events.md create mode 100644 node_modules/webworker-threads/examples/ex03_ping_pong.js create mode 100644 node_modules/webworker-threads/examples/ex03_ping_pong.md create mode 100644 node_modules/webworker-threads/examples/ex04_main.js create mode 100644 node_modules/webworker-threads/examples/ex04_main.md create mode 100644 node_modules/webworker-threads/examples/ex04_worker.js create mode 100644 node_modules/webworker-threads/examples/ex04_worker.md create mode 100644 node_modules/webworker-threads/examples/ex05_pool.js create mode 100644 node_modules/webworker-threads/examples/ex05_pool.md create mode 100644 node_modules/webworker-threads/examples/ex06_complex.js create mode 100644 node_modules/webworker-threads/examples/ex06_jason.js create mode 100644 node_modules/webworker-threads/examples/ex06_jason.md create mode 100755 node_modules/webworker-threads/examples/fiveThreads.ls create mode 100755 node_modules/webworker-threads/examples/multiThreadEvented.ls create mode 100644 node_modules/webworker-threads/examples/quickIntro_blocking.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_evented_childThreadCode.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_fiveThreads.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_loop.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_multiThread.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_multiThreadEvented.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_oneThread.js create mode 100644 node_modules/webworker-threads/examples/quickIntro_oneThreadEvented.js create mode 100644 node_modules/webworker-threads/package.json create mode 100755 node_modules/webworker-threads/package.ls create mode 100644 node_modules/webworker-threads/src/WebWorkerThreads.cc create mode 100644 node_modules/webworker-threads/src/bson.cc create mode 100644 node_modules/webworker-threads/src/bson.h create mode 100644 node_modules/webworker-threads/src/createPool.js create mode 100644 node_modules/webworker-threads/src/createPool.js.c create mode 100644 node_modules/webworker-threads/src/createPool.ls create mode 100644 node_modules/webworker-threads/src/events.js create mode 100644 node_modules/webworker-threads/src/events.js.c create mode 100644 node_modules/webworker-threads/src/events.ls create mode 100644 node_modules/webworker-threads/src/jslib.cc create mode 100644 node_modules/webworker-threads/src/load.js create mode 100644 node_modules/webworker-threads/src/load.js.c create mode 100644 node_modules/webworker-threads/src/load.ls create mode 100644 node_modules/webworker-threads/src/queues_a_gogo.cc create mode 100644 node_modules/webworker-threads/src/thread_nextTick.js create mode 100644 node_modules/webworker-threads/src/thread_nextTick.js.c create mode 100644 node_modules/webworker-threads/src/thread_nextTick.ls create mode 100644 node_modules/webworker-threads/src/worker.js create mode 100644 node_modules/webworker-threads/src/worker.js.c create mode 100644 node_modules/webworker-threads/src/worker.ls create mode 100755 node_modules/webworker-threads/test.ls create mode 100644 node_modules/webworker-threads/test/ab.js create mode 100644 node_modules/webworker-threads/test/test00_run_once_and_destroy.js create mode 100644 node_modules/webworker-threads/test/test01_loop_as_fast_as_possible.js create mode 100644 node_modules/webworker-threads/test/test02_loop_as_fast_as_possible.js create mode 100644 node_modules/webworker-threads/test/test03_infiniteLoopFunction.js create mode 100644 node_modules/webworker-threads/test/test04_gc_versus_not_gc.js create mode 100644 node_modules/webworker-threads/test/test05_debugLeaksNoCallbacks.js create mode 100644 node_modules/webworker-threads/test/test06_throw_from_the_thread.js create mode 100644 node_modules/webworker-threads/test/test07_sigkill.js create mode 100644 node_modules/webworker-threads/test/test08_sigkill_leaks.js create mode 100644 node_modules/webworker-threads/test/test09_throw_from_the_callback.js create mode 100644 node_modules/webworker-threads/test/test10_node_nextTick_speed.js create mode 100644 node_modules/webworker-threads/test/test11_multi_callbacks.js create mode 100644 node_modules/webworker-threads/test/test12_precompiled_vs_normal.js create mode 100644 node_modules/webworker-threads/test/test13_thread_nextTick_speed.js create mode 100644 node_modules/webworker-threads/test/test14_emit_once.js create mode 100644 node_modules/webworker-threads/test/test15_emit_ping_pong.js create mode 100644 node_modules/webworker-threads/test/test16_syntax_error_in_the_thread.js create mode 100644 node_modules/webworker-threads/test/test17_pool_pi.js create mode 100644 node_modules/webworker-threads/test/test18_pool_any_as_fast_as_possible.js create mode 100644 node_modules/webworker-threads/test/test19_pool_emit_any_all.js create mode 100644 node_modules/webworker-threads/test/test20_removeAllListeners.js create mode 100644 node_modules/webworker-threads/test/test21_emit_ping_pong_big_string.js create mode 100644 node_modules/webworker-threads/test/test22_create_destroy_loop.js create mode 100644 node_modules/webworker-threads/test/test23_create_destroy_loop.js create mode 100644 node_modules/webworker-threads/test/test24_puts.js create mode 100644 node_modules/webworker-threads/test/test25_delete_puts.js create mode 100644 node_modules/webworker-threads/test/test26_puts_with_many_args.js create mode 100644 node_modules/webworker-threads/test/test27_puts_event_loop.js create mode 100644 node_modules/webworker-threads/test/test28_puts_nextTick_loop.js create mode 100644 node_modules/webworker-threads/test/test29_puts_callback_loop.js (limited to 'node_modules/webworker-threads') diff --git a/node_modules/webworker-threads/.npmignore b/node_modules/webworker-threads/.npmignore new file mode 100644 index 0000000..54f9e46 --- /dev/null +++ b/node_modules/webworker-threads/.npmignore @@ -0,0 +1,3 @@ +threads_a_gogo.node +build +.lock-wscript diff --git a/node_modules/webworker-threads/AUTHORS b/node_modules/webworker-threads/AUTHORS new file mode 100644 index 0000000..4c44003 --- /dev/null +++ b/node_modules/webworker-threads/AUTHORS @@ -0,0 +1,5 @@ +//Threads_a_gogo AUTHORS + +2011-11-06 Jorge Chamorro Bieling +2011-11-25 Juan Falgueras Cano +2012-01-26 Bruno Jouhier diff --git a/node_modules/webworker-threads/CHANGES.md b/node_modules/webworker-threads/CHANGES.md new file mode 100644 index 0000000..c956a56 --- /dev/null +++ b/node_modules/webworker-threads/CHANGES.md @@ -0,0 +1,73 @@ +## 0.4.6 + +### Bug Fixes + +* Compatibility with Node.js 0.10. + +## 0.4.5 + +### Bug Fixes + +* new Worker("filename.js") was broken on OS X. (@dfellis) + +## 0.4.3 + +### Bug Fixes + +* Fix Linux compilation issue introduced in 0.4.1. (@dfellis) + +* `importScripts` now checks if the files have been read entirely, + instead of (potentially) evaluating part of the file in case + of filesystem failure. + +## 0.4.2 + +### Global Worker API + +* Set `onmessage = function(event) { ... }` directly now works + as specced. (Previously it required `self.onmessage = ...`.) + +## 0.4.1 + +### Global Worker API + +* Add `importScripts` for loading on-disk files. + +* Add `console.log` and `console.error` from thread.js. + +## 0.4.0 + +* Support for Windows with Node.js 0.9.3+. + +## 0.3.2 + +* Fix BSON building on SunOS. + +## 0.3.1 + +* Switch to BSON instead of JSON for message serialization. + + Note that neither one supports circular structures or + native buffer objects yet. + +## 0.3.0 + +* Require Node.js 0.8. + +## 0.2.3 + +* Add SunOS to supported OSs; tested on Linux. + +## 0.2.2 + +* Allow an empty `new Worker()` constructor. + +* Update API documentation in README. + +## 0.2.1 + +* Allow any JSON-serializable structures in postMessage/onmessage. + +## 0.2.0 + +* Initial release. diff --git a/node_modules/webworker-threads/LICENSE b/node_modules/webworker-threads/LICENSE new file mode 100644 index 0000000..8ae0385 --- /dev/null +++ b/node_modules/webworker-threads/LICENSE @@ -0,0 +1,40 @@ +# CC0 1.0 Universal + +To the extent possible under law, 唐鳳 has waived all copyright +and related or neighboring rights to webworker-threads. + +This work is published from Taiwan. + +http://creativecommons.org/publicdomain/zero/1.0 + +# This module includes src/bson.cc and src/bson.h, under the Apache License v2.0: + +https://github.com/mongodb/js-bson/ + +Copyright by Christian Amor Kvalheim and other contributors. + +# This module includes src/jslib.cc, under the MIT license: + +https://github.com/rob333/thread.js + +Copyright(C) 2012 by RobertL + +# This module is based on Threads_a_gogo, under the MIT license: + +https://github.com/xk/node-threads-a-gogo/blob/2665efb9d1d3cc0934ac2f5b6265b37a684d2e07/package.json#L24 + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright 2011 Proyectos Equis Ka, s.l., Jorge Chamorro Bieling and other +contributors. See the AUTHORS file. All rights reserved. + +==== + +This license applies to all parts of Threads_a_gogo that are not externally +maintained libraries. diff --git a/node_modules/webworker-threads/README.md b/node_modules/webworker-threads/README.md new file mode 100644 index 0000000..f46aef4 --- /dev/null +++ b/node_modules/webworker-threads/README.md @@ -0,0 +1,465 @@ +# WebWorker Threads + +This is based on @xk (jorgechamorro)'s [Threads A GoGo for Node.js](https://github.com/audreyt/node-threads-a-gogo), but with an API conforming to the [Web Worker standard](http://www.w3.org/TR/workers/). + +This module provides an asynchronous, evented and/or continuation passing style API for moving blocking/longish CPU-bound tasks out of Node's event loop to JavaScript threads that run in parallel in the background and that use all the available CPU cores automatically; all from within a single Node process. + +This module requires Node.js 0.8.0+. + +On Unix (including Linux and OS X), this module requires a working node-gyp toolchain, which in turn requires make and C/C++. +For example, on OS X, you could install XCode from Apple, and then use it to install the command line tools (under Preferences -> Downloads). + +On Windows, this module requires Node.js 0.9.3+ and a working [node-gyp toolchain](http://dailyjs.com/2012/05/17/windows-and-node-3/). + +## Installing the module + +With [npm](http://npmjs.org/): + + npm install webworker-threads + +Sample usage (adapted from [MDN](https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers#Passing_data)): + +```js +var Worker = require('webworker-threads').Worker; +// var w = new Worker('worker.js'); // Standard API + +// You may also pass in a function: +var worker = new Worker(function(){ + postMessage("I'm working before postMessage('ali')."); + onmessage = function(event) { + postMessage('Hi ' + event.data); + self.close(); + }; +}); +worker.onmessage = function(event) { + console.log("Worker said : " + event.data); +}; +worker.postMessage('ali'); +``` + +A more involved example in [LiveScript](http://livescript.net/) syntax, with five threads: + +```coffee +{ Worker } = require \webworker-threads + +for til 5 => (new Worker -> + fibo = (n) -> if n > 1 then fibo(n - 1) + fibo(n - 2) else 1 + @onmessage = ({ data }) -> postMessage fibo data +) + ..onmessage = ({ data }) -> + console.log "[#{ @thread.id }] #data" + @postMessage Math.ceil Math.random! * 30 + ..postMessage Math.ceil Math.random! * 30 + +do spin = -> process.nextTick spin +``` + +## Introduction + +After the initialization phase of a Node program, whose purpose is to setup listeners and callbacks to be executed in response to events, the next phase, the proper execution of the program, is orchestrated by the event loop whose duty is to [juggle events, listeners and callbacks quickly and without any hiccups nor interruptions that would ruin its performance](http://youtube.com/v/D0uA_NOb0PE?autoplay=1) + +Both the event loop and said listeners and callbacks run sequentially in a single thread of execution, Node's main thread. If any of them ever blocks, nothing else will happen for the duration of the block: no more events will be handled, no more callbacks nor listeners nor timeouts nor nextTick()ed functions will have the chance to run and do their job, because they won't be called by the blocked event loop, and the program will turn sluggish at best, or appear to be frozen and dead at worst. + +### What is WebWorker-Threads + +`webworker-threads` provides an asynchronous API for CPU-bound tasks that's missing in Node.js: + +``` javascript +var Worker = require('webworker-threads').Worker; +require('http').createServer(function (req,res) { + var fibo = new Worker(function() { + function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; + } + onmessage = function (event) { + postMessage(fibo(event.data)); + } + }); + fibo.onmessage = function (event) { + res.end('fib(40) = ' + event.data); + }; + fibo.postMessage(40); +}).listen(port); +``` + +And it won't block the event loop because for each request, the `fibo` worker will run in parallel in a separate background thread. + +## API + +### Module API +``` javascript +var Threads= require('webworker-threads'); +``` +##### .Worker +`new Threads.Worker( [ file | function ] )` returns a Worker object. +##### .create() +`Threads.create( /* no arguments */ )` returns a thread object. +##### .createPool( numThreads ) +`Threads.createPool( numberOfThreads )` returns a threadPool object. + +--- +### Web Worker API +``` javascript +var worker= new Threads.Worker('worker.js'); +var worker= new Threads.Worker(function(){ ... }); +var worker= new Threads.Worker(); +``` +##### .postMessage( data ) +`worker.postMessage({ x: 1, y: 2 })` sends a data structure into the worker. The worker can receive it using the `onmessage` handler. +##### .onmessage +`worker.onmessage = function (event) { console.log(event.data) };` receives data from the worker's `postMessage` calls. +##### .terminate() +`worker.terminate()` terminates the worker thread. +##### .addEventListener( type, cb ) +`worker.addEventListener('message', callback)` is equivalent to setting `worker.onmesssage = callback`. +##### .dispatchEvent( event ) +Currently unimplemented. +##### .removeEventListener( type ) +Currently unimplemented. +##### .thread +Returns the underlying `thread` object; see the next section for details. +Note that this attribute is implementation-specific, and not part of W3C Web Worker API. + +--- +### Thread API +``` javascript +var thread= Threads.create(); +``` +##### .id +`thread.id` is a sequential thread serial number. +##### .load( absolutePath [, cb] ) +`thread.load( absolutePath [, cb] )` reads the file at `absolutePath` and `thread.eval(fileContents, cb)`. +##### .eval( program [, cb]) +`thread.eval( program [, cb])` converts `program.toString()` and eval()s it in the thread's global context, and (if provided) returns the completion value to `cb(err, completionValue)`. +##### .on( eventType, listener ) +`thread.on( eventType, listener )` registers the listener `listener(data)` for any events of `eventType` that the thread `thread` may emit. +##### .once( eventType, listener ) +`thread.once( eventType, listener )` is like `thread.on()`, but the listener will only be called once. +##### .removeAllListeners( [eventType] ) +`thread.removeAllListeners( [eventType] )` deletes all listeners for all eventTypes. If `eventType` is provided, deletes all listeners only for the event type `eventType`. +##### .emit( eventType, eventData [, eventData ... ] ) +`thread.emit( eventType, eventData [, eventData ... ] )` emits an event of `eventType` with `eventData` inside the thread `thread`. All its arguments are .toString()ed. +##### .destroy( /* no arguments */ ) +`thread.destroy( /* no arguments */ )` destroys the thread. + +--- +### Thread pool API +``` javascript +threadPool= Threads.createPool( numberOfThreads ); +``` +##### .load( absolutePath [, cb] ) +`threadPool.load( absolutePath [, cb] )` runs `thread.load( absolutePath [, cb] )` in all the pool's threads. +##### .any.eval( program, cb ) +`threadPool.any.eval( program, cb )` is like `thread.eval()`, but in any of the pool's threads. +##### .any.emit( eventType, eventData [, eventData ... ] ) +`threadPool.any.emit( eventType, eventData [, eventData ... ] )` is like `thread.emit()`, but in any of the pool's threads. +##### .all.eval( program, cb ) +`threadPool.all.eval( program, cb )` is like `thread.eval()`, but in all the pool's threads. +##### .all.emit( eventType, eventData [, eventData ... ] ) +`threadPool.all.emit( eventType, eventData [, eventData ... ] )` is like `thread.emit()`, but in all the pool's threads. +##### .on( eventType, listener ) +`threadPool.on( eventType, listener )` is like `thread.on()`, registers listeners for events from any of the threads in the pool. +##### .totalThreads() +`threadPool.totalThreads()` returns the number of threads in this pool: as supplied in `.createPool( number )` +##### .idleThreads() +`threadPool.idleThreads()` returns the number of threads in this pool that are currently idle (sleeping) +##### .pendingJobs() +`threadPool.pendingJobs()` returns the number of jobs pending. +##### .destroy( [ rudely ] ) +`threadPool.destroy( [ rudely ] )` waits until `pendingJobs()` is zero and then destroys the pool. If `rudely` is truthy, then it doesn't wait for `pendingJobs === 0`. + +--- +### Global Web Worker API + +Inside every Worker instance from webworker-threads, there's a global `self` object with these properties: + +##### .postMessage( data ) +`postMessage({ x: 1, y: 2 })` sends a data structure back to the main thread. +##### .onmessage +`onmessage = function (event) { ... }` receives data from the main thread's `.postMessage` calls. +##### .close() +`close()` stops the current thread. +##### .addEventListener( type, cb ) +`addEventListener('message', callback)` is equivalent to setting `self.onmesssage = callback`. +##### .dispatchEvent( event ) +`dispatchEvent({ type: 'message', data: data })` is the same as `self.postMessage(data)`. +##### .removeEventListener( type ) +Currently unimplemented. +##### .importScripts( file [, file...] ) +`importScripts('a.js', 'b.js')` loads one or more files from the disk and `eval()` them in the worker's instance scope. +##### .thread +The underlying `thread` object; see the next section for details. +Note that this attribute is implementation-specific, and not part of W3C Web Worker API. + +--- +### Global Thread API + +Inside every thread .create()d by webworker-threads, there's a global `thread` object with these properties: +##### .id +`thread.id` is the serial number of this thread +##### .on( eventType, listener ) +`thread.on( eventType, listener )` is just like `thread.on()` above. +##### .once( eventType, listener ) +`thread.once( eventType, listener )` is just like `thread.once()` above. +##### .emit( eventType, eventData [, eventData ... ] ) +`thread.emit( eventType, eventData [, eventData ... ] )` is just like `thread.emit()` above. +##### .removeAllListeners( [eventType] ) +`thread.removeAllListeners( [eventType] )` is just like `thread.removeAllListeners()` above. +##### .nextTick( function ) +`thread.nextTick( function )` is like `process.nextTick()`, but much faster. + +--- +### Global Helper API + +Inside every thread .create()d by webworker-threads, there are some helpers: + +##### console.log(arg1 [, arg2 ...]) +Same as `console.log` on the main process. + +##### console.error(arg1 [, arg2 ...]) +Same as `console.log`, except it prints to stderr. + +##### puts(arg1 [, arg2 ...]) +`puts(arg1 [, arg2 ...])` converts .toString()s and prints its arguments to stdout. + +----------- +WIP WIP WIP +----------- +Note that everything below this line is under construction and subject to change. +----------- + +## Examples + +**A.-** Here's a program that makes Node's event loop spin freely and as fast as possible: it simply prints a dot to the console in each turn: + + cat examples/quickIntro_loop.js + +``` javascript +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**B.-** Here's another program that adds to the one above a fibonacci(35) call in each turn, a CPU-bound task that takes quite a while to complete and that blocks the event loop making it spin slowly and clumsily. The point is simply to show that you can't put a job like that in the event loop because Node will stop performing properly when its event loop can't spin fast and freely due to a callback/listener/nextTick()ed function that's blocking. + + cat examples/quickIntro_blocking.js + +``` javascript +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +(function fiboLoop () { + process.stdout.write(fibo(35).toString()); + process.nextTick(fiboLoop); +})(); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**C.-** The program below uses `webworker-threads` to run the fibonacci(35) calls in a background thread, so Node's event loop isn't blocked at all and can spin freely again at full speed: + + cat examples/quickIntro_oneThread.js + +``` javascript +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +function cb (err, data) { + process.stdout.write(data); + this.eval('fibo(35)', cb); +} + +var thread= require('webworker-threads').create(); + +thread.eval(fibo).eval('fibo(35)', cb); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**D.-** This example is almost identical to the one above, only that it creates 5 threads instead of one, each running a fibonacci(35) in parallel and in parallel too with Node's event loop that keeps spinning happily at full speed in its own thread: + + cat examples/quickIntro_fiveThreads.js + +``` javascript +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +function cb (err, data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.eval('fibo(35)', cb); +} + +var Threads= require('webworker-threads'); + +Threads.create().eval(fibo).eval('fibo(35)', cb); +Threads.create().eval(fibo).eval('fibo(35)', cb); +Threads.create().eval(fibo).eval('fibo(35)', cb); +Threads.create().eval(fibo).eval('fibo(35)', cb); +Threads.create().eval(fibo).eval('fibo(35)', cb); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**E.-** The next one asks `webworker-threads` to create a pool of 10 background threads, instead of creating them manually one by one: + + cat examples/multiThread.js + +``` javascript +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +var numThreads= 10; +var threadPool= require('webworker-threads').createPool(numThreads).all.eval(fibo); + +threadPool.all.eval('fibo(35)', function cb (err, data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.eval('fibo(35)', cb); +}); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**F.-** This is a demo of the `webworker-threads` eventEmitter API, using one thread: + + cat examples/quickIntro_oneThreadEvented.js + +``` javascript +var thread= require('webworker-threads').create(); +thread.load(__dirname + '/quickIntro_evented_childThreadCode.js'); + +/* + This is the code that's .load()ed into the child/background thread: + + function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; + } + + thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) { + this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread. + }); + +*/ + +//Emit 'giveMeTheFibo' in the child/background thread. +thread.emit('giveMeTheFibo', 35); + +//Listener for the 'theFiboIs' events emitted by the child/background thread. +thread.on('theFiboIs', function cb (data) { + process.stdout.write(data); + this.emit('giveMeTheFibo', 35); +}); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +**G.-** This is a demo of the `webworker-threads` eventEmitter API, using a pool of threads: + + cat examples/quickIntro_multiThreadEvented.js + +``` javascript +var numThreads= 10; +var threadPool= require('webworker-threads').createPool(numThreads); +threadPool.load(__dirname + '/quickIntro_evented_childThreadCode.js'); + +/* + This is the code that's .load()ed into the child/background threads: + + function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; + } + + thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) { + this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread. + }); + +*/ + +//Emit 'giveMeTheFibo' in all the child/background threads. +threadPool.all.emit('giveMeTheFibo', 35); + +//Listener for the 'theFiboIs' events emitted by the child/background threads. +threadPool.on('theFiboIs', function cb (data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.emit('giveMeTheFibo', 35); +}); + +(function spinForever () { + process.nextTick(spinForever); +})(); +``` + +## More examples + +The `examples` directory contains a few more examples: + +* [ex01_basic](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex01_basic.md): Running a simple function in a thread. +* [ex02_events](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex02_events.md): Sending events from a worker thread. +* [ex03_ping_pong](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex03_ping_pong.md): Sending events both ways between the main thread and a worker thread. +* [ex04_main](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex04_main.md): Loading the worker code from a file. +* [ex05_pool](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex05_pool.md): Using the thread pool. +* [ex06_jason](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex06_jason.md): Passing complex objects to threads. + +## Rationale + +[Node.js](http://nodejs.org) is the most awesome, cute and super-sexy piece of free, open source software. + +Its event loop can spin as fast and smooth as a turbo, and roughly speaking, **the faster it spins, the more power it delivers**. That's why [@ryah](http://twitter.com/ryah) took great care to ensure that no -possibly slow- I/O operations could ever block it: a pool of background threads (thanks to [Marc Lehmann's libeio library](http://software.schmorp.de/pkg/libeio.html)) handle any blocking I/O calls in the background, in parallel. + +In Node it's verboten to write a server like this: + +``` javascript +http.createServer(function (req,res) { + res.end( fs.readFileSync(path) ); +}).listen(port); +``` +Because synchronous I/O calls **block the turbo**, and without proper boost, Node.js begins to stutter and behaves clumsily. To avoid it there's the asynchronous version of `.readFile()`, in continuation passing style, that takes a callback: + +``` javascript +fs.readfile(path, function cb (err, data) { /* ... */ }); +``` + +It's cool, we love it (*), and there's hundreds of ad hoc built-in functions like this in Node to help us deal with almost any variety of possibly slow, blocking I/O. + +### But what's with longish, CPU-bound tasks? + +How do you avoid blocking the event loop, when the task at hand isn't I/O bound, and lasts more than a few fractions of a millisecond? + +``` javascript +http.createServer(function cb (req,res) { + res.end( fibonacci(40) ); +}).listen(port); +``` + +You simply can't, because there's no way... well, there wasn't before `webworker-threads`. + +### Why Threads + +Threads (kernel threads) are very interesting creatures. They provide: + +1.- Parallelism: All the threads run in parallel. On a single core processor, the CPU is switched rapidly back and forth among the threads providing the illusion that the threads are running in parallel, albeit on a slower CPU than the real one. With 10 compute-bound threads in a process, the threads would appear to be running in parallel, each one on a CPU with 1/10th the speed of the real CPU. On a multi-core processor, threads are truly running in parallel, and get time-sliced when the number of threads exceed the number of cores. So with 12 compute bound threads on a quad-core processor each thread will appear to run at 1/3rd of the nominal core speed. + +2.- Fairness: No thread is more important than another, cores and CPU slices are fairly distributed among threads by the OS scheduler. + +3.- Threads fully exploit all the available CPU resources in your system. On a loaded system running many tasks in many threads, the more cores there are, the faster the threads will complete. Automatically. + +4.- The threads of a process share exactly the same address space, that of the process they belong to. Every thread can access every memory address within the process' address space. This is a very appropriate setup when the threads are actually part of the same job and are actively and closely cooperating with each other. Passing a reference to a chunk of data via a pointer is many orders of magnitude faster than transferring a copy of the data via IPC. + +### Why not multiple processes. + +The "can't block the event loop" problem is inherent to Node's evented model. No matter how many Node processes you have running as a [Node-cluster](http://blog.nodejs.org/2011/10/04/an-easy-way-to-build-scalable-network-programs/), it won't solve its issues with CPU-bound tasks. + +Launch a cluster of N Nodes running the example B (`quickIntro_blocking.js`) above, and all you'll get is N -instead of one- Nodes with their event loops blocked and showing a sluggish performance. diff --git a/node_modules/webworker-threads/TODO.md b/node_modules/webworker-threads/TODO.md new file mode 100644 index 0000000..0e01a20 --- /dev/null +++ b/node_modules/webworker-threads/TODO.md @@ -0,0 +1,6 @@ +* Worker API + * `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval` + Forwarding to the default implementation (in NativeModule TimerWrap). + * `onerror` handler + Catch runtime errors; also addEventListener 'error'. + * `dispatchEvent`? diff --git a/node_modules/webworker-threads/benchmark/b00_fibonacci_server_no_threads.js b/node_modules/webworker-threads/benchmark/b00_fibonacci_server_no_threads.js new file mode 100644 index 0000000..74c74fc --- /dev/null +++ b/node_modules/webworker-threads/benchmark/b00_fibonacci_server_no_threads.js @@ -0,0 +1,27 @@ + + +function fib (n) { + return (n < 2) ? 1 : fib(n-2)+ fib(n-1); +} + +var i= 0; +var n= 35; +function ƒ (req, res) { + if ((++i) % 10) { + res.end(" QUICK"); + process.stdout.write(" QUICK"); + } + else { + var txt= ' '+ fib(n); + res.end(txt); + process.stdout.write(txt); + } +} + + +var port= +process.argv[2] || 1234; +var http= require('http'); +http.globalAgent.maxSockets= 8192+2048; +http.createServer(ƒ).listen(port); +console.log('Fibonacci server (NO THREADS) running @port: '+ port); + diff --git a/node_modules/webworker-threads/benchmark/b01_fibonacci_server_threads.js b/node_modules/webworker-threads/benchmark/b01_fibonacci_server_threads.js new file mode 100644 index 0000000..dbedc87 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/b01_fibonacci_server_threads.js @@ -0,0 +1,42 @@ + + +function fib (n) { + return (n < 2) ? 1 : fib(n-2)+ fib(n-1); +} + +//We're going to use n threads +var numThreads= +process.argv[3] || 1; +console.log("Using "+ numThreads+ " threads"); + +var threads= []; +var round_robin= 0; +var t= require('threads_a_gogo'); +while (numThreads--) { + threads.push(t.create().eval(fib)); +} + +var i= 0; +var n= 35; +function ƒ (req, res) { + if ((++i) % 10) { + res.end(" QUICK"); + process.stdout.write(" QUICK"); + } + else { + round_robin= (++round_robin) % threads.length; + threads[round_robin].eval('fib('+ n+ ')', function cb (err, data) { + if (err) throw err; + var txt= ' '+ data; + res.end(txt); + process.stdout.write(txt); + }); + } +} + + +var port= +process.argv[2] || 1234; +var http= require('http'); +http.globalAgent.maxSockets= 8192+2048; +http.createServer(ƒ).listen(port); +console.log('Fibonacci server (WITH THREADS) running @port: '+ port); + diff --git a/node_modules/webworker-threads/benchmark/b02_fibonacci_server_threads_pool.js b/node_modules/webworker-threads/benchmark/b02_fibonacci_server_threads_pool.js new file mode 100644 index 0000000..7b2eef5 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/b02_fibonacci_server_threads_pool.js @@ -0,0 +1,36 @@ + + +function fib (n) { + return (n < 2) ? 1 : fib(n-2)+ fib(n-1); +} + +//We're going to use n threads +var numThreads= +process.argv[3] || 1; +console.log("Using a POOL of "+ numThreads+ " threads"); + +var pool= require('threads_a_gogo').createPool(numThreads).all.eval(fib); + +var i= 0; +var n= 35; +function ƒ (req, res) { + if ((++i) % 10) { + res.end(" QUICK"); + process.stdout.write(" QUICK"); + } + else { + pool.any.eval('fib('+ n+ ')', function cb (err, data) { + if (err) throw err; + var txt= ' '+ data; + res.end(txt); + process.stdout.write(txt); + }); + } +} + + +var port= +process.argv[2] || 1234; +var http= require('http'); +http.globalAgent.maxSockets= 8192+2048; +http.createServer(ƒ).listen(port); +console.log('Fibonacci server (WITH A THREAD POOL) running @port: '+ port); + diff --git a/node_modules/webworker-threads/benchmark/b03_fibonacci_server_clustered.js b/node_modules/webworker-threads/benchmark/b03_fibonacci_server_clustered.js new file mode 100644 index 0000000..d6609b9 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/b03_fibonacci_server_clustered.js @@ -0,0 +1,39 @@ + + +function fib (n) { + return (n < 2) ? 1 : fib(n-2)+ fib(n-1); +} + +var i= 0; +var n= 35; +function ƒ (req, res) { + if ((++i) % 10) { + res.end(" QUICK"); + process.stdout.write(" QUICK"); + } + else { + var txt= ' '+ fib(n); + res.end(txt); + process.stdout.write(txt); + } +} + +var cluster = require('cluster'); +if (cluster.isMaster) { + require('http').globalAgent.maxSockets= 8192+2048; + var numCPUs = process.argv[3] || 1; + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('death', function(worker) { + console.log('worker ' + worker.pid + ' died'); + }); +} else { + var port= + process.argv[2] || 1234; + var http= require('http'); + http.globalAgent.maxSockets= 8192+2048; + http.createServer(ƒ).listen(port); + console.log('Fibonacci server (CLUSTERED) listening: ' + port); +} + diff --git a/node_modules/webworker-threads/benchmark/b04_only_quick.js b/node_modules/webworker-threads/benchmark/b04_only_quick.js new file mode 100644 index 0000000..105ebb2 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/b04_only_quick.js @@ -0,0 +1,14 @@ + + +function ƒ (req, res) { + res.end(" QUICK"); + process.stdout.write(" QUICK"); +} + + +var port= +process.argv[2] || 1234; +var http= require('http'); +http.globalAgent.maxSockets= 8192+2048; +http.createServer(ƒ).listen(port); +console.log('Fibonacci server (NO THREADS) running @port: '+ port); + diff --git a/node_modules/webworker-threads/benchmark/doubles.c b/node_modules/webworker-threads/benchmark/doubles.c new file mode 100644 index 0000000..3210a51 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/doubles.c @@ -0,0 +1,637 @@ +/* + simple thread/process benchmark + + Copyright (C) Andrew Tridgell 2003 + + Released under the GNU GPL version 2 or later +*/ + +/* + this program is designed to test the relative performance of threads/processes + for operations typically performed by fileserving applications. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef NO_THREADS +#include +#endif + +/* this contains per-task data */ +static struct { + char *dname; + char *fname; +} *id_data; + +/* these pipes are used for synchronised startup of the tasks */ +static struct barrier { + int fd1[2]; + int fd2[2]; +} barriers[2]; + +/* setup a barrier */ +static void barrier_setup(struct barrier *b) +{ + if (pipe(b->fd1) != 0 || pipe(b->fd2) != 0) { + fprintf(stderr,"Barrier setup failed\n"); + exit(1); + } +} + +/* cleanup the barrier pipes */ +static void barrier_cleanup(struct barrier *b) +{ + close(b->fd1[0]); + close(b->fd1[1]); + close(b->fd2[0]); + close(b->fd2[1]); +} + +/* wait for the parent to signal startup */ +static void barrier_wait(struct barrier *b) +{ + char c = 0; + + if (write(b->fd1[1], &c, 1) != 1 || + read(b->fd2[0], &c, 1) != 1) { + fprintf(stderr, "Barrier wait failed\n"); + exit(1); + } +} + +/* synchronise children. Return the amount of time since the last + barrier */ +static double barrier_parent(struct barrier *b, int nprocs) +{ + char *s = calloc(nprocs, 1); + int i, nwritten=0; + char c = 0; + double t; + static struct timeval tp1; + struct timeval tp2; + + for (i=0;ifd1[0], &c, 1) != 1) ; + } + + /* putting the timer here prevents problems with the parent getting + rescheduled after the write */ + gettimeofday(&tp2,NULL); + t = (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - + (tp1.tv_sec + (tp1.tv_usec*1.0e-6)); + gettimeofday(&tp1,NULL); + + while (nwritten != nprocs) { + int n = write(b->fd2[1], s, nprocs-nwritten); + if (n <= 0) { + fprintf(stderr, "Barrier parent failed\n"); + exit(1); + } + nwritten += n; + } + free(s); + return t; +} + +#ifndef NO_THREADS +/* + create a thread with initial function fn(private) +*/ +static pthread_t thread_start(void *(*fn)(int), int id) +{ + pthread_t thread_id; + pthread_attr_t thread_attr; + int rc; + typedef void *(*thread_fn_t)(void *); + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, 0); + rc = pthread_create(&thread_id, &thread_attr, (thread_fn_t)fn, (void *)(intptr_t)id); + pthread_attr_destroy(&thread_attr); + + if (rc != 0) { + fprintf(stderr,"Thread create failed for id %d\n", id); + exit(1); + } + + return thread_id; +} + +/* wait for a thread to exit */ +static int thread_join(pthread_t id) +{ + return pthread_join(id, NULL); +} +#endif + + +/* + create a process with initial function fn(private) +*/ +static pid_t proc_start(void *(*fn)(int), int id) +{ + pid_t pid; + + pid = fork(); + if (pid == (pid_t)-1) { + fprintf(stderr,"Fork failed for id %d\n", id); + return pid; + } + if (pid == 0) { + fn(id); + exit(0); + } + return pid; +} + +/* wait for a process to exit */ +static int proc_join(pid_t id) +{ + if (waitpid(id, NULL, 0) != id) { + return -1; + } + return 0; +} + +#ifndef NO_THREADS +/* run a function under a set of threads */ +static double run_threads(int nthreads, void *(*fn)(int )) +{ + int i; + pthread_t *ids = calloc(sizeof(*ids), nthreads); + double t; + + barrier_setup(&barriers[0]); + barrier_setup(&barriers[1]); + + for (i=0;i=0;i--) { + kill(ids[i], SIGTERM); + } + exit(1); + } + } + + barrier_parent(&barriers[0], nprocs); + t = barrier_parent(&barriers[1], nprocs); + + for (i=0;i maxt) maxt = t[i]; + total += t[i]; + } + printf("%s %5.2f +/- %.2f seconds\n", name, total/nrepeats, (maxt-mint)/2); +} + + +/* lock a byte range in a open file */ +int main(int argc, char *argv[]) +{ + int nprocs, i; + char *tname = "ALL"; +#define NREPEATS 10 + struct { + const char *name; + void *(*fn)(int ); + } tests[] = { + {"noop", test_noop}, + {"malloc", test_malloc}, + {"setreuid", test_setreuid}, + {"readwrite", test_readwrite}, + {"stat", test_stat}, + {"fstat", test_fstat}, + {"dir", test_dir}, + {"dirsingle", test_dirsingle}, + {"create", test_create}, + {"lock", test_lock}, + {NULL, NULL} + }; + + if (argc <= 1) { + printf("thread_perf NPROCS\n"); + exit(1); + } + + nprocs = atoi(argv[1]); + + if (argc > 2) { + tname = argv[2]; + } + + id_data = calloc(nprocs, sizeof(*id_data)); + if (!id_data) { + exit(1); + } + +#ifndef NO_THREADS + printf("NOTE! for accurate process results please compile with -DNO_THREADS and don't link to -lpthread\n\n"); +#endif + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include + +#define kPI 5e7 + +typedef struct { + int id; + pid_t pid; + pthread_t thread; +} threadData; + + + + +struct timeval t0; +void timer_start () { + gettimeofday(&t0, NULL); +} + +double timer_end () { + struct timeval t1; + gettimeofday(&t1, NULL); + return (double) (((double)t1.tv_sec)+ ((double)t1.tv_usec*1.0e-6))- (((double)t0.tv_sec)+ ((double)t0.tv_usec*1.0e-6)); +} + + + + +double pi (double n) { + double pi= 0; + double num= 4; + double den= 1; + int plus= 1; + + while (den < n) { + if (plus) { + pi+= num/den; + plus= 0; + } + else { + pi-= num/den; + plus= 1; + } + den+= 2; + } + return pi; +} + + + + +void* thread_proc (void* arg) { + fprintf(stdout, "%.16f -> TID[%d]\n", pi(kPI), ((threadData*) arg)->id); + return NULL; +} + + + + +int main (int argc, char *argv[]) { + + double tThreads= 0, tProcs= 0; + int numThreads= (argc > 1) ? atoi(argv[1]): 33; + threadData* threads= (threadData*) malloc(numThreads* sizeof(threadData)); + + + + // USING PROCESSES + + fprintf(stdout, "\n**** Using %d processes\n", numThreads); + + timer_start(); + + { + pid_t pid; + int i= numThreads; + while (i--) { + threads[i].id= numThreads- i; + threads[i].pid= pid= fork(); + if (!pid) { + //child + fprintf(stdout, "%.16f -> PID[%d]\n", pi(kPI), threads[i].id); + exit(0); + } + else if (pid < 0) { + fprintf(stdout, "**** Error: fork(): -1\n"); + while (++i < numThreads) { + kill(threads[i].pid, SIGKILL); + } + exit(-1); + } + } + + i= numThreads; + while (i--) { + waitpid(WAIT_ANY, NULL, 0); + } + } + + tProcs= timer_end(); + + + + + // USING THREADS + + fprintf(stdout, "\n**** Using %d threads\n", numThreads); + + timer_start(); + + { + int i= numThreads; + while (i--) { + threads[i].id= numThreads- i; + pthread_create(&threads[i].thread, NULL, thread_proc, &threads[i]); + } + + i= numThreads; + while (i--) { + pthread_join(threads[i].thread, NULL); + } + } + + tThreads= timer_end(); + + + fprintf(stdout, "\n*** Procesos:\n"); + fprintf(stdout, "Tiempo total (ms) -> %.0f\n", tProcs*1e3); + fprintf(stdout, "Procesos por segundo -> %.1f\n", (double)(numThreads/tProcs)); + fprintf(stdout, "Total de procesos ejecutadas -> %d\n", numThreads); + + fprintf(stdout, "\n*** Threads:\n"); + fprintf(stdout, "Tiempo total (ms) -> %.0f\n", tThreads*1e3); + fprintf(stdout, "Threads por segundo -> %.1f\n", (double)(numThreads/tThreads)); + fprintf(stdout, "Total de threads ejecutadas -> %d\n", numThreads); + + fprintf(stdout, "\nRatio t_Threads/t_Procesos -> %.4f\n", (double)(tThreads/tProcs)); + free(threads); +} diff --git a/node_modules/webworker-threads/benchmark/pi.js b/node_modules/webworker-threads/benchmark/pi.js new file mode 100755 index 0000000..fe30668 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/pi.js @@ -0,0 +1,50 @@ + + +var Threads= require('threads_a_gogo'); + + +function cb (err, msg) { + this.destroy(); + ++i; + process.stdout.write('\n'+ msg + ' -> '+ this.id); +} + +function pi () { + var π= 0; + var num= 4; + var den= 1; + var plus= true; + + while (den < 5e7) { + if (plus) { + π+= num/den; + plus= false; + } + else { + π-= num/den; + plus= true; + } + den+= 2; + } + return π; +} + + +var i= +process.argv[2] || 1; +console.log('Using '+ i+ ' threads'); + + +var t= Date.now(); +while (i--) { + Threads.create().eval('('+ pi+ ')()', cb); +} + + +i= 0; +process.on('exit', function () { + t= Date.now()- t; + var tps= (i*1e3/t).toFixed(1); + console.log('\nTiempo total (ms) -> '+ t); + console.log('Threads por segundo -> '+ tps); + console.log('Total de threads ejecutadas -> '+ i); +}); diff --git a/node_modules/webworker-threads/benchmark/pi.rb b/node_modules/webworker-threads/benchmark/pi.rb new file mode 100755 index 0000000..5f85965 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/pi.rb @@ -0,0 +1,39 @@ +#!/usr/bin/env ruby + +def pi(i) + pi= 0 + num= 4.0 + den= 1 + plus= true + + while den < 5e7 + if plus + pi+= num/den + plus= false + else + pi-= num/den + plus= true + end + den+= 2 + end + puts "#{pi} -> #{i}" +end + +threads=[] +count=ARGV.shift || 1 +puts "Using #{count} threads" + +t= Time.new +count.to_i.times do |i| + threads << Thread.new{pi(i)} +end + +threads.each do |j| + j.join +end + +t= (Time.new- t)* 1e3 +tps= Integer(count) * 1e3 / t +puts "\nTiempo total (ms) -> %.0f" % t +puts "Threads por segundo -> %.1f" % tps +puts "Total de threads ejecutadas -> #{count}" diff --git a/node_modules/webworker-threads/benchmark/pi_precompiled.js b/node_modules/webworker-threads/benchmark/pi_precompiled.js new file mode 100644 index 0000000..7139ac1 --- /dev/null +++ b/node_modules/webworker-threads/benchmark/pi_precompiled.js @@ -0,0 +1,50 @@ + + +var Threads= require('threads_a_gogo'); + + +function cb (err, msg) { + this.destroy(); + ++i; + process.stdout.write('\n'+ msg + ' -> '+ this.id); +} + +function pi () { + var π= 0; + var num= 4; + var den= 1; + var plus= true; + + while (den < 1e7) { + if (plus) { + π+= num/den; + plus= false; + } + else { + π-= num/den; + plus= true; + } + den+= 2; + } + return π; +} + + +var i= +process.argv[2] || 1; +console.log('Using '+ i+ ' threads'); + +var precompiled= Threads.preCompile('('+ pi+ ')()'); +var t= Date.now(); +while (i--) { + Threads.create().eval(precompiled, cb); +} + + +i= 0; +process.on('exit', function () { + t= Date.now()- t; + var tps= (i*1e3/t).toFixed(1); + console.log('\nTiempo total (ms) -> '+ t); + console.log('Threads por segundo -> '+ tps); + console.log('Total de threads ejecutadas -> '+ i); +}); diff --git a/node_modules/webworker-threads/binding.gyp b/node_modules/webworker-threads/binding.gyp new file mode 100644 index 0000000..fcd23db --- /dev/null +++ b/node_modules/webworker-threads/binding.gyp @@ -0,0 +1,17 @@ +{ + 'targets': [ + { + 'target_name': 'WebWorkerThreads', + 'sources': [ 'src/WebWorkerThreads.cc' ], + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions' ], + 'conditions': [ + ['OS=="mac"', { + 'xcode_settings': { + 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' + } + }] + ] + } + ] +} diff --git a/node_modules/webworker-threads/build/Makefile b/node_modules/webworker-threads/build/Makefile new file mode 100644 index 0000000..7f64210 --- /dev/null +++ b/node_modules/webworker-threads/build/Makefile @@ -0,0 +1,332 @@ +# We borrow heavily from the kernel build setup, though we are simpler since +# we don't have Kconfig tweaking settings on us. + +# The implicit make rules have it looking for RCS files, among other things. +# We instead explicitly write all the rules we care about. +# It's even quicker (saves ~200ms) to pass -r on the command line. +MAKEFLAGS=-r + +# The source directory tree. +srcdir := .. +abs_srcdir := $(abspath $(srcdir)) + +# The name of the builddir. +builddir_name ?= . + +# The V=1 flag on command line makes us verbosely print command lines. +ifdef V + quiet= +else + quiet=quiet_ +endif + +# Specify BUILDTYPE=Release on the command line for a release build. +BUILDTYPE ?= Release + +# Directory all our build output goes into. +# Note that this must be two directories beneath src/ for unit tests to pass, +# as they reach into the src/ directory for data with relative paths. +builddir ?= $(builddir_name)/$(BUILDTYPE) +abs_builddir := $(abspath $(builddir)) +depsdir := $(builddir)/.deps + +# Object output directory. +obj := $(builddir)/obj +abs_obj := $(abspath $(obj)) + +# We build up a list of every single one of the targets so we can slurp in the +# generated dependency rule Makefiles in one pass. +all_deps := + + + +# C++ apps need to be linked with g++. +# +# Note: flock is used to seralize linking. Linking is a memory-intensive +# process so running parallel links can often lead to thrashing. To disable +# the serialization, override LINK via an envrionment variable as follows: +# +# export LINK=g++ +# +# This will allow make to invoke N linker processes as specified in -jN. +LINK ?= flock $(builddir)/linker.lock $(CXX.target) + +CC.target ?= $(CC) +CFLAGS.target ?= $(CFLAGS) +CXX.target ?= $(CXX) +CXXFLAGS.target ?= $(CXXFLAGS) +LINK.target ?= $(LINK) +LDFLAGS.target ?= $(LDFLAGS) +AR.target ?= $(AR) + +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need +# to replicate this environment fallback in make as well. +CC.host ?= gcc +CFLAGS.host ?= +CXX.host ?= g++ +CXXFLAGS.host ?= +LINK.host ?= g++ +LDFLAGS.host ?= +AR.host ?= ar + +# Define a dir function that can handle spaces. +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions +# "leading spaces cannot appear in the text of the first argument as written. +# These characters can be put into the argument value by variable substitution." +empty := +space := $(empty) $(empty) + +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces +replace_spaces = $(subst $(space),?,$1) +unreplace_spaces = $(subst ?,$(space),$1) +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) + +# Flags to make gcc output dependency info. Note that you need to be +# careful here to use the flags that ccache and distcc can understand. +# We write to a dep file on the side first and then rename at the end +# so we can't end up with a broken dep file. +depfile = $(depsdir)/$(call replace_spaces,$@).d +DEPFLAGS = -MMD -MF $(depfile).raw + +# We have to fixup the deps output in a few ways. +# (1) the file output should mention the proper .o file. +# ccache or distcc lose the path to the target, so we convert a rule of +# the form: +# foobar.o: DEP1 DEP2 +# into +# path/to/foobar.o: DEP1 DEP2 +# (2) we want missing files not to cause us to fail to build. +# We want to rewrite +# foobar.o: DEP1 DEP2 \ +# DEP3 +# to +# DEP1: +# DEP2: +# DEP3: +# so if the files are missing, they're just considered phony rules. +# We have to do some pretty insane escaping to get those backslashes +# and dollar signs past make, the shell, and sed at the same time. +# Doesn't work with spaces, but that's fine: .d files have spaces in +# their names replaced with other characters. +define fixup_dep +# The depfile may not exist if the input file didn't have any #includes. +touch $(depfile).raw +# Fixup path as in (1). +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef + +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = rm -rf "$@" && cp -af "$<" "$@" + +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) + +# We support two kinds of shared objects (.so): +# 1) shared_library, which is just bundling together many dependent libraries +# into a link line. +# 2) loadable_module, which is generating a module intended for dlopen(). +# +# They differ only slightly: +# In the former case, we want to package all dependent code into the .so. +# In the latter case, we want to package just the API exposed by the +# outermost module. +# This means shared_library uses --whole-archive, while loadable_module doesn't. +# (Note that --whole-archive is incompatible with the --start-group used in +# normal linking.) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) + + +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' + +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain ? instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\ + for p in $(POSTBUILDS); do\ + eval $$p;\ + E=$$?;\ + if [ $$E -ne 0 ]; then\ + break;\ + fi;\ + done;\ + if [ $$E -ne 0 ]; then\ + rm -rf "$@";\ + exit $$E;\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for +# spaces already and dirx strips the ? characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word 1,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "all" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: all +all: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +TOOLSET := target +# Suffix rules, putting all outputs into $(obj). +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) + + +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,WebWorkerThreads.target.mk)))),) + include WebWorkerThreads.target.mk +endif + +quiet_cmd_regen_makefile = ACTION Regenerating $@ +cmd_regen_makefile = /usr/libexec/openshift/cartridges/c9-0.1/root/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/var/lib/stickshift/521199af5973ca01b600005b/app-root/data/587788/node_modules/webworker-threads/build/config.gypi -I/usr/libexec/openshift/cartridges/c9-0.1/root/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15" "-Dmodule_root_dir=/var/lib/stickshift/521199af5973ca01b600005b/app-root/data/587788/node_modules/webworker-threads" binding.gyp +Makefile: $(srcdir)/../../../../../../../openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../usr/libexec/openshift/cartridges/c9-0.1/root/lib/node_modules/npm/node_modules/node-gyp/addon.gypi + $(call do_cmd,regen_makefile) + +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif diff --git a/node_modules/webworker-threads/build/Release/.deps/Release/WebWorkerThreads.node.d b/node_modules/webworker-threads/build/Release/.deps/Release/WebWorkerThreads.node.d new file mode 100644 index 0000000..beba378 --- /dev/null +++ b/node_modules/webworker-threads/build/Release/.deps/Release/WebWorkerThreads.node.d @@ -0,0 +1 @@ +cmd_Release/WebWorkerThreads.node := rm -rf "Release/WebWorkerThreads.node" && cp -af "Release/obj.target/WebWorkerThreads.node" "Release/WebWorkerThreads.node" diff --git a/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads.node.d b/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads.node.d new file mode 100644 index 0000000..1407ad7 --- /dev/null +++ b/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads.node.d @@ -0,0 +1 @@ +cmd_Release/obj.target/WebWorkerThreads.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m64 -Wl,-soname=WebWorkerThreads.node -o Release/obj.target/WebWorkerThreads.node -Wl,--start-group Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o -Wl,--end-group diff --git a/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o.d b/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o.d new file mode 100644 index 0000000..80bc675 --- /dev/null +++ b/node_modules/webworker-threads/build/Release/.deps/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o.d @@ -0,0 +1,41 @@ +cmd_Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include -fPIC -Wall -Wextra -Wno-unused-parameter -pthread -m64 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-tree-sink -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o.d.raw -c -o Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o ../src/WebWorkerThreads.cc +Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o: \ + ../src/WebWorkerThreads.cc \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include/v8.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include/v8stdint.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/uv-unix.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/ngx-queue.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/uv-linux.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_object_wrap.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node.h \ + ../src/queues_a_gogo.cc ../src/bson.cc \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_version.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_buffer.h \ + ../src/bson.h \ + /var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_object_wrap.h \ + ../src/jslib.cc ../src/events.js.c ../src/load.js.c \ + ../src/createPool.js.c ../src/worker.js.c ../src/thread_nextTick.js.c +../src/WebWorkerThreads.cc: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include/v8.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include/v8stdint.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/uv-unix.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/ngx-queue.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include/uv-private/uv-linux.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_object_wrap.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node.h: +../src/queues_a_gogo.cc: +../src/bson.cc: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_version.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_buffer.h: +../src/bson.h: +/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src/node_object_wrap.h: +../src/jslib.cc: +../src/events.js.c: +../src/load.js.c: +../src/createPool.js.c: +../src/worker.js.c: +../src/thread_nextTick.js.c: diff --git a/node_modules/webworker-threads/build/Release/WebWorkerThreads.node b/node_modules/webworker-threads/build/Release/WebWorkerThreads.node new file mode 100755 index 0000000..efa129c Binary files /dev/null and b/node_modules/webworker-threads/build/Release/WebWorkerThreads.node differ diff --git a/node_modules/webworker-threads/build/Release/linker.lock b/node_modules/webworker-threads/build/Release/linker.lock new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads.node b/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads.node new file mode 100755 index 0000000..efa129c Binary files /dev/null and b/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads.node differ diff --git a/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o b/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o new file mode 100644 index 0000000..04e3f4c Binary files /dev/null and b/node_modules/webworker-threads/build/Release/obj.target/WebWorkerThreads/src/WebWorkerThreads.o differ diff --git a/node_modules/webworker-threads/build/WebWorkerThreads.target.mk b/node_modules/webworker-threads/build/WebWorkerThreads.target.mk new file mode 100644 index 0000000..882c07e --- /dev/null +++ b/node_modules/webworker-threads/build/WebWorkerThreads.target.mk @@ -0,0 +1,128 @@ +# This file is generated by gyp; do not edit. + +TOOLSET := target +TARGET := WebWorkerThreads +DEFS_Debug := \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' \ + '-DDEBUG' \ + '-D_DEBUG' + +# Flags passed to all source files. +CFLAGS_Debug := \ + -fPIC \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -pthread \ + -m64 \ + -g \ + -O0 + +# Flags passed to only C files. +CFLAGS_C_Debug := + +# Flags passed to only C++ files. +CFLAGS_CC_Debug := \ + -fno-rtti + +INCS_Debug := \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include + +DEFS_Release := \ + '-D_LARGEFILE_SOURCE' \ + '-D_FILE_OFFSET_BITS=64' \ + '-DBUILDING_NODE_EXTENSION' + +# Flags passed to all source files. +CFLAGS_Release := \ + -fPIC \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -pthread \ + -m64 \ + -O2 \ + -fno-strict-aliasing \ + -fno-tree-vrp \ + -fno-tree-sink + +# Flags passed to only C files. +CFLAGS_C_Release := + +# Flags passed to only C++ files. +CFLAGS_CC_Release := \ + -fno-rtti + +INCS_Release := \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/src \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/uv/include \ + -I/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15/deps/v8/include + +OBJS := \ + $(obj).target/$(TARGET)/src/WebWorkerThreads.o + +# Add to the list of files we specially track dependencies for. +all_deps += $(OBJS) + +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual. +$(OBJS): TOOLSET := $(TOOLSET) +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) + +# Suffix rules, putting all outputs into $(obj). + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# Try building from generated source, too. + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) + +# End of this set of suffix rules +### Rules for final target. +LDFLAGS_Debug := \ + -pthread \ + -rdynamic \ + -m64 + +LDFLAGS_Release := \ + -pthread \ + -rdynamic \ + -m64 + +LIBS := + +$(obj).target/WebWorkerThreads.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) +$(obj).target/WebWorkerThreads.node: LIBS := $(LIBS) +$(obj).target/WebWorkerThreads.node: TOOLSET := $(TOOLSET) +$(obj).target/WebWorkerThreads.node: $(OBJS) FORCE_DO_CMD + $(call do_cmd,solink_module) + +all_deps += $(obj).target/WebWorkerThreads.node +# Add target alias +.PHONY: WebWorkerThreads +WebWorkerThreads: $(builddir)/WebWorkerThreads.node + +# Copy this to the executable output path. +$(builddir)/WebWorkerThreads.node: TOOLSET := $(TOOLSET) +$(builddir)/WebWorkerThreads.node: $(obj).target/WebWorkerThreads.node FORCE_DO_CMD + $(call do_cmd,copy) + +all_deps += $(builddir)/WebWorkerThreads.node +# Short alias for building this executable. +.PHONY: WebWorkerThreads.node +WebWorkerThreads.node: $(obj).target/WebWorkerThreads.node $(builddir)/WebWorkerThreads.node + +# Add executable to "all" target. +.PHONY: all +all: $(builddir)/WebWorkerThreads.node + diff --git a/node_modules/webworker-threads/build/binding.Makefile b/node_modules/webworker-threads/build/binding.Makefile new file mode 100644 index 0000000..50f7621 --- /dev/null +++ b/node_modules/webworker-threads/build/binding.Makefile @@ -0,0 +1,6 @@ +# This file is generated by gyp; do not edit. + +export builddir_name ?= build/./. +.PHONY: all +all: + $(MAKE) WebWorkerThreads diff --git a/node_modules/webworker-threads/build/config.gypi b/node_modules/webworker-threads/build/config.gypi new file mode 100644 index 0000000..64d8bc5 --- /dev/null +++ b/node_modules/webworker-threads/build/config.gypi @@ -0,0 +1,114 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "clang": 0, + "gcc_version": 44, + "host_arch": "x64", + "node_install_npm": "true", + "node_prefix": "", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_openssl": "false", + "node_shared_v8": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_unsafe_optimizations": 0, + "node_use_dtrace": "false", + "node_use_etw": "false", + "node_use_openssl": "true", + "node_use_perfctr": "false", + "node_use_systemtap": "false", + "python": "/var/lib/stickshift/5169307b5973cafe5600012f/app-root/data/.nix-profile/bin/python", + "target_arch": "x64", + "v8_enable_gdbjit": 0, + "v8_no_strict_aliasing": 1, + "v8_use_snapshot": "true", + "nodedir": "/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.node-gyp/0.10.15", + "copy_dev_lib": "true", + "standalone_static_library": 1, + "save_dev": "", + "viewer": "man", + "browser": "", + "rollback": "true", + "usage": "", + "globalignorefile": "/var/lib/stickshift/521199af5973ca01b600005b/app-root/data/etc/npmignore", + "shell": "/usr/bin/oo-trap-user", + "init_author_url": "", + "shrinkwrap": "true", + "parseable": "", + "userignorefile": "/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.npmignore", + "sign_git_tag": "", + "init_author_email": "", + "cache_max": "null", + "long": "", + "ignore": "", + "npat": "", + "fetch_retries": "2", + "registry": "https://registry.npmjs.org/", + "versions": "", + "message": "%s", + "globalconfig": "/var/lib/stickshift/521199af5973ca01b600005b/app-root/data/etc/npmrc", + "always_auth": "", + "cache_lock_retries": "10", + "proprietary_attribs": "true", + "fetch_retry_mintimeout": "10000", + "json": "", + "coverage": "", + "pre": "", + "https_proxy": "", + "engine_strict": "", + "description": "true", + "userconfig": "/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.npmrc", + "init_module": "/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.npm-init.js", + "npaturl": "http://npat.npmjs.org/", + "user": "6841", + "node_version": "v0.10.15", + "save": "", + "editor": "vi", + "tag": "latest", + "global": "", + "username": "", + "optional": "true", + "force": "", + "bin_links": "true", + "searchopts": "", + "depth": "null", + "searchsort": "name", + "rebuild_bundle": "true", + "yes": "", + "unicode": "true", + "fetch_retry_maxtimeout": "60000", + "strict_ssl": "true", + "group": "6841", + "fetch_retry_factor": "10", + "dev": "", + "version": "", + "cache_lock_stale": "60000", + "cache_min": "10", + "searchexclude": "", + "cache": "/var/lib/openshift/521199af5973ca01b600005b/app-root/data/.npm", + "color": "true", + "save_optional": "", + "user_agent": "node/v0.10.15 linux x64", + "cache_lock_wait": "10000", + "production": "", + "save_bundle": "", + "umask": "18", + "init_version": "0.0.0", + "init_author_name": "", + "git": "/var/lib/stickshift/521199af5973ca01b600005b/app-root/data/bin/git", + "unsafe_perm": "true", + "tmp": "/tmp/", + "onload_script": "", + "link": "", + "prefix": "/var/lib/stickshift/521199af5973ca01b600005b/app-root/data" + } +} diff --git a/node_modules/webworker-threads/deps/minifier/bin/minify b/node_modules/webworker-threads/deps/minifier/bin/minify new file mode 100755 index 0000000..539d559 Binary files /dev/null and b/node_modules/webworker-threads/deps/minifier/bin/minify differ diff --git a/node_modules/webworker-threads/deps/minifier/src/minify.c b/node_modules/webworker-threads/deps/minifier/src/minify.c new file mode 100644 index 0000000..37fe385 --- /dev/null +++ b/node_modules/webworker-threads/deps/minifier/src/minify.c @@ -0,0 +1,432 @@ +/* + +2012-02-20 minify.c basado en jsmin.c, Jorge Chamorro Bieling, Proyectos Equis Ka, s.l. + +Minifica un .js, y lo convierte en una sentencia de C que fabrica una +string de C debidamente acabada en \0, con el nombre que se haya pasado en arg[1], +lista para ser guardada en un fichero del que se puede hacer un #include "fichero". + + +*/ + +/* jsmin.c +2012-01-09 + +Copyright (c) 2002 Douglas Crockford (www.crockford.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include + +static int theA; +static int theB; +static int theLookahead = EOF; +static const char* hex= "0123456789abcdef"; + +/* + +static int len; +static int first; +#define maxLen 80 + +static void put_hex (int c) { + int lo= c & 0x000f; + int hi= (c & 0x00f0) >> 4; + + if (first) { + first= 0; + fprintf(stdout, " 0x%c%c", hex[hi], hex[lo]); + len+= 6; + } + else { + len+= 6; + if (len > maxLen) { + len= 6; + fprintf(stdout, ",\n 0x%c%c", hex[hi], hex[lo]); + } + else { + fprintf(stdout, ", 0x%c%c", hex[hi], hex[lo]); + } + } +} +*/ + +/* +static void put_hex (int c) { + if (c < ' ') { + if (c == '\n') { + fprintf(stdout, "\\n"); + } + else if (c == '\t') { + fprintf(stdout, "\\t"); + } + else if (c == '\r') { + fprintf(stdout, "\\r"); + } + else { + int lo= c & 0x000f; + int hi= (c & 0x00f0) >> 4; + + fprintf(stdout, "\\x%c%c", hex[hi], hex[lo]); + } + } + else if ((c == '\\') || (c == '"')) { + fprintf(stdout, "\\%c", c); + } + else { + putc(c, stdout); + } +} +*/ + +/* + +static void put_hex (int c) { + int lo, hi; + + if (c == '\n') { + fprintf(stdout, "\\n"); + lastCharWasHex= 0; + return; + } + + if (c == '\r') { + fprintf(stdout, "\\r"); + lastCharWasHex= 0; + return; + } + + if (c == '\t') { + fprintf(stdout, "\\t"); + lastCharWasHex= 0; + return; + } + + if ( (c == '"') || (c == '\\') || (c < 32) || (c > 126) ) { + goto printHex; + } + + if (lastCharWasHex && ( (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') )) { + goto printHex; + } + + putc(c, stdout); + lastCharWasHex= 0; + goto quit; + + printHex: + lo= c & 0x000f; + hi= (c & 0x00f0) >> 4; + fprintf(stdout, "\\x%c%c", hex[hi], hex[lo]); + lastCharWasHex= 1; + + quit: + return; +} +*/ + + +static void put_hex (int c) { + if (c == '\n') { + fputs("\\n", stdout); + } + else if (c == '\r') { + fputs("\\r", stdout); + } + else if (c == '\t') { + fputs("\\t", stdout); + } + else if (c == ' ') { + putc(c, stdout); + } + else { + int lo= c & 0x000f; + int hi= (c & 0x00f0) >> 4; + fprintf(stdout, "\\x%c%c", hex[hi], hex[lo]); + } +} + + +/* isAlphanum -- return true if the character is a letter, digit, underscore, +dollar sign, or non-ASCII character. +*/ +static int isAlphanum (int c) { + return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' || + c > 126); +} + + +/* get -- return the next character from stdin. Watch out for lookahead. If +the character is a control character, translate it to a space or +linefeed. +*/ + +static int get() { + int c = theLookahead; + theLookahead = EOF; + if (c == EOF) { + c = getc(stdin); + } + if (c >= ' ' || c == '\n' || c == EOF) { + return c; + } + if (c == '\r') { + return '\n'; + } + return ' '; +} + + +/* peek -- get the next character without getting it. +*/ + +static int peek () { + theLookahead = get(); + return theLookahead; +} + + +/* next -- get the next character, excluding comments. peek() is used to see +if a '/' is followed by a '/' or '*'. +*/ + +static int next () { + int c = get(); + if (c == '/') { + switch (peek()) { + case '/': + for (;;) { + c = get(); + if (c <= '\n') { + return c; + } + } + case '*': + get(); + for (;;) { + switch (get()) { + case '*': + if (peek() == '/') { + get(); + return ' '; + } + break; + case EOF: + fprintf(stderr, "Error: JSMIN Unterminated comment.\n"); + exit(1); + } + } + default: + return c; + } + } + return c; +} + + +/* action -- do something! What you do is determined by the argument: +1 Output A. Copy B to A. Get the next B. +2 Copy B to A. Get the next B. (Delete A). +3 Get the next B. (Delete B). +action treats a string as a single character. Wow! +action recognizes a regular expression if it is preceded by ( or , or =. +*/ + +static void action (int d) { + switch (d) { + case 1: + put_hex(theA); + case 2: + theA = theB; + if (theA == '\'' || theA == '"' || theA == '`') { + for (;;) { + put_hex(theA); + theA = get(); + if (theA == theB) { + break; + } + if (theA == '\\') { + put_hex(theA); + theA = get(); + } + if (theA == EOF) { + fprintf(stderr, "Error: JSMIN unterminated string literal."); + exit(1); + } + } + } + case 3: + theB = next(); + if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' || + theA == ':' || theA == '[' || theA == '!' || + theA == '&' || theA == '|' || theA == '?' || + theA == '{' || theA == '}' || theA == ';' || + theA == '\n')) { + put_hex(theA); + put_hex(theB); + for (;;) { + theA = get(); + if (theA == '[') { + for (;;) { + put_hex(theA); + theA = get(); + if (theA == ']') { + break; + } + if (theA == '\\') { + put_hex(theA); + theA = get(); + } + if (theA == EOF) { + fprintf(stderr, + "Error: JSMIN unterminated set in Regular Expression literal.\n"); + exit(1); + } + } + } else if (theA == '/') { + break; + } else if (theA =='\\') { + put_hex(theA); + theA = get(); + } + if (theA == EOF) { + fprintf(stderr, + "Error: JSMIN unterminated Regular Expression literal.\n"); + exit(1); + } + put_hex(theA); + } + theB = next(); + } + } + } + + +/* jsmin -- Copy the input to the output, deleting the characters which are +insignificant to JavaScript. Comments will be removed. Tabs will be +replaced with spaces. Carriage returns will be replaced with linefeeds. +Most spaces and linefeeds will be removed. +*/ + +static void jsmin() { + if (peek() == 0xEF) { + get(); + get(); + get(); + } + theA = '\n'; + action(3); + while (theA != EOF) { + switch (theA) { + case ' ': + if (isAlphanum(theB)) { + action(1); + } else { + action(2); + } + break; + case '\n': + switch (theB) { + case '{': + case '[': + case '(': + case '+': + case '-': + action(1); + break; + case ' ': + action(3); + break; + default: + if (isAlphanum(theB)) { + action(1); + } else { + action(2); + } + } + break; + default: + switch (theB) { + case ' ': + if (isAlphanum(theA)) { + action(1); + break; + } + action(3); + break; + case '\n': + switch (theA) { + case '}': + case ']': + case ')': + case '+': + case '-': + case '"': + case '\'': + case '`': + action(1); + break; + default: + if (isAlphanum(theA)) { + action(1); + } else { + action(3); + } + } + break; + default: + action(1); + break; + } + } + } +} + + +/* main -- Output any command line arguments as comments +and then minify the input. +*/ +int main (int argc, char* argv[]) { + if (argv[1] == NULL) exit(1); + fprintf(stdout, "static const char* %s= \"", argv[1]); + /* + len= 0; + first= 1; + */ + if (argv[2] == NULL) { + putchar('('); + jsmin(); + puts(")\";"); + } + else if (argv[3] == NULL) { + putchar('('); + jsmin(); + puts(")()\";"); + } + else { + jsmin(); + puts("\";"); + } + return 0; +} diff --git a/node_modules/webworker-threads/deps/minifier/src/test b/node_modules/webworker-threads/deps/minifier/src/test new file mode 100755 index 0000000..78ffee7 Binary files /dev/null and b/node_modules/webworker-threads/deps/minifier/src/test differ diff --git a/node_modules/webworker-threads/deps/minifier/src/test.include.c b/node_modules/webworker-threads/deps/minifier/src/test.include.c new file mode 100644 index 0000000..b7c3506 --- /dev/null +++ b/node_modules/webworker-threads/deps/minifier/src/test.include.c @@ -0,0 +1,14 @@ +static const char* _test= "\n\x28\x66\x75\x6e\x63\x74\x69\x6f\x6e \x6c\x6f\x61\x64\x28\x70\x2c\x63\x62\x29\x7b\x72\x65\x74\x75\x72\x6e \x74\x68\x69\x73\x2e\x65\x76\x61\x6c\x28\x72\x65\x71\x75\x69\x72\x65\x28\x27\x66\x73\x27\x29\x2e\x72\x65\x61\x64\x46\x69\x6c\x65\x53\x79\x6e\x63\x28\x70\x29\x2c\x63\x62\x29\x3b\x7d\x29"; + +/* +static const char _test[]= { + 0x0a, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x66, 0x73, 0x3d, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x28, 0x27, 0x66, 0x73, 0x27, 0x29, 0x2e, 0x72, 0x65, 0x61, 0x64, + 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, + 0x6f, 0x61, 0x64, 0x28, 0x70, 0x61, 0x74, 0x68, 0x2c, 0x63, 0x62, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, + 0x76, 0x61, 0x6c, 0x28, 0x72, 0x66, 0x73, 0x28, 0x70, 0x61, 0x74, 0x68, 0x29, + 0x2c, 0x63, 0x62, 0x29, 0x3b, 0x7d, 0x3b, 0x7d, 0x29, 0x28, 0x29, 0x00 }; +*/ \ No newline at end of file diff --git a/node_modules/webworker-threads/deps/minifier/src/test_minifier.c b/node_modules/webworker-threads/deps/minifier/src/test_minifier.c new file mode 100644 index 0000000..8be053b --- /dev/null +++ b/node_modules/webworker-threads/deps/minifier/src/test_minifier.c @@ -0,0 +1,8 @@ +#include +#include + +int main (int argc, char* argv[]) { + #include "test.include.c" + printf("%s\n\n", _test); + return 0; +} \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/demo.js b/node_modules/webworker-threads/examples/demo.js new file mode 100644 index 0000000..63316ae --- /dev/null +++ b/node_modules/webworker-threads/examples/demo.js @@ -0,0 +1,31 @@ +var http= require('http'); + +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +function fast (req,res) { + process.stdout.write('·'); + res.end("FAST"); +} + +function slow (req,res) { + process.stdout.write('•'); + res.end("SLOW -> "+ fibo(40)); +} + +var numThreads= parseInt(process.argv[2], 10) || 5; +console.log("Using "+ numThreads+ " threads."); +var Worker= require('webworker-threads'); +var threadPool= Worker.createPool(numThreads).all.eval(fibo); + +function tagg (req,res) { + threadPool.any.eval('fibo(40)', function (err, data) { + process.stdout.write('❚'); + res.end("TAGG -> "+ data); //Threads A GoGo + }); +} + +http.createServer(fast).listen(12345), console.log("fast @ localhost:12345"); +http.createServer(slow).listen(12346), console.log("slow @ localhost:12346"); +http.createServer(tagg).listen(12347), console.log("useThreads @ localhost:12347"); diff --git a/node_modules/webworker-threads/examples/ex01_basic.js b/node_modules/webworker-threads/examples/ex01_basic.js new file mode 100644 index 0000000..e82cd9d --- /dev/null +++ b/node_modules/webworker-threads/examples/ex01_basic.js @@ -0,0 +1,63 @@ +/// !example +/// ## Running a simple function in a thread +/// +/// This first example demonstrates how you can run an expensive computation in +/// a worker thread and obtain its result. +/// +/// First, we define the function that we want to execute in the worker thread: +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +/// Then, we create a worker thread with the `Threads.create` call: +var Threads = require('webworker-threads'); +var t = Threads.create(); +/// In the next step, we load the function into the worker thead. +/// We get the function's source with `fibo.toString()` and we +/// call `t.eval(source)` to evalutate it into the worker thread's context: +t.eval(fibo); +/// Now, we are ready to call this function. +/// We use the `t.eval` function again, with two arguments this time. +/// The first argument is the expression to evaluate. +/// The second one is a callback that receives the result (or an error if there was one). +t.eval('fibo(10)', function(err, result) { + if (err) throw err; // something abnormal + // print the result + console.log('fibo(10)=' + result); + // chain with next step + step2(); +}); +/// Let's call it again: +function step2() { + t.eval('fibo(20)', function(err, result) { + if (err) throw err; + console.log('fibo(20)=' + result); + step3(); + }); +} +/// If the expression is invalid, we get an error through the callback +function step3() { + // 'x' is not defined + t.eval('fibo(x)', function(err, result) { + console.log('error=' + err); + step4(); + }); +} +/// But the thread is still alive and ready to accept more calls: +function step4() { + t.eval('fibo(15)', function(err, result) { + console.log('fibo(15)=' + result); + step5(); + }); +} +/// Once we are done, we destroy the thread: +function step5() { + t.destroy(); +} +/// ### Output +/// +/// ``` +/// fibo(10)=89 +/// fibo(20)=10946 +/// error=Error: ReferenceError: x is not defined +/// fibo(15)=987 +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex01_basic.md b/node_modules/webworker-threads/examples/ex01_basic.md new file mode 100644 index 0000000..21ee60d --- /dev/null +++ b/node_modules/webworker-threads/examples/ex01_basic.md @@ -0,0 +1,94 @@ +## Running a simple function in a thread + +This first example demonstrates how you can run an expensive computation in +a worker thread and obtain its result. + +First, we define the function that we want to execute in the worker thread: + +``` javascript +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +``` + +Then, we create a worker thread with the `Threads.create` call: + +``` javascript +var Threads = require('webworker-threads'); +var t = Threads.create(); +``` + +In the next step, we load the function into the worker thead. +We get the function's source with `fibo.toString()` and we +call `t.eval(source)` to evalutate it into the worker thread's context: + +``` javascript +t.eval(fibo); +``` + +Now, we are ready to call this function. +We use the `t.eval` function again, with two arguments this time. +The first argument is the expression to evaluate. +The second one is a callback that receives the result (or an error if there was one). + +``` javascript +t.eval('fibo(10)', function(err, result) { + if (err) throw err; // something abnormal + // print the result + console.log('fibo(10)=' + result); + // chain with next step + step2(); +}); +``` + +Let's call it again: + +``` javascript +function step2() { + t.eval('fibo(20)', function(err, result) { + if (err) throw err; + console.log('fibo(20)=' + result); + step3(); + }); +} +``` + +If the expression is invalid, we get an error through the callback + +``` javascript +function step3() { + // 'x' is not defined + t.eval('fibo(x)', function(err, result) { + console.log('error=' + err); + step4(); + }); +} +``` + +But the thread is still alive and ready to accept more calls: + +``` javascript +function step4() { + t.eval('fibo(15)', function(err, result) { + console.log('fibo(15)=' + result); + step5(); + }); +} +``` + +Once we are done, we destroy the thread: + +``` javascript +function step5() { + t.destroy(); +} +``` + +### Output + +``` +fibo(10)=89 +fibo(20)=10946 +error=Error: ReferenceError: x is not defined +fibo(15)=987 +``` diff --git a/node_modules/webworker-threads/examples/ex02_events.js b/node_modules/webworker-threads/examples/ex02_events.js new file mode 100644 index 0000000..6d6bfac --- /dev/null +++ b/node_modules/webworker-threads/examples/ex02_events.js @@ -0,0 +1,54 @@ +/// !example +/// ## Sending events from a worker thread +/// +/// This second example demonstrates how we can use events to communicate from the worker +/// thread to the main thread. +/// +/// Like before, we create a thread and we define the fibonacci function: +var Threads = require('webworker-threads'); +var t = Threads.create(); + +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +/// Instead of running a single fibonacci computation in the worker thread, we are going to execute a function +/// that computes all fibonacci numbers and emits a `data` event for every number it generates. +/// +/// This function runs inside the worker thread so it does not see the `t` variable which belongs to the +/// main thread. But **webworker-threads** sets up a global `thread` variable that the worker thread can use to +/// send events to the main thread. +/// +/// Here is our fibonacci generator: +function generateFibos(max) { + for (var i = 1; i <= max; i++) { + thread.emit("data", i, fibo(i)); + } +} +/// Note: this is obviously a very inefficient algorithm to generate the sequence of fibonacci numbers. +/// +/// Inside the main thread, we set up an event listener for the `data` events emitted by the +/// worker thread: +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); +}) +/// Now, we are ready to go. We load the two functions into the worker thread +t.eval(fibo); +t.eval(generateFibos); +/// And we run the generator with a callback that will execute when the generator returns from its loop: +t.eval("generateFibos(40)", function(err, result) { + if (err) throw err; + console.log("generator is done!"); + t.destroy(); +}); +/// ### Output +/// +/// ``` +/// fibo(1) = 1 +/// fibo(2) = 2 +/// fibo(3) = 3 +/// fibo(4) = 5 +/// ... +/// fibo(39) = 102334155 +/// fibo(40) = 165580141 +/// generator is done! +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex02_events.md b/node_modules/webworker-threads/examples/ex02_events.md new file mode 100644 index 0000000..7819b17 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex02_events.md @@ -0,0 +1,73 @@ +## Sending events from a worker thread + +This second example demonstrates how we can use events to communicate from the worker +thread to the main thread. + +Like before, we create a thread and we define the fibonacci function: + +``` javascript +var Threads = require('webworker-threads'); +var t = Threads.create(); + +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +``` + +Instead of running a single fibonacci computation in the worker thread, we are going to execute a function +that computes all fibonacci numbers and emits a `data` event for every number it generates. + +This function runs inside the worker thread so it does not see the `t` variable which belongs to the +main thread. But **webworker-threads** sets up a global `thread` variable that the worker thread can use to +send events to the main thread. + +Here is our fibonacci generator: + +``` javascript +function generateFibos(max) { + for (var i = 1; i <= max; i++) { + thread.emit("data", i, fibo(i)); + } +} +``` + +Note: this is obviously a very inefficient algorithm to generate the sequence of fibonacci numbers. + +Inside the main thread, we set up an event listener for the `data` events emitted by the +worker thread: + +``` javascript +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); +}) +``` + +Now, we are ready to go. We load the two functions into the worker thread + +``` javascript +t.eval(fibo); +t.eval(generateFibos); +``` + +And we run the generator with a callback that will execute when the generator returns from its loop: + +``` javascript +t.eval("generateFibos(40)", function(err, result) { + if (err) throw err; + console.log("generator is done!"); + t.destroy(); +}); +``` + +### Output + +``` +fibo(1) = 1 +fibo(2) = 2 +fibo(3) = 3 +fibo(4) = 5 +... +fibo(39) = 102334155 +fibo(40) = 165580141 +generator is done! +``` diff --git a/node_modules/webworker-threads/examples/ex03_ping_pong.js b/node_modules/webworker-threads/examples/ex03_ping_pong.js new file mode 100644 index 0000000..f2d7df4 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex03_ping_pong.js @@ -0,0 +1,57 @@ +/// !example +/// ## Sending events both ways between the main thread and a worker thread +/// +/// This third example demonstrates how we can use events to communicate in both directions +/// between main thread and worker thread. +/// +/// Like before, we create a worker thread and we define the fibonacci function: +var Threads = require('webworker-threads'); +var t = Threads.create(); + +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +/// In the previous example we were running a loop that generates fibonacci numbers in the worker thread. +/// This is fine if the generator produces the number at a slower rate than the main thread can consume them +/// but it will hog memory if the main thread is too busy and cannot consume the data events fast enough. +/// We can improve this by controlling the flow with events in both directions. +/// +/// The `thread` global variable that **webworker-threads** predefines in every worker thread is also an `EventEmitter`. +/// So we will use it to send events in the other direction, from the main thread to the worker thread. +/// +/// Our modified generator does not use a loop any more. Instead, it generates numbers in response to `next` events +/// sent from the main thread. Here is the new generator: +function generateFibos() { + var i = 1; + thread.on('next', function() { + thread.emit('data', i, fibo(i)); + i++; + }); +} +/// From the main thread, we listen for the `data` events emitted by the worker thread. +/// Every time we get a `data` event from the worker thread, we print the result and we `emit` a +/// `next` event into the worker thread (stopping at 40): +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); + if (n < 40) t.emit('next'); + else console.log('bye!'), t.destroy(); +}); +/// We now have all we need for our little ping-pong game. We load the two functions into the thread: +t.eval(fibo); +t.eval(generateFibos); +/// We start the generator in the worker thread: +t.eval("generateFibos()"); +/// And we start the game by emitting the first `next` event: +t.emit('next'); +/// ### Output +/// +/// ``` +/// fibo(1) = 1 +/// fibo(2) = 2 +/// fibo(3) = 3 +/// fibo(4) = 5 +/// ... +/// fibo(39) = 102334155 +/// fibo(40) = 165580141 +/// bye! +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex03_ping_pong.md b/node_modules/webworker-threads/examples/ex03_ping_pong.md new file mode 100644 index 0000000..826df60 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex03_ping_pong.md @@ -0,0 +1,80 @@ +## Sending events both ways between the main thread and a worker thread + +This third example demonstrates how we can use events to communicate in both directions +between main thread and worker thread. + +Like before, we create a worker thread and we define the fibonacci function: + +``` javascript +var Threads = require('webworker-threads'); +var t = Threads.create(); + +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} +``` + +In the previous example we were running a loop that generates fibonacci numbers in the worker thread. +This is fine if the generator produces the number at a slower rate than the main thread can consume them +but it will hog memory if the main thread is too busy and cannot consume the data events fast enough. +We can improve this by controlling the flow with events in both directions. + +The `thread` global variable that **webworker-threads** predefines in every worker thread is also an `EventEmitter`. +So we will use it to send events in the other direction, from the main thread to the worker thread. + +Our modified generator does not use a loop any more. Instead, it generates numbers in response to `next` events +sent from the main thread. Here is the new generator: + +``` javascript +function generateFibos() { + var i = 1; + thread.on('next', function() { + thread.emit('data', i, fibo(i)); + i++; + }); +} +``` + +From the main thread, we listen for the `data` events emitted by the worker thread. +Every time we get a `data` event from the worker thread, we print the result and we `emit` a +`next` event into the worker thread (stopping at 40): + +``` javascript +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); + if (n < 40) t.emit('next'); + else console.log('bye!'), t.destroy(); +}); +``` + +We now have all we need for our little ping-pong game. We load the two functions into the thread: + +``` javascript +t.eval(fibo); +t.eval(generateFibos); +``` + +We start the generator in the worker thread: + +``` javascript +t.eval("generateFibos()"); +``` + +And we start the game by emitting the first `next` event: + +``` javascript +t.emit('next'); +``` + +### Output + +``` +fibo(1) = 1 +fibo(2) = 2 +fibo(3) = 3 +fibo(4) = 5 +... +fibo(39) = 102334155 +fibo(40) = 165580141 +bye! +``` diff --git a/node_modules/webworker-threads/examples/ex04_main.js b/node_modules/webworker-threads/examples/ex04_main.js new file mode 100644 index 0000000..be8ca7c --- /dev/null +++ b/node_modules/webworker-threads/examples/ex04_main.js @@ -0,0 +1,40 @@ +/// !example +/// ## Loading the worker code from a file (main side) +/// +/// When writing code for threads we have both code that executes in the main thread and code that +/// executes in worker threads. When the code is small, it may be handy to have all code in a single file +/// but it is often clearer to split the code apart when the worker code starts to grow. +/// +/// This example demonstrates how we can package the worker code in a separeate file and +/// load it with `t.load`. +/// +/// We are going to keep the same logic as in our previous 'ping pong' example, but just repackage +/// it slightly differently. +/// +/// In this file we keep only the ping (main) side: +// Creating the worker thread +var Threads = require('webworker-threads'); +var t = Threads.create(); + +// Listening to 'data' events from the worker thread +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); + if (n < 40) t.emit('next'); + else console.log('bye!'), t.destroy(); +}); +/// At this point we load the worker code: +t.load(__dirname + '/ex04_worker.js'); +/// And we start the game by emitting the first `next` event: +t.emit('next'); +/// ### Output +/// +/// ``` +/// fibo(1) = 1 +/// fibo(2) = 2 +/// fibo(3) = 3 +/// fibo(4) = 5 +/// ... +/// fibo(39) = 102334155 +/// fibo(40) = 165580141 +/// bye! +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex04_main.md b/node_modules/webworker-threads/examples/ex04_main.md new file mode 100644 index 0000000..f341518 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex04_main.md @@ -0,0 +1,51 @@ +## Loading the worker code from a file (main side) + +When writing code for threads we have both code that executes in the main thread and code that +executes in worker threads. When the code is small, it may be handy to have all code in a single file +but it is often clearer to split the code apart when the worker code starts to grow. + +This example demonstrates how we can package the worker code in a separeate file and +load it with `t.load`. + +We are going to keep the same logic as in our previous 'ping pong' example, but just repackage +it slightly differently. + +In this file we keep only the ping (main) side: + +``` javascript +// Creating the worker thread +var Threads = require('webworker-threads'); +var t = Threads.create(); + +// Listening to 'data' events from the worker thread +t.on('data', function(n, result) { + console.log('fibo(' + n + ') = ' + result); + if (n < 40) t.emit('next'); + else console.log('bye!'), t.destroy(); +}); +``` + +At this point we load the worker code: + +``` javascript +t.load(__dirname + '/ex04_worker.js'); +``` + +And we start the game by emitting the first `next` event: + +``` javascript +t.emit('next'); +``` + +### Output + +``` +fibo(1) = 1 +fibo(2) = 2 +fibo(3) = 3 +fibo(4) = 5 +... +fibo(39) = 102334155 +fibo(40) = 165580141 +bye! +``` diff --git a/node_modules/webworker-threads/examples/ex04_worker.js b/node_modules/webworker-threads/examples/ex04_worker.js new file mode 100644 index 0000000..4a784e6 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex04_worker.js @@ -0,0 +1,15 @@ +/// !example +/// ## Loading the worker code from a file (worker side) +/// +/// This file contains the pong (worker) side of our ping pong example. +/// It is loaded by a `t.load` call in `ex4_main.js`. +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +// returning the next fibonacci number when a 'next' event comes in: +var i = 1; +thread.on('next', function() { + thread.emit('data', i, fibo(i)); + i++; +}); \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex04_worker.md b/node_modules/webworker-threads/examples/ex04_worker.md new file mode 100644 index 0000000..1304675 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex04_worker.md @@ -0,0 +1,18 @@ +## Loading the worker code from a file (worker side) + +This file contains the pong (worker) side of our ping pong example. +It is loaded by a `t.load` call in `ex4_main.js`. + +``` javascript +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +// returning the next fibonacci number when a 'next' event comes in: +var i = 1; +thread.on('next', function() { + thread.emit('data', i, fibo(i)); + i++; +}); +``` + diff --git a/node_modules/webworker-threads/examples/ex05_pool.js b/node_modules/webworker-threads/examples/ex05_pool.js new file mode 100644 index 0000000..f9ce4d8 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex05_pool.js @@ -0,0 +1,52 @@ +/// !example +/// ## Using the thread pool +/// +/// Our previous examples used a single worker thread, and thus only one processor core. +/// If we want to take full advantage of multi-core processors, we need the ability to delegate +/// expensive computations to a pool of theads. This example demonstrates the pool thread that comes +/// bundled with Worker. +/// +/// First, we create a pool +var Threads = require('webworker-threads'); +var pool = Threads.createPool(3); +/// +/// Then we load our fibonacci function in all the pool's threads: +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +pool.all.eval(fibo); +/// Now, we can get fibonacci numbers from our pool +/// +/// We request them in reverse order, to show that longer computations (`fibo(40)`) run in +/// parallel with shorter ones (`fibo(39)`, `fibo(38)`, ...). The results won't come out in strictly decreasing order. +var remain = 11; +for (var i = 40; i >= 30; i--) { + // extra closure to get proper scoping on 'i' + (function(i) { + // dispatch each request to the first available thread + pool.any.eval('fibo(' + i + ')', function(err, val) { + console.log('fibo(' + i + ')=' + i); + // destroy the pool when all results have been produced + if (--remain == 0) console.log('bye!'), pool.destroy(); + }); + })(i); +} +/// ### Typical (*) Output +/// +/// (*) Execution is non-deterministic. So order may vary. +/// +/// ``` +/// fibo(38)=38 +/// fibo(39)=39 +/// fibo(37)=37 +/// fibo(35)=35 +/// fibo(36)=36 +/// fibo(33)=33 +/// fibo(34)=34 +/// fibo(31)=31 +/// fibo(32)=32 +/// fibo(30)=30 +/// fibo(40)=40 +/// bye! +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex05_pool.md b/node_modules/webworker-threads/examples/ex05_pool.md new file mode 100644 index 0000000..528793f --- /dev/null +++ b/node_modules/webworker-threads/examples/ex05_pool.md @@ -0,0 +1,63 @@ +## Using the thread pool + +Our previous examples used a single worker thread, and thus only one processor core. +If we want to take full advantage of multi-core processors, we need the ability to delegate +expensive computations to a pool of theads. This example demonstrates the pool thread that comes +bundled with webworker-threads. + +First, we create a pool + +``` javascript +var Threads = require('webworker-threads'); +var pool = Threads.createPool(3); +``` + + +Then we load our fibonacci function in all the pool's threads: + +``` javascript +function fibo(n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +pool.all.eval(fibo); +``` + +Now, we can get fibonacci numbers from our pool + +We request them in reverse order, to show that longer computations (`fibo(40)`) run in +parallel with shorter ones (`fibo(39)`, `fibo(38)`, ...). The results won't come out in strictly decreasing order. + +``` javascript +var remain = 11; +for (var i = 40; i >= 30; i--) { + // extra closure to get proper scoping on 'i' + (function(i) { + // dispatch each request to the first available thread + pool.any.eval('fibo(' + i + ')', function(err, val) { + console.log('fibo(' + i + ')=' + i); + // destroy the pool when all results have been produced + if (--remain == 0) console.log('bye!'), pool.destroy(); + }); + })(i); +} +``` + +### Typical (*) Output + +(*) Execution is non-deterministic. So order may vary. + +``` +fibo(38)=38 +fibo(39)=39 +fibo(37)=37 +fibo(35)=35 +fibo(36)=36 +fibo(33)=33 +fibo(34)=34 +fibo(31)=31 +fibo(32)=32 +fibo(30)=30 +fibo(40)=40 +bye! +``` diff --git a/node_modules/webworker-threads/examples/ex06_complex.js b/node_modules/webworker-threads/examples/ex06_complex.js new file mode 100644 index 0000000..d8d71b4 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex06_complex.js @@ -0,0 +1,39 @@ +/// A very simple class for complex numbers + +function Complex (x, y) { + this.x = x; + this.y = y; + this.add= complex_add; + this.mul= complex_mul; + this.toString= complex_toString; +} +function complex_toString () { + return this.x + (this.y > 0 ? " + " + this.y + "i" : this.y < 0 ? " - " + -this.y + "i" : ""); +} +function complex_add (c) { + return new Complex(this.x + c.x, this.y + c.y); +} +function complex_mul (c) { + return new Complex(this.x * c.x - this.y * c.y, this.x + c.y + this.y * c.x); +} + +/// A class to represent a degree 2 polynomial equation with real coefficients. + +function Equation (a, b, c) { + this.a = a; + this.b = b; + this.c = c; + this.toString= equation_toString; + this.solve= equation_solve; +} +function equation_toString () { + return this.a + "x^2 + " + this.b + "x + " + this.c +} +function equation_solve () { + var a = this.a, b = this.b, c = this.c + var det = b * b - 4 * a * c; + var sdet = Math.sqrt(Math.abs(det)); + var _2a = 2 * a; + if (det >= 0) return [new Complex((-b - sdet) / _2a, 0), new Complex((-b + sdet) / _2a, 0)]; + else return [new Complex(-b / _2a, -sdet / _2a), new Complex(-b / _2a, sdet / _2a)]; +} \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex06_jason.js b/node_modules/webworker-threads/examples/ex06_jason.js new file mode 100644 index 0000000..94c9474 --- /dev/null +++ b/node_modules/webworker-threads/examples/ex06_jason.js @@ -0,0 +1,42 @@ +/// !example +/// ## Passing complex objects to threads +/// +/// In the previous examples, we have been using threads with very simple functions and +/// we have been passing very simple values (integers) between threads. +/// +/// This example shows how we can pass more complex data between threads. +/// +/// It is important to understand that objects cannot be shared across threads. +/// This does not prevent us from passing complex objects but we have to serialize them +/// and pass them as strings. +/// +/// If the objects are really simple, we can use JSON serialization but if they contain +/// information that JSON discards, like methods, we should use the JASON serializer +/// published on https://github.com/xk/JASON +/// +/// In this example, we are going to use a thread to do computation with complex numbers. +/// We use the Complex and Equation classes defined in the ex06_complex.js file. +var Equation = require("./ex06_complex").Equation; +/// As usual, we create a thread +var t = require('webworker-threads').create(); +/// We require the JASON serializer +var JASON = require("JASON"); +/// We load the JASON serializer and the solve function in our thread: +t.eval("JASON= "+ JASON.stringify(JASON)); +t.load(__dirname + "/ex06_complex.js"); +/// Now we can pass a request to solve an equation to our thread. +/// The expression is wrapped into a `JASON.stringify` call because we want the thread +/// to stringify the solution object before returning it to the main thread +/// The main thread calls `JASON.parse` to _de-stringify_ the solution. +t.eval("JASON.stringify(new Equation(1, -4, 29).solve())", function(err, result) { + if (err) throw err; + var r = JASON.parse(result).join(', '); + console.log("\nsolution is:\n[" + r+ "]\n"); + t.destroy(); +}); +/// ### Typical Output +/// +/// ``` +/// solution is: +/// [2 - 5i, 2 + 5i] +/// ``` \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/ex06_jason.md b/node_modules/webworker-threads/examples/ex06_jason.md new file mode 100644 index 0000000..000c3af --- /dev/null +++ b/node_modules/webworker-threads/examples/ex06_jason.md @@ -0,0 +1,61 @@ +## Passing complex objects to threads + +In the previous examples, we have been using threads with very simple functions and +we have been passing very simple values (integers) between threads. + +This example shows how we can pass more complex data between threads. + +It is important to understand that objects cannot be shared across threads. +This does not prevent us from passing complex objects but we have to serialize them +and pass them as strings. + +If the objects are really simple, we can use JSON serialization but if they contain +information that JSON discards, like methods, we should use the JASON serializer +published on https://github.com/xk/JASON + +In this example, we are going to use a thread to do computation with complex numbers. +We use the Complex and Equation classes defined in the ex06_complex.js file. + +``` javascript +var Equation = require("./ex06_complex").Equation; +``` + +As usual, we create a thread + +``` javascript +var t = require('webworker-threads').create(); +``` + +We require the JASON serializer + +``` javascript +var JASON = require("JASON"); +``` + +We load the JASON serializer and the solve function in our thread: + +``` javascript +t.eval("JASON= "+ JASON.stringify(JASON)); +t.load(__dirname + "/ex06_complex.js") +``` + +Now we can pass a request to solve an equation to our thread. +The expression is wrapped into a `JASON.stringify` call because we want the thread +to stringify the solution object before returning it to the main thread +The main thread calls `JASON.parse` to _de-stringify_ the solution. + +``` javascript +t.eval("JASON.stringify(new Equation(1, -4, 29).solve())", function(err, result) { + if (err) throw err; + var r = JASON.parse(result).join(', '); + console.log("\nsolution is:\n[" + r+ "]\n"); + t.destroy(); +}); +``` + +### Typical Output + +``` +solution is: +[2 - 5i, 2 + 5i] +``` diff --git a/node_modules/webworker-threads/examples/fiveThreads.ls b/node_modules/webworker-threads/examples/fiveThreads.ls new file mode 100755 index 0000000..9d8b324 --- /dev/null +++ b/node_modules/webworker-threads/examples/fiveThreads.ls @@ -0,0 +1,15 @@ +#!/usr/bin/env lsc +# Same as multiThreadEvented.ls, but with 5 workers + +{ Worker } = require \webworker-threads + +for til 5 => (new Worker -> + fibo = (n) -> if n > 1 then fibo(n - 1) + fibo(n - 2) else 1 + @onmessage = ({ data }) -> postMessage fibo data +) + ..onmessage = ({ data }) -> + console.log "[#{ @thread.id }] #data" + @postMessage Math.ceil Math.random! * 30 + ..postMessage Math.ceil Math.random! * 30 + +do spin = -> process.nextTick spin diff --git a/node_modules/webworker-threads/examples/multiThreadEvented.ls b/node_modules/webworker-threads/examples/multiThreadEvented.ls new file mode 100755 index 0000000..982c1dd --- /dev/null +++ b/node_modules/webworker-threads/examples/multiThreadEvented.ls @@ -0,0 +1,15 @@ +#!/usr/bin/env lsc +# Minimal example for https://npmjs.org/package/webworker-threads + +{ Worker } = require \webworker-threads + +(new Worker -> + fibo = (n) -> if n > 1 then fibo(n - 1) + fibo(n - 2) else 1 + @onmessage = ({ data }) -> postMessage fibo data +) + ..onmessage = ({ data }) -> + console.log data + @postMessage Math.ceil Math.random! * 30 + ..postMessage Math.ceil Math.random! * 30 + +do spin = -> process.nextTick spin diff --git a/node_modules/webworker-threads/examples/quickIntro_blocking.js b/node_modules/webworker-threads/examples/quickIntro_blocking.js new file mode 100644 index 0000000..fedb97f --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_blocking.js @@ -0,0 +1,13 @@ +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +(function fiboLoop () { + process.stdout.write(fibo(35).toString()); + process.nextTick(fiboLoop); +})(); + +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_evented_childThreadCode.js b/node_modules/webworker-threads/examples/quickIntro_evented_childThreadCode.js new file mode 100644 index 0000000..ba31205 --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_evented_childThreadCode.js @@ -0,0 +1,7 @@ +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) { + this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread. +}); \ No newline at end of file diff --git a/node_modules/webworker-threads/examples/quickIntro_fiveThreads.js b/node_modules/webworker-threads/examples/quickIntro_fiveThreads.js new file mode 100644 index 0000000..1348a97 --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_fiveThreads.js @@ -0,0 +1,21 @@ +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +function cb (err, data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.eval('fibo(35)', cb); +} + +var Worker= require('webworker-threads'); + +Worker.create().eval(fibo).eval('fibo(35)', cb); +Worker.create().eval(fibo).eval('fibo(35)', cb); +Worker.create().eval(fibo).eval('fibo(35)', cb); +Worker.create().eval(fibo).eval('fibo(35)', cb); +Worker.create().eval(fibo).eval('fibo(35)', cb); + +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_loop.js b/node_modules/webworker-threads/examples/quickIntro_loop.js new file mode 100644 index 0000000..4d4212c --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_loop.js @@ -0,0 +1,4 @@ +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_multiThread.js b/node_modules/webworker-threads/examples/quickIntro_multiThread.js new file mode 100644 index 0000000..86e861e --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_multiThread.js @@ -0,0 +1,16 @@ +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +var numThreads= 10; +var threadPool= require('webworker-threads').createPool(numThreads).all.eval(fibo); + +threadPool.all.eval('fibo(35)', function cb (err, data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.eval('fibo(35)', cb); +}); + +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_multiThreadEvented.js b/node_modules/webworker-threads/examples/quickIntro_multiThreadEvented.js new file mode 100644 index 0000000..bd7f4c1 --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_multiThreadEvented.js @@ -0,0 +1,30 @@ +var numThreads= 10; +var threadPool= require('webworker-threads').createPool(numThreads); +threadPool.load(__dirname + '/quickIntro_evented_childThreadCode.js'); + +/* + This is the code that's .load()ed into the child/background threads: + + function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; + } + + thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) { + this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread. + }); + +*/ + +//Emit 'giveMeTheFibo' in all the child/background threads. +threadPool.all.emit('giveMeTheFibo', 35); + +//Listener for the 'theFiboIs' events emitted by the child/background thread. +threadPool.on('theFiboIs', function cb (data) { + process.stdout.write(" ["+ this.id+ "]"+ data); + this.emit('giveMeTheFibo', 35); +}); + +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_oneThread.js b/node_modules/webworker-threads/examples/quickIntro_oneThread.js new file mode 100644 index 0000000..82f342d --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_oneThread.js @@ -0,0 +1,17 @@ +function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; +} + +function cb (err, data) { + process.stdout.write(data); + this.eval('fibo(35)', cb); +} + +var thread= require('webworker-threads').create(); + +thread.eval(fibo).eval('fibo(35)', cb); + +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/examples/quickIntro_oneThreadEvented.js b/node_modules/webworker-threads/examples/quickIntro_oneThreadEvented.js new file mode 100644 index 0000000..fed6f41 --- /dev/null +++ b/node_modules/webworker-threads/examples/quickIntro_oneThreadEvented.js @@ -0,0 +1,18 @@ +var Worker = require('webworker-threads').Worker; +var w = new Worker(function(){ + function fibo (n) { + return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; + } + self.onmessage = function (event) { + self.postMessage( fibo( event.data ) ); + }; +}); +w.postMessage(Math.ceil(Math.random()*30)); +w.onmessage = function cb (event) { + process.stdout.write(event.data); + w.postMessage(Math.ceil(Math.random()*30)); +}; +(function spinForever () { + process.stdout.write("."); + process.nextTick(spinForever); +})(); diff --git a/node_modules/webworker-threads/package.json b/node_modules/webworker-threads/package.json new file mode 100644 index 0000000..d792ca4 --- /dev/null +++ b/node_modules/webworker-threads/package.json @@ -0,0 +1,70 @@ +{ + "name": "webworker-threads", + "version": "0.4.7", + "main": "build/Release/WebWorkerThreads.node", + "description": "Lightweight Web Worker API implementation with native threads", + "keywords": [ + "threads", + "web worker", + "a gogo" + ], + "author": { + "name": "Audrey Tang", + "email": "audreyt@audreyt.org" + }, + "homepage": "https://github.com/audreyt/node-webworker-threads", + "bugs": { + "url": "http://github.com/audreyt/node-webworker-threads/issues", + "email": "audreyt@audreyt.org" + }, + "licenses": [ + { + "type": "Apache License, Version 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + }, + { + "type": "MIT", + "url": "file:LICENSE" + } + ], + "repository": { + "type": "git", + "url": "http://github.com/audreyt/node-webworker-threads.git" + }, + "scripts": { + "js": "env PATH=./node_modules/.bin:\"$PATH\" lsc -cj package.ls;\ngcc deps/minifier/src/minify.c -o deps/minifier/bin/minify;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/worker.ls > src/worker.js;\n./deps/minifier/bin/minify kWorker_js < src/worker.js > src/worker.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/events.ls > src/events.js;\n./deps/minifier/bin/minify kEvents_js < src/events.js > src/events.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/createPool.ls > src/createPool.js;\n./deps/minifier/bin/minify kCreatePool_js < src/createPool.js > src/createPool.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/thread_nextTick.ls > src/thread_nextTick.js;\n./deps/minifier/bin/minify kThread_nextTick_js 1 < src/thread_nextTick.js > src/thread_nextTick.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/load.ls > src/load.js;\n./deps/minifier/bin/minify kLoad_js 1 1 < src/load.js > src/load.js.c;", + "install": "node-gyp rebuild" + }, + "devDependencies": { + "LiveScript": "1.1.x" + }, + "gypfile": true, + "engines": { + "node": ">= 0.8.0" + }, + "contributors": [ + { + "name": "//Threads_a_gogo AUTHORS" + }, + { + "name": "2011-11-06 Jorge Chamorro Bieling", + "email": "jorge@jorgechamorro.com" + }, + { + "name": "2011-11-25 Juan Falgueras Cano", + "email": "juan.falgueras@gmail.com" + }, + { + "name": "2012-01-26 Bruno Jouhier", + "email": "bjouhier@gmail.com" + } + ], + "readme": "# WebWorker Threads\n\nThis is based on @xk (jorgechamorro)'s [Threads A GoGo for Node.js](https://github.com/audreyt/node-threads-a-gogo), but with an API conforming to the [Web Worker standard](http://www.w3.org/TR/workers/).\n\nThis module provides an asynchronous, evented and/or continuation passing style API for moving blocking/longish CPU-bound tasks out of Node's event loop to JavaScript threads that run in parallel in the background and that use all the available CPU cores automatically; all from within a single Node process.\n\nThis module requires Node.js 0.8.0+.\n\nOn Unix (including Linux and OS X), this module requires a working node-gyp toolchain, which in turn requires make and C/C++.\nFor example, on OS X, you could install XCode from Apple, and then use it to install the command line tools (under Preferences -> Downloads).\n\nOn Windows, this module requires Node.js 0.9.3+ and a working [node-gyp toolchain](http://dailyjs.com/2012/05/17/windows-and-node-3/).\n\n## Installing the module\n\nWith [npm](http://npmjs.org/):\n\n npm install webworker-threads\n\nSample usage (adapted from [MDN](https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers#Passing_data)):\n\n```js\nvar Worker = require('webworker-threads').Worker;\n// var w = new Worker('worker.js'); // Standard API\n\n// You may also pass in a function:\nvar worker = new Worker(function(){\n postMessage(\"I'm working before postMessage('ali').\");\n onmessage = function(event) {\n postMessage('Hi ' + event.data);\n self.close();\n };\n});\nworker.onmessage = function(event) {\n console.log(\"Worker said : \" + event.data);\n};\nworker.postMessage('ali');\n```\n\nA more involved example in [LiveScript](http://livescript.net/) syntax, with five threads:\n\n```coffee\n{ Worker } = require \\webworker-threads\n\nfor til 5 => (new Worker ->\n fibo = (n) -> if n > 1 then fibo(n - 1) + fibo(n - 2) else 1\n @onmessage = ({ data }) -> postMessage fibo data\n)\n ..onmessage = ({ data }) ->\n console.log \"[#{ @thread.id }] #data\"\n @postMessage Math.ceil Math.random! * 30\n ..postMessage Math.ceil Math.random! * 30\n\ndo spin = -> process.nextTick spin\n```\n\n## Introduction\n\nAfter the initialization phase of a Node program, whose purpose is to setup listeners and callbacks to be executed in response to events, the next phase, the proper execution of the program, is orchestrated by the event loop whose duty is to [juggle events, listeners and callbacks quickly and without any hiccups nor interruptions that would ruin its performance](http://youtube.com/v/D0uA_NOb0PE?autoplay=1)\n\nBoth the event loop and said listeners and callbacks run sequentially in a single thread of execution, Node's main thread. If any of them ever blocks, nothing else will happen for the duration of the block: no more events will be handled, no more callbacks nor listeners nor timeouts nor nextTick()ed functions will have the chance to run and do their job, because they won't be called by the blocked event loop, and the program will turn sluggish at best, or appear to be frozen and dead at worst.\n\n### What is WebWorker-Threads\n\n`webworker-threads` provides an asynchronous API for CPU-bound tasks that's missing in Node.js:\n\n``` javascript\nvar Worker = require('webworker-threads').Worker;\nrequire('http').createServer(function (req,res) {\n var fibo = new Worker(function() {\n function fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n }\n onmessage = function (event) {\n postMessage(fibo(event.data));\n }\n });\n fibo.onmessage = function (event) {\n res.end('fib(40) = ' + event.data);\n };\n fibo.postMessage(40);\n}).listen(port);\n```\n\nAnd it won't block the event loop because for each request, the `fibo` worker will run in parallel in a separate background thread.\n\n## API\n\n### Module API\n``` javascript\nvar Threads= require('webworker-threads');\n```\n##### .Worker\n`new Threads.Worker( [ file | function ] )` returns a Worker object.\n##### .create()\n`Threads.create( /* no arguments */ )` returns a thread object.\n##### .createPool( numThreads )\n`Threads.createPool( numberOfThreads )` returns a threadPool object.\n\n---\n### Web Worker API\n``` javascript\nvar worker= new Threads.Worker('worker.js');\nvar worker= new Threads.Worker(function(){ ... });\nvar worker= new Threads.Worker();\n```\n##### .postMessage( data )\n`worker.postMessage({ x: 1, y: 2 })` sends a data structure into the worker. The worker can receive it using the `onmessage` handler.\n##### .onmessage\n`worker.onmessage = function (event) { console.log(event.data) };` receives data from the worker's `postMessage` calls.\n##### .terminate()\n`worker.terminate()` terminates the worker thread.\n##### .addEventListener( type, cb )\n`worker.addEventListener('message', callback)` is equivalent to setting `worker.onmesssage = callback`.\n##### .dispatchEvent( event )\nCurrently unimplemented.\n##### .removeEventListener( type )\nCurrently unimplemented.\n##### .thread\nReturns the underlying `thread` object; see the next section for details.\nNote that this attribute is implementation-specific, and not part of W3C Web Worker API.\n\n---\n### Thread API\n``` javascript\nvar thread= Threads.create();\n```\n##### .id\n`thread.id` is a sequential thread serial number.\n##### .load( absolutePath [, cb] )\n`thread.load( absolutePath [, cb] )` reads the file at `absolutePath` and `thread.eval(fileContents, cb)`.\n##### .eval( program [, cb])\n`thread.eval( program [, cb])` converts `program.toString()` and eval()s it in the thread's global context, and (if provided) returns the completion value to `cb(err, completionValue)`.\n##### .on( eventType, listener )\n`thread.on( eventType, listener )` registers the listener `listener(data)` for any events of `eventType` that the thread `thread` may emit.\n##### .once( eventType, listener )\n`thread.once( eventType, listener )` is like `thread.on()`, but the listener will only be called once.\n##### .removeAllListeners( [eventType] )\n`thread.removeAllListeners( [eventType] )` deletes all listeners for all eventTypes. If `eventType` is provided, deletes all listeners only for the event type `eventType`.\n##### .emit( eventType, eventData [, eventData ... ] )\n`thread.emit( eventType, eventData [, eventData ... ] )` emits an event of `eventType` with `eventData` inside the thread `thread`. All its arguments are .toString()ed.\n##### .destroy( /* no arguments */ )\n`thread.destroy( /* no arguments */ )` destroys the thread.\n\n---\n### Thread pool API\n``` javascript\nthreadPool= Threads.createPool( numberOfThreads );\n```\n##### .load( absolutePath [, cb] )\n`threadPool.load( absolutePath [, cb] )` runs `thread.load( absolutePath [, cb] )` in all the pool's threads.\n##### .any.eval( program, cb )\n`threadPool.any.eval( program, cb )` is like `thread.eval()`, but in any of the pool's threads.\n##### .any.emit( eventType, eventData [, eventData ... ] )\n`threadPool.any.emit( eventType, eventData [, eventData ... ] )` is like `thread.emit()`, but in any of the pool's threads.\n##### .all.eval( program, cb )\n`threadPool.all.eval( program, cb )` is like `thread.eval()`, but in all the pool's threads.\n##### .all.emit( eventType, eventData [, eventData ... ] )\n`threadPool.all.emit( eventType, eventData [, eventData ... ] )` is like `thread.emit()`, but in all the pool's threads.\n##### .on( eventType, listener )\n`threadPool.on( eventType, listener )` is like `thread.on()`, registers listeners for events from any of the threads in the pool.\n##### .totalThreads()\n`threadPool.totalThreads()` returns the number of threads in this pool: as supplied in `.createPool( number )`\n##### .idleThreads()\n`threadPool.idleThreads()` returns the number of threads in this pool that are currently idle (sleeping)\n##### .pendingJobs()\n`threadPool.pendingJobs()` returns the number of jobs pending.\n##### .destroy( [ rudely ] )\n`threadPool.destroy( [ rudely ] )` waits until `pendingJobs()` is zero and then destroys the pool. If `rudely` is truthy, then it doesn't wait for `pendingJobs === 0`.\n\n---\n### Global Web Worker API\n\nInside every Worker instance from webworker-threads, there's a global `self` object with these properties:\n\n##### .postMessage( data )\n`postMessage({ x: 1, y: 2 })` sends a data structure back to the main thread.\n##### .onmessage\n`onmessage = function (event) { ... }` receives data from the main thread's `.postMessage` calls.\n##### .close()\n`close()` stops the current thread.\n##### .addEventListener( type, cb )\n`addEventListener('message', callback)` is equivalent to setting `self.onmesssage = callback`.\n##### .dispatchEvent( event )\n`dispatchEvent({ type: 'message', data: data })` is the same as `self.postMessage(data)`.\n##### .removeEventListener( type )\nCurrently unimplemented.\n##### .importScripts( file [, file...] )\n`importScripts('a.js', 'b.js')` loads one or more files from the disk and `eval()` them in the worker's instance scope.\n##### .thread\nThe underlying `thread` object; see the next section for details.\nNote that this attribute is implementation-specific, and not part of W3C Web Worker API.\n\n---\n### Global Thread API\n\nInside every thread .create()d by webworker-threads, there's a global `thread` object with these properties:\n##### .id\n`thread.id` is the serial number of this thread\n##### .on( eventType, listener )\n`thread.on( eventType, listener )` is just like `thread.on()` above.\n##### .once( eventType, listener )\n`thread.once( eventType, listener )` is just like `thread.once()` above.\n##### .emit( eventType, eventData [, eventData ... ] )\n`thread.emit( eventType, eventData [, eventData ... ] )` is just like `thread.emit()` above.\n##### .removeAllListeners( [eventType] )\n`thread.removeAllListeners( [eventType] )` is just like `thread.removeAllListeners()` above.\n##### .nextTick( function )\n`thread.nextTick( function )` is like `process.nextTick()`, but much faster.\n\n---\n### Global Helper API\n\nInside every thread .create()d by webworker-threads, there are some helpers:\n\n##### console.log(arg1 [, arg2 ...])\nSame as `console.log` on the main process.\n\n##### console.error(arg1 [, arg2 ...])\nSame as `console.log`, except it prints to stderr.\n\n##### puts(arg1 [, arg2 ...])\n`puts(arg1 [, arg2 ...])` converts .toString()s and prints its arguments to stdout.\n\n-----------\nWIP WIP WIP\n-----------\nNote that everything below this line is under construction and subject to change.\n-----------\n\n## Examples\n\n**A.-** Here's a program that makes Node's event loop spin freely and as fast as possible: it simply prints a dot to the console in each turn:\n\n cat examples/quickIntro_loop.js\n \n``` javascript\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**B.-** Here's another program that adds to the one above a fibonacci(35) call in each turn, a CPU-bound task that takes quite a while to complete and that blocks the event loop making it spin slowly and clumsily. The point is simply to show that you can't put a job like that in the event loop because Node will stop performing properly when its event loop can't spin fast and freely due to a callback/listener/nextTick()ed function that's blocking.\n\n cat examples/quickIntro_blocking.js\n\n``` javascript\nfunction fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n}\n\n(function fiboLoop () {\n process.stdout.write(fibo(35).toString());\n process.nextTick(fiboLoop);\n})();\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**C.-** The program below uses `webworker-threads` to run the fibonacci(35) calls in a background thread, so Node's event loop isn't blocked at all and can spin freely again at full speed:\n\n cat examples/quickIntro_oneThread.js\n \n``` javascript\nfunction fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n}\n\nfunction cb (err, data) {\n process.stdout.write(data);\n this.eval('fibo(35)', cb);\n}\n\nvar thread= require('webworker-threads').create();\n\nthread.eval(fibo).eval('fibo(35)', cb);\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**D.-** This example is almost identical to the one above, only that it creates 5 threads instead of one, each running a fibonacci(35) in parallel and in parallel too with Node's event loop that keeps spinning happily at full speed in its own thread:\n\n cat examples/quickIntro_fiveThreads.js\n \n``` javascript\nfunction fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n}\n\nfunction cb (err, data) {\n process.stdout.write(\" [\"+ this.id+ \"]\"+ data);\n this.eval('fibo(35)', cb);\n}\n\nvar Threads= require('webworker-threads');\n\nThreads.create().eval(fibo).eval('fibo(35)', cb);\nThreads.create().eval(fibo).eval('fibo(35)', cb);\nThreads.create().eval(fibo).eval('fibo(35)', cb);\nThreads.create().eval(fibo).eval('fibo(35)', cb);\nThreads.create().eval(fibo).eval('fibo(35)', cb);\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**E.-** The next one asks `webworker-threads` to create a pool of 10 background threads, instead of creating them manually one by one:\n\n cat examples/multiThread.js\n\n``` javascript\nfunction fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n}\n\nvar numThreads= 10;\nvar threadPool= require('webworker-threads').createPool(numThreads).all.eval(fibo);\n\nthreadPool.all.eval('fibo(35)', function cb (err, data) {\n process.stdout.write(\" [\"+ this.id+ \"]\"+ data);\n this.eval('fibo(35)', cb);\n});\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**F.-** This is a demo of the `webworker-threads` eventEmitter API, using one thread:\n\n cat examples/quickIntro_oneThreadEvented.js\n\n``` javascript\nvar thread= require('webworker-threads').create();\nthread.load(__dirname + '/quickIntro_evented_childThreadCode.js');\n\n/*\n This is the code that's .load()ed into the child/background thread:\n \n function fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n }\n\n thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) {\n this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread.\n });\n \n*/\n\n//Emit 'giveMeTheFibo' in the child/background thread.\nthread.emit('giveMeTheFibo', 35);\n\n//Listener for the 'theFiboIs' events emitted by the child/background thread.\nthread.on('theFiboIs', function cb (data) {\n process.stdout.write(data);\n this.emit('giveMeTheFibo', 35);\n});\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n**G.-** This is a demo of the `webworker-threads` eventEmitter API, using a pool of threads:\n\n cat examples/quickIntro_multiThreadEvented.js\n\n``` javascript\nvar numThreads= 10;\nvar threadPool= require('webworker-threads').createPool(numThreads);\nthreadPool.load(__dirname + '/quickIntro_evented_childThreadCode.js');\n\n/*\n This is the code that's .load()ed into the child/background threads:\n \n function fibo (n) {\n return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;\n }\n\n thread.on('giveMeTheFibo', function onGiveMeTheFibo (data) {\n this.emit('theFiboIs', fibo(+data)); //Emits 'theFiboIs' in the parent/main thread.\n });\n \n*/\n\n//Emit 'giveMeTheFibo' in all the child/background threads.\nthreadPool.all.emit('giveMeTheFibo', 35);\n\n//Listener for the 'theFiboIs' events emitted by the child/background threads.\nthreadPool.on('theFiboIs', function cb (data) {\n process.stdout.write(\" [\"+ this.id+ \"]\"+ data);\n this.emit('giveMeTheFibo', 35);\n});\n\n(function spinForever () {\n process.nextTick(spinForever);\n})();\n```\n\n## More examples\n\nThe `examples` directory contains a few more examples:\n\n* [ex01_basic](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex01_basic.md): Running a simple function in a thread.\n* [ex02_events](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex02_events.md): Sending events from a worker thread.\n* [ex03_ping_pong](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex03_ping_pong.md): Sending events both ways between the main thread and a worker thread.\n* [ex04_main](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex04_main.md): Loading the worker code from a file.\n* [ex05_pool](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex05_pool.md): Using the thread pool.\n* [ex06_jason](https://github.com/xk/node-threads-a-gogo/blob/master/examples/ex06_jason.md): Passing complex objects to threads.\n\n## Rationale\n\n[Node.js](http://nodejs.org) is the most awesome, cute and super-sexy piece of free, open source software.\n\nIts event loop can spin as fast and smooth as a turbo, and roughly speaking, **the faster it spins, the more power it delivers**. That's why [@ryah](http://twitter.com/ryah) took great care to ensure that no -possibly slow- I/O operations could ever block it: a pool of background threads (thanks to [Marc Lehmann's libeio library](http://software.schmorp.de/pkg/libeio.html)) handle any blocking I/O calls in the background, in parallel.\n\nIn Node it's verboten to write a server like this:\n\n``` javascript\nhttp.createServer(function (req,res) {\n res.end( fs.readFileSync(path) );\n}).listen(port);\n```\nBecause synchronous I/O calls **block the turbo**, and without proper boost, Node.js begins to stutter and behaves clumsily. To avoid it there's the asynchronous version of `.readFile()`, in continuation passing style, that takes a callback:\n\n``` javascript\nfs.readfile(path, function cb (err, data) { /* ... */ });\n```\n\nIt's cool, we love it (*), and there's hundreds of ad hoc built-in functions like this in Node to help us deal with almost any variety of possibly slow, blocking I/O.\n\n### But what's with longish, CPU-bound tasks?\n\nHow do you avoid blocking the event loop, when the task at hand isn't I/O bound, and lasts more than a few fractions of a millisecond?\n\n``` javascript\nhttp.createServer(function cb (req,res) {\n res.end( fibonacci(40) );\n}).listen(port);\n```\n\nYou simply can't, because there's no way... well, there wasn't before `webworker-threads`.\n\n### Why Threads\n\nThreads (kernel threads) are very interesting creatures. They provide:\n\n1.- Parallelism: All the threads run in parallel. On a single core processor, the CPU is switched rapidly back and forth among the threads providing the illusion that the threads are running in parallel, albeit on a slower CPU than the real one. With 10 compute-bound threads in a process, the threads would appear to be running in parallel, each one on a CPU with 1/10th the speed of the real CPU. On a multi-core processor, threads are truly running in parallel, and get time-sliced when the number of threads exceed the number of cores. So with 12 compute bound threads on a quad-core processor each thread will appear to run at 1/3rd of the nominal core speed.\n\n2.- Fairness: No thread is more important than another, cores and CPU slices are fairly distributed among threads by the OS scheduler.\n\n3.- Threads fully exploit all the available CPU resources in your system. On a loaded system running many tasks in many threads, the more cores there are, the faster the threads will complete. Automatically.\n\n4.- The threads of a process share exactly the same address space, that of the process they belong to. Every thread can access every memory address within the process' address space. This is a very appropriate setup when the threads are actually part of the same job and are actively and closely cooperating with each other. Passing a reference to a chunk of data via a pointer is many orders of magnitude faster than transferring a copy of the data via IPC.\n\n### Why not multiple processes.\n\nThe \"can't block the event loop\" problem is inherent to Node's evented model. No matter how many Node processes you have running as a [Node-cluster](http://blog.nodejs.org/2011/10/04/an-easy-way-to-build-scalable-network-programs/), it won't solve its issues with CPU-bound tasks.\n\nLaunch a cluster of N Nodes running the example B (`quickIntro_blocking.js`) above, and all you'll get is N -instead of one- Nodes with their event loops blocked and showing a sluggish performance.\n", + "readmeFilename": "README.md", + "_id": "webworker-threads@0.4.7", + "dist": { + "shasum": "be36d346b673b0ab80d5cbc3914fb234ecb136a3" + }, + "_from": "webworker-threads@", + "_resolved": "https://registry.npmjs.org/webworker-threads/-/webworker-threads-0.4.7.tgz" +} diff --git a/node_modules/webworker-threads/package.ls b/node_modules/webworker-threads/package.ls new file mode 100755 index 0000000..ca3e388 --- /dev/null +++ b/node_modules/webworker-threads/package.ls @@ -0,0 +1,41 @@ +#!/usr/bin/env lsc -cj +name: \webworker-threads +version: \0.4.7 +main: \build/Release/WebWorkerThreads.node +description: 'Lightweight Web Worker API implementation with native threads' +keywords: [ 'threads' 'web worker' 'a gogo' ] +author: + name: 'Audrey Tang' + email: \audreyt@audreyt.org + twitter: \audreyt +homepage: \https://github.com/audreyt/node-webworker-threads +bugs: + url: \http://github.com/audreyt/node-webworker-threads/issues + email: \audreyt@audreyt.org +licenses: [ + { type: "Apache License, Version 2.0", url: "http://www.apache.org/licenses/LICENSE-2.0" } + { type: 'MIT', url: "file:LICENSE" } +] +repository: + type: \git + url: \http://github.com/audreyt/node-webworker-threads.git +scripts: +# prepublish: 'env PATH=./node_modules/.bin:"$PATH" lsc -cj package.ls' + js: """ + env PATH=./node_modules/.bin:"$PATH" lsc -cj package.ls; + gcc deps/minifier/src/minify.c -o deps/minifier/bin/minify; + env PATH=./node_modules/.bin:"$PATH" lsc -cbp src/worker.ls > src/worker.js; + ./deps/minifier/bin/minify kWorker_js < src/worker.js > src/worker.js.c; + env PATH=./node_modules/.bin:"$PATH" lsc -cbp src/events.ls > src/events.js; + ./deps/minifier/bin/minify kEvents_js < src/events.js > src/events.js.c; + env PATH=./node_modules/.bin:"$PATH" lsc -cbp src/createPool.ls > src/createPool.js; + ./deps/minifier/bin/minify kCreatePool_js < src/createPool.js > src/createPool.js.c; + env PATH=./node_modules/.bin:"$PATH" lsc -cbp src/thread_nextTick.ls > src/thread_nextTick.js; + ./deps/minifier/bin/minify kThread_nextTick_js 1 < src/thread_nextTick.js > src/thread_nextTick.js.c; + env PATH=./node_modules/.bin:"$PATH" lsc -cbp src/load.ls > src/load.js; + ./deps/minifier/bin/minify kLoad_js 1 1 < src/load.js > src/load.js.c; + """ +dev-dependencies: + LiveScript: \1.1.x +gypfile: true +engines: { node: '>= 0.8.0' } diff --git a/node_modules/webworker-threads/src/WebWorkerThreads.cc b/node_modules/webworker-threads/src/WebWorkerThreads.cc new file mode 100644 index 0000000..7cf7746 --- /dev/null +++ b/node_modules/webworker-threads/src/WebWorkerThreads.cc @@ -0,0 +1,955 @@ +//2011-11 Proyectos Equis Ka, s.l., jorge@jorgechamorro.com +//WebWorkerThreads.cc + + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) || defined(_AIX) +#define WWT_PTHREAD 1 +#include +#include +#ifndef uv_cond_t +#define uv_cond_signal(x) pthread_cond_signal(x) +#define uv_cond_init(x) pthread_cond_init(x, NULL) +#define uv_cond_wait(x,y) pthread_cond_wait(x, y) +typedef pthread_cond_t uv_cond_t; +#endif +#else +#define pthread_setcancelstate(x,y) NULL +#define pthread_setcanceltype(x,y) NULL +#endif + + +/* +static int debug_threads= 0; +static int debug_allocs= 0; +*/ + +#include "queues_a_gogo.cc" +#include "bson.cc" +#include "jslib.cc" + +//using namespace node; +using namespace v8; + +static Persistent id_symbol; +static Persistent threadTemplate; +static bool useLocker; + +static typeQueue* freeJobsQueue= NULL; +static typeQueue* freeThreadsQueue= NULL; + +#define kThreadMagicCookie 0x99c0ffee +typedef struct { + uv_async_t async_watcher; //MUST be the first one + + long int id; + uv_thread_t thread; + volatile int sigkill; + + typeQueue inQueue; //Jobs to run + typeQueue outQueue; //Jobs done + + volatile int IDLE; + uv_cond_t IDLE_cv; + uv_mutex_t IDLE_mutex; + + Isolate* isolate; + Persistent context; + Persistent JSObject; + Persistent threadJSObject; + Persistent dispatchEvents; + + unsigned long threadMagicCookie; +} typeThread; + +enum jobTypes { + kJobTypeEval, + kJobTypeEvent, + kJobTypeEventSerialized +}; + +typedef struct { + int jobType; + Persistent cb; + union { + struct { + int length; + String::Utf8Value* eventName; + String::Utf8Value** argumentos; + } typeEvent; + struct { + int length; + String::Utf8Value* eventName; + char* buffer; + size_t bufferSize; + } typeEventSerialized; + struct { + int error; + int tiene_callBack; + int useStringObject; + String::Utf8Value* resultado; + union { + char* scriptText_CharPtr; + String::Utf8Value* scriptText_StringObject; + }; + } typeEval; + }; +} typeJob; + +/* + +cd deps/minifier/src +gcc minify.c -o minify +cat ../../../src/events.js | ./minify kEvents_js > ../../../src/kEvents_js +cat ../../../src/load.js | ./minify kLoad_js > ../../../src/kLoad_js +cat ../../../src/createPool.js | ./minify kCreatePool_js > ../../../src/kCreatePool_js +cat ../../../src/worker.js | ./minify kWorker_js > ../../../src/kWorker_js +cat ../../../src/thread_nextTick.js | ./minify kThread_nextTick_js > ../../../src/kThread_nextTick_js + +*/ + +#include "events.js.c" +#include "load.js.c" +#include "createPool.js.c" +#include "worker.js.c" +#include "thread_nextTick.js.c" +//#include "JASON.js.c" + +//node-waf configure uninstall distclean configure build install + + + + + + + + +static typeQueueItem* nuJobQueueItem (void) { + typeQueueItem* qitem= queue_pull(freeJobsQueue); + if (!qitem) { + qitem= nuItem(kItemTypePointer, calloc(1, sizeof(typeJob))); + } + return qitem; +} + + + + + + +static typeThread* isAThread (Handle receiver) { + typeThread* thread; + + if (receiver->IsObject()) { + if (receiver->InternalFieldCount() == 1) { + thread= (typeThread*) receiver->GetPointerFromInternalField(0); + if (thread && (thread->threadMagicCookie == kThreadMagicCookie)) { + return thread; + } + } + } + + return NULL; +} + + + + + + +static void pushToInQueue (typeQueueItem* qitem, typeThread* thread) { + uv_mutex_lock(&thread->IDLE_mutex); + queue_push(qitem, &thread->inQueue); + if (thread->IDLE) { + uv_cond_signal(&thread->IDLE_cv); + } + uv_mutex_unlock(&thread->IDLE_mutex); +} + + + + + + +static Handle Puts (const Arguments &args) { + //fprintf(stdout, "*** Puts BEGIN\n"); + + HandleScope scope; + int i= 0; + while (i < args.Length()) { + String::Utf8Value c_str(args[i]); + fputs(*c_str, stdout); + i++; + } + fflush(stdout); + + //fprintf(stdout, "*** Puts END\n"); + return Undefined(); +} + +static Handle Print (const Arguments &args) { + HandleScope scope; + int i= 0; + while (i < args.Length()) { + String::Utf8Value c_str(args[i]); + fputs(*c_str, stdout); + i++; + } + static char end = '\n'; + fputs(&end, stdout); + fflush(stdout); + + //fprintf(stdout, "*** Puts END\n"); + return Undefined(); +} + + + + +static void eventLoop (typeThread* thread); + +// A background thread +#ifdef WWT_PTHREAD +static void* aThread (void* arg) { +#else +static void aThread (void* arg) { +#endif + + int dummy; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &dummy); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &dummy); + + typeThread* thread= (typeThread*) arg; + thread->isolate= Isolate::New(); + thread->isolate->SetData(thread); + + if (useLocker) { + //printf("**** USING LOCKER: YES\n"); + v8::Locker myLocker(thread->isolate); + //v8::Isolate::Scope isolate_scope(thread->isolate); + eventLoop(thread); + } + else { + //printf("**** USING LOCKER: NO\n"); + //v8::Isolate::Scope isolate_scope(thread->isolate); + eventLoop(thread); + } + thread->isolate->Exit(); + thread->isolate->Dispose(); + + // wake up callback + if (!(thread->inQueue.length)) uv_async_send(&thread->async_watcher); +#ifdef WWT_PTHREAD + return NULL; +#endif +} + + + +static Handle threadEmit (const Arguments &args); +static Handle postMessage (const Arguments &args); +static Handle postError (const Arguments &args); + + + +static void eventLoop (typeThread* thread) { + thread->isolate->Enter(); + thread->context= Context::New(); + thread->context->Enter(); + + { + HandleScope scope1; + + Local global= thread->context->Global(); + + Handle fs_obj = Object::New(); + JSObjFn(fs_obj, "readFileSync", readFileSync_); + global->Set(String::New("native_fs_"), fs_obj, attribute_ro_dd); + + Handle console_obj = Object::New(); + JSObjFn(console_obj, "log", console_log); + JSObjFn(console_obj, "error", console_error); + global->Set(String::New("console"), console_obj, attribute_ro_dd); + + global->Set(String::NewSymbol("self"), global); + global->Set(String::NewSymbol("global"), global); + + global->Set(String::NewSymbol("puts"), FunctionTemplate::New(Puts)->GetFunction()); + global->Set(String::NewSymbol("print"), FunctionTemplate::New(Print)->GetFunction()); + + global->Set(String::NewSymbol("postMessage"), FunctionTemplate::New(postMessage)->GetFunction()); + global->Set(String::NewSymbol("__postError"), FunctionTemplate::New(postError)->GetFunction()); + + Local threadObject= Object::New(); + global->Set(String::NewSymbol("thread"), threadObject); + + threadObject->Set(String::NewSymbol("id"), Number::New(thread->id)); + threadObject->Set(String::NewSymbol("emit"), FunctionTemplate::New(threadEmit)->GetFunction()); + Local dispatchEvents= Script::Compile(String::New(kEvents_js))->Run()->ToObject()->CallAsFunction(threadObject, 0, NULL)->ToObject(); + Local dispatchNextTicks= Script::Compile(String::New(kThread_nextTick_js))->Run()->ToObject(); + Local _ntq= (v8::Array*) *threadObject->Get(String::NewSymbol("_ntq")); + + Script::Compile(String::New(kLoad_js))->Run(); + + double nextTickQueueLength= 0; + long int ctr= 0; + + //SetFatalErrorHandler(FatalErrorCB); + + while (!thread->sigkill) { + typeJob* job; + typeQueueItem* qitem; + + { + HandleScope scope2; + TryCatch onError; + String::Utf8Value* str; + Local source; + Local