From 960ccdc72cefa9c7b9e588a1d149a1dba7a0c296 Mon Sep 17 00:00:00 2001 From: Artur Adib Date: Tue, 8 Nov 2011 21:13:59 -0500 Subject: [PATCH 01/25] docs: clarify addon docs --- doc/api/addons.markdown | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 3234e7a60822..3e815d4d44e1 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -22,8 +22,8 @@ Node statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries. -To get started let's make a small Addon which does the following except in -C++: +To get started let's make a small Addon which is the C++ equivalent of +the following Javascript code: exports.hello = function() { return 'world'; }; @@ -40,11 +40,18 @@ To get started we create a file `hello.cc`: } void init(Handle target) { - NODE_SET_METHOD(target, "method", Method); + NODE_SET_METHOD(target, "hello", Method); } NODE_MODULE(hello, init) -This source code needs to be built into `hello.node`, the binary Addon. To +Note that all Node addons must export an initialization function: + + void Initialize (Handle target); + NODE_MODULE(module_name, Initialize) + +There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`). + +The source code needs to be built into `hello.node`, the binary Addon. To do this we create a file called `wscript` which is python code and looks like this: @@ -70,10 +77,12 @@ Running `node-waf configure build` will create a file `node-waf` is just [WAF](http://code.google.com/p/waf), the python-based build system. `node-waf` is provided for the ease of users. -All Node addons must export an initialization function: +You can now use the binary addon in a Node project `hello.js` by pointing `require` to +the recently built module: - void Initialize (Handle target); - NODE_MODULE(hello, Initialize) + var addon = require('./build/Release/hello'); + + console.log(addon.hello()); // 'world' For the moment, that is all the documentation on addons. Please see for a real example. From 8f15582ef333e6091af06f7095b9b785e82eb1ab Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Nov 2011 13:36:29 +0100 Subject: [PATCH 02/25] test: add 'no response headers' http parser test --- test/simple/test-http-parser.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/simple/test-http-parser.js b/test/simple/test-http-parser.js index 086d53bf448f..2382726a4acf 100644 --- a/test/simple/test-http-parser.js +++ b/test/simple/test-http-parser.js @@ -149,6 +149,29 @@ function expectBody(expected) { })(); +// +// Response with no headers. +// +(function() { + var request = Buffer( + 'HTTP/1.0 200 Connection established' + CRLF + + CRLF + ); + + var parser = newParser(RESPONSE); + + parser.onHeadersComplete = mustCall(function(info) { + assert.equal(info.method, undefined); + assert.equal(info.versionMajor, 1); + assert.equal(info.versionMinor, 0); + assert.equal(info.statusCode, 200); + assert.deepEqual(info.headers || parser.headers, []); + }); + + parser.execute(request, 0, request.length); +})(); + + // // Trailing headers. // @@ -481,7 +504,7 @@ function expectBody(expected) { // -// +// Test parser reinit sequence. // (function() { var req1 = Buffer( From 4f38c5ece3017923eebf034b815755c98c8c6113 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Nov 2011 16:30:37 +0100 Subject: [PATCH 03/25] test: add 'response body with no headers' http test HTTP/0.9 - fails with a parse error HTTP/1.0 - works HTTP/1.1 - fails with an empty response body See #1711. --- test/simple/test-http-response-no-headers.js | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 test/simple/test-http-response-no-headers.js diff --git a/test/simple/test-http-response-no-headers.js b/test/simple/test-http-response-no-headers.js new file mode 100644 index 000000000000..aa5c37b78972 --- /dev/null +++ b/test/simple/test-http-response-no-headers.js @@ -0,0 +1,75 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var net = require('net'); + +var expected = 'I AM THE WALRUS'; + +var gotExpected = false; + +function test(httpVersion, callback) { + process.on('exit', function() { + assert(gotExpected); + }); + + var server = net.createServer(function(conn) { + var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' + expected; + + conn.write(reply, function() { + conn.destroy(); + }) + }); + + server.listen(common.PORT, '127.0.0.1', function() { + var options = { + host: '127.0.0.1', + port: common.PORT + }; + + var req = http.get(options, function(res) { + var body = ''; + + res.on('data', function(data) { + body += data; + }); + + res.on('end', function() { + assert.equal(body, expected); + gotExpected = true; + server.close(); + if (callback) process.nextTick(callback); + }); + }); + + req.on('error', function(err) { + throw err; + }); + }); +} + +test('0.9', function() { + test('1.0', function() { + test('1.1'); + }); +}); From 2c52ccea80e74d813ba678ad2f39bd2079c73bf7 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 2 Sep 2011 14:39:04 +0000 Subject: [PATCH 04/25] v8: compile with __C99FEATURES__=1 on sunos Exposes INFINITY, isinf(), isfinite(), etc. Re-applies d104e5b91cfa3ef3ef846d5a0ab07c0336263a92, lost in a V8 upgrade. --- deps/v8/tools/gyp/v8-node.gyp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/deps/v8/tools/gyp/v8-node.gyp b/deps/v8/tools/gyp/v8-node.gyp index 3b067a5f5608..f2b3a337bd87 100644 --- a/deps/v8/tools/gyp/v8-node.gyp +++ b/deps/v8/tools/gyp/v8-node.gyp @@ -3,4 +3,11 @@ '../../build/common.gypi', 'v8.gyp' ], + 'target_defaults': { + 'conditions': [ + [ 'OS=="solaris"', { + 'defines': [ '__C99FEATURES__=1' ], + }], + ], + }, } From 4f8a0cd2f9d92135fe6e9e94229d1332dff3e0e0 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 2 Sep 2011 14:39:44 +0000 Subject: [PATCH 05/25] v8: add platform-solaris.cc to gyp build Re-applies 77e4abbc3e66505af89c57cd7bff555890a33f3f, lost in a V8 upgrade. --- deps/v8/tools/gyp/v8.gyp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp index 50144172a047..92d1e5c96a6d 100644 --- a/deps/v8/tools/gyp/v8.gyp +++ b/deps/v8/tools/gyp/v8.gyp @@ -641,6 +641,13 @@ ], } ], + ['OS=="solaris"', { + 'sources': [ + '../../src/platform-solaris.cc', + '../../src/platform-posix.cc' + ], + } + ], ['OS=="mac"', { 'sources': [ '../../src/platform-macos.cc', From e2581696669003fdd691c167ff1500ef16dddb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=2E=20Azer=20Ko=C3=A7ulu?= Date: Wed, 16 Nov 2011 23:20:06 -0800 Subject: [PATCH 06/25] util: remove the line requiring events --- lib/util.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/util.js b/lib/util.js index 639c04f9e7a1..aafc0edf3259 100644 --- a/lib/util.js +++ b/lib/util.js @@ -19,9 +19,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -var events = require('events'); - - var formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (typeof f !== 'string') { From b0030af13566e22cca289595a7e80b76f5e2c2f2 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 17 Nov 2011 11:39:14 -0800 Subject: [PATCH 07/25] Fixes #2140. Fix illumos build. --- src/node.h | 1 + src/node_object_wrap.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/node.h b/src/node.h index 1d322370d19f..cb58a220bbeb 100644 --- a/src/node.h +++ b/src/node.h @@ -62,6 +62,7 @@ #include #include /* struct stat */ #include +#include #include diff --git a/src/node_object_wrap.h b/src/node_object_wrap.h index d76dd594ab81..0ead639b6457 100644 --- a/src/node_object_wrap.h +++ b/src/node_object_wrap.h @@ -22,6 +22,7 @@ #ifndef object_wrap_h #define object_wrap_h +#include #include #include From 534e41b4747b9f9311ccbc62d8525963a4d9708a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Nov 2011 20:46:40 +0100 Subject: [PATCH 08/25] crypto: make verify() return true or false, not 1 or 0 It's what the documentation says it should return. --- src/node_crypto.cc | 2 +- test/simple/test-crypto.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index c1e197b62c95..9d34304af05c 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3483,7 +3483,7 @@ class Verify : public ObjectWrap { delete [] kbuf; delete [] hbuf; - return scope.Close(Integer::New(r)); + return Boolean::New(r && r != -1); } Verify () : ObjectWrap () { diff --git a/test/simple/test-crypto.js b/test/simple/test-crypto.js index 583eec755199..6b1c6ca0204c 100644 --- a/test/simple/test-crypto.js +++ b/test/simple/test-crypto.js @@ -286,7 +286,7 @@ var verified = crypto.createVerify('RSA-SHA1') .update('Test') .update('123') .verify(certPem, s1, 'base64'); -assert.ok(verified, 'sign and verify (base 64)'); +assert.strictEqual(verified, true, 'sign and verify (base 64)'); var s2 = crypto.createSign('RSA-SHA256') .update('Test123') @@ -295,7 +295,7 @@ var verified = crypto.createVerify('RSA-SHA256') .update('Test') .update('123') .verify(certPem, s2); // binary -assert.ok(verified, 'sign and verify (binary)'); +assert.strictEqual(verified, true, 'sign and verify (binary)'); // Test encryption and decryption var plaintext = 'Keep this a secret? No! Tell everyone about node.js!'; @@ -392,7 +392,7 @@ var rsaSignature = rsaSign.sign(rsaKeyPem, 'hex'); assert.equal(rsaSignature, '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6'); rsaVerify.update(rsaPubPem); -assert.equal(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), 1); +assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); // Test PBKDF2 with RFC 6070 test vectors (except #4) From 29d8ff51c85ddd491672ade6f4f3404f0f68e1a4 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Nov 2011 23:48:40 +0100 Subject: [PATCH 09/25] build: remove v8-node.gyp --- deps/v8/build/common.gypi | 3 +++ deps/v8/tools/gyp/v8-node.gyp | 13 ------------- node.gyp | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) delete mode 100644 deps/v8/tools/gyp/v8-node.gyp diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 4e896e019a85..34508913fedd 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -184,6 +184,9 @@ }], ], }], + ['OS=="solaris"', { + 'defines': [ '__C99FEATURES__=1' ], # isinf() etc. + }], ], 'configurations': { 'Debug': { diff --git a/deps/v8/tools/gyp/v8-node.gyp b/deps/v8/tools/gyp/v8-node.gyp deleted file mode 100644 index f2b3a337bd87..000000000000 --- a/deps/v8/tools/gyp/v8-node.gyp +++ /dev/null @@ -1,13 +0,0 @@ -{ - 'includes': [ - '../../build/common.gypi', - 'v8.gyp' - ], - 'target_defaults': { - 'conditions': [ - [ 'OS=="solaris"', { - 'defines': [ '__C99FEATURES__=1' ], - }], - ], - }, -} diff --git a/node.gyp b/node.gyp index abc83c51b373..e2413979124e 100644 --- a/node.gyp +++ b/node.gyp @@ -55,7 +55,7 @@ 'dependencies': [ 'deps/http_parser/http_parser.gyp:http_parser', - 'deps/v8/tools/gyp/v8-node.gyp:v8', + 'deps/v8/tools/gyp/v8.gyp:v8', 'deps/uv/uv.gyp:uv', 'deps/zlib/zlib.gyp:zlib', 'node_js2c#host', From 4f8d6d0834ef7132aa9702f4c83033daf42f9d06 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 15 Nov 2011 23:52:23 +0000 Subject: [PATCH 10/25] build: fix gyp xcode project generator Only attempt to generate FrameworkPhase output for code targets. --- tools/gyp/pylib/gyp/generator/xcode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gyp/pylib/gyp/generator/xcode.py b/tools/gyp/pylib/gyp/generator/xcode.py index 066bb9f02f85..f905efdd896e 100644 --- a/tools/gyp/pylib/gyp/generator/xcode.py +++ b/tools/gyp/pylib/gyp/generator/xcode.py @@ -1161,7 +1161,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if support_xct: support_xct.AddDependency(xcode_targets[dependency]) - if 'libraries' in spec: + if spec['type'] != 'none' and 'libraries' in spec: for library in spec['libraries']: xct.FrameworksPhase().AddFile(library) # Add the library's directory to LIBRARY_SEARCH_PATHS if necessary. From 48d21dd541929c85ee5bc0d7082811663442a698 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 17 Nov 2011 17:18:29 -0800 Subject: [PATCH 11/25] Force makefile generation in gyp --- Makefile | 4 ++-- configure | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f8dbeaffd4b5..2511dce1c0f5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ BUILDTYPE ?= Release all: out/Makefile - tools/gyp_node -f make $(MAKE) -C out BUILDTYPE=$(BUILDTYPE) -ln -fs out/Release/node node -ln -fs out/Debug/node node_g @@ -14,7 +13,8 @@ clean: rm -rf out distclean: - rm -rf out + -rm -rf out + -options.gypi test: all python tools/test.py --mode=release simple message diff --git a/configure b/configure index 36ffb6bcf767..53b63b186c8d 100755 --- a/configure +++ b/configure @@ -246,4 +246,4 @@ json.dump(output, f, indent=2, skipkeys=True) f.write("\n") f.close() -subprocess.call('tools/gyp_node') +subprocess.call(['tools/gyp_node','-f', 'make']) From 1b2d333ee3f3f4deb79e09f07358a4b8aec4933c Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 18 Nov 2011 13:07:01 +0100 Subject: [PATCH 12/25] uv: upgrade to e4680cc --- deps/uv/config-unix.mk | 1 + deps/uv/include/uv-private/uv-unix.h | 4 + deps/uv/include/uv-private/uv-win.h | 11 + deps/uv/include/uv.h | 14 ++ deps/uv/src/unix/core.c | 4 +- deps/uv/src/unix/internal.h | 71 ++++-- deps/uv/src/unix/kqueue.c | 1 + deps/uv/src/unix/process.c | 4 +- deps/uv/src/unix/stream.c | 4 +- deps/uv/src/unix/thread.c | 141 ++++++++++++ deps/uv/src/win/handle.c | 2 +- deps/uv/src/win/thread.c | 320 +++++++++++++++++++++++++++ deps/uv/src/win/threads.c | 81 ------- deps/uv/src/win/winapi.c | 28 +++ deps/uv/src/win/winapi.h | 27 +++ deps/uv/test/test-fs-event.c | 42 +++- deps/uv/test/test-list.h | 6 + deps/uv/test/test-mutexes.c | 63 ++++++ deps/uv/uv.gyp | 4 +- 19 files changed, 722 insertions(+), 106 deletions(-) create mode 100644 deps/uv/src/unix/thread.c create mode 100644 deps/uv/src/win/thread.c delete mode 100644 deps/uv/src/win/threads.c create mode 100644 deps/uv/test/test-mutexes.c diff --git a/deps/uv/config-unix.mk b/deps/uv/config-unix.mk index 8fe7254cfdd2..c8220c56f274 100644 --- a/deps/uv/config-unix.mk +++ b/deps/uv/config-unix.mk @@ -33,6 +33,7 @@ OBJS += src/unix/fs.o OBJS += src/unix/cares.o OBJS += src/unix/udp.o OBJS += src/unix/error.o +OBJS += src/unix/thread.o OBJS += src/unix/process.o OBJS += src/unix/tcp.o OBJS += src/unix/pipe.o diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 21078fe36370..abbccc2cc437 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -34,6 +34,7 @@ #include #include #include +#include /* Note: May be cast to struct iovec. See writev(2). */ typedef struct { @@ -43,6 +44,9 @@ typedef struct { typedef int uv_file; +typedef pthread_mutex_t uv_mutex_t; +typedef pthread_rwlock_t uv_rwlock_t; + /* Platform-specific definitions for uv_dlopen support. */ typedef void* uv_lib_t; #define UV_DYNAMIC /* empty */ diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h index 5d461090f159..e5afd321c86b 100644 --- a/deps/uv/include/uv-private/uv-win.h +++ b/deps/uv/include/uv-private/uv-win.h @@ -137,6 +137,17 @@ typedef struct uv_buf_t { typedef int uv_file; +typedef CRITICAL_SECTION uv_mutex_t; + +typedef union { + SRWLOCK srwlock_; + struct { + uv_mutex_t read_mutex_; + uv_mutex_t write_mutex_; + unsigned int num_readers_; + } fallback_; +} uv_rwlock_t; + /* Platform-specific definitions for uv_dlopen support. */ typedef HMODULE uv_lib_t; #define UV_DYNAMIC FAR WINAPI diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index a2c4f2aa7a57..3da160a27c51 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1243,6 +1243,20 @@ UV_EXTERN uv_err_t uv_dlclose(uv_lib_t library); */ UV_EXTERN uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr); +UV_EXTERN int uv_mutex_init(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle); + +UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); /* the presence of these unions force similar struct layout */ union uv_any_handle { diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 4d8324136630..ac00569477d4 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -727,8 +727,8 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) { assert(sockfd >= 0); while (1) { -#if HAVE_ACCEPT4 - peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC); +#if HAVE_SYS_ACCEPT4 + peerfd = sys_accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC); if (peerfd != -1) break; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 12ab62177c1f..4784bcf84bfe 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -28,30 +28,69 @@ #include /* offsetof */ #undef HAVE_FUTIMES -#undef HAVE_PIPE2 -#undef HAVE_ACCEPT4 #undef HAVE_KQUEUE #undef HAVE_PORTS_FS #if defined(__linux__) -#include -#include +# undef HAVE_SYS_UTIMESAT +# undef HAVE_SYS_PIPE2 +# undef HAVE_SYS_ACCEPT4 -/* futimes() requires linux >= 2.6.22 and glib >= 2.6 */ -#if LINUX_VERSION_CODE >= 0x20616 && __GLIBC_PREREQ(2, 6) -#define HAVE_FUTIMES 1 -#endif +# undef _GNU_SOURCE +# define _GNU_SOURCE -/* pipe2() requires linux >= 2.6.27 and glibc >= 2.9 */ -#if LINUX_VERSION_CODE >= 0x2061B && __GLIBC_PREREQ(2, 9) -#define HAVE_PIPE2 1 -#endif +# include +# include +# include +# include -/* accept4() requires linux >= 2.6.28 and glib >= 2.10 */ -#if LINUX_VERSION_CODE >= 0x2061C && __GLIBC_PREREQ(2, 10) -#define HAVE_ACCEPT4 1 -#endif +# if __NR_utimensat +# define HAVE_SYS_UTIMESAT 1 +# endif +# if __NR_pipe2 +# define HAVE_SYS_PIPE2 1 +# endif +# if __NR_accept4 +# define HAVE_SYS_ACCEPT4 1 +# endif + +# if HAVE_SYS_UTIMESAT +inline static int sys_utimesat(int dirfd, + const char* path, + const struct timespec times[2], + int flags) +{ + return syscall(__NR_utimensat, dirfd, path, times, flags); +} +inline static int sys_futimes(int fd, const struct timeval times[2]) +{ + struct timespec ts[2]; + ts[0].tv_sec = times[0].tv_sec, ts[0].tv_nsec = times[0].tv_usec * 1000; + ts[1].tv_sec = times[1].tv_sec, ts[1].tv_nsec = times[1].tv_usec * 1000; + return sys_utimesat(fd, NULL, ts, 0); +} +# undef HAVE_FUTIMES +# define HAVE_FUTIMES 1 +# define futimes(fd, times) sys_futimes(fd, times) +# endif /* HAVE_SYS_FUTIMESAT */ + +# if HAVE_SYS_PIPE2 +inline static int sys_pipe2(int pipefd[2], int flags) +{ + return syscall(__NR_pipe2, pipefd, flags); +} +# endif /* HAVE_SYS_PIPE2 */ + +# if HAVE_SYS_ACCEPT4 +inline static int sys_accept4(int fd, + struct sockaddr* addr, + socklen_t* addrlen, + int flags) +{ + return syscall(__NR_accept4, fd, addr, addrlen, flags); +} +# endif /* HAVE_SYS_ACCEPT4 */ #endif /* __linux__ */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index 00180cd41d36..ad80a26fbb06 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -116,6 +116,7 @@ int uv_fs_event_init(uv_loop_t* loop, void uv__fs_event_destroy(uv_fs_event_t* handle) { + uv__fs_event_stop(handle); free(handle->filename); uv__close(handle->fd); handle->fd = -1; diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index c5a459291571..5581d8b80998 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -104,7 +104,7 @@ static int uv__make_socketpair(int fds[2], int flags) { static int uv__make_pipe(int fds[2], int flags) { -#if HAVE_PIPE2 +#if HAVE_SYS_PIPE2 int fl; fl = O_CLOEXEC; @@ -112,7 +112,7 @@ static int uv__make_pipe(int fds[2], int flags) { if (flags & UV__F_NONBLOCK) fl |= O_NONBLOCK; - if (pipe2(fds, fl) == 0) + if (sys_pipe2(fds, fl) == 0) return 0; if (errno != ENOSYS) diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 25737814e583..3cdeaa8cf7b2 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -145,7 +145,7 @@ void uv__stream_destroy(uv_stream_t* stream) { req = ngx_queue_data(q, uv_write_t, queue); if (req->cb) { - uv__set_sys_error(stream->loop, req->error); + uv__set_artificial_error(stream->loop, req->error); req->cb(req, req->error ? -1 : 0); } } @@ -490,7 +490,7 @@ static void uv__write_callbacks(uv_stream_t* stream) { /* NOTE: call callback AFTER freeing the request data. */ if (req->cb) { - uv__set_sys_error(stream->loop, req->error); + uv__set_artificial_error(stream->loop, req->error); req->cb(req, req->error ? -1 : 0); } diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c new file mode 100644 index 000000000000..b5c0f19839eb --- /dev/null +++ b/deps/uv/src/unix/thread.c @@ -0,0 +1,141 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + + +#ifdef NDEBUG +# define CHECK(r) ((void) (r)) +#else +# include +# include +# define CHECK(r) \ + do { \ + int __r = (r); \ + if (__r) errno = __r, perror(#r), abort(); \ + } \ + while (0) +#endif + + +int uv_mutex_init(uv_mutex_t* mutex) { + if (pthread_mutex_init(mutex, NULL)) + return -1; + else + return 0; +} + + +void uv_mutex_destroy(uv_mutex_t* mutex) { + CHECK(pthread_mutex_destroy(mutex)); +} + + +void uv_mutex_lock(uv_mutex_t* mutex) { + CHECK(pthread_mutex_lock(mutex)); +} + + +int uv_mutex_trylock(uv_mutex_t* mutex) { + int r; + + r = pthread_mutex_trylock(mutex); + + if (r && r != EAGAIN) + CHECK(r); + + if (r) + return -1; + else + return 0; +} + + +void uv_mutex_unlock(uv_mutex_t* mutex) { + CHECK(pthread_mutex_unlock(mutex)); +} + + +int uv_rwlock_init(uv_rwlock_t* rwlock) { + if (pthread_rwlock_init(rwlock, NULL)) + return -1; + else + return 0; +} + + +void uv_rwlock_destroy(uv_rwlock_t* rwlock) { + CHECK(pthread_rwlock_destroy(rwlock)); +} + + +void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { + CHECK(pthread_rwlock_rdlock(rwlock)); +} + + +int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { + int r; + + r = pthread_rwlock_tryrdlock(rwlock); + + if (r && r != EAGAIN) + CHECK(r); + + if (r) + return -1; + else + return 0; +} + + +void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { + CHECK(pthread_rwlock_unlock(rwlock)); +} + + +void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { + CHECK(pthread_rwlock_wrlock(rwlock)); +} + + +int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { + int r; + + r = pthread_rwlock_trywrlock(rwlock); + + if (r && r != EAGAIN) + CHECK(r); + + if (r) + return -1; + else + return 0; +} + + +void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { + CHECK(pthread_rwlock_unlock(rwlock)); +} diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index b67139cbc6a5..ba0af755fe7f 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -35,7 +35,7 @@ uv_handle_type uv_guess_handle(uv_file file) { if (GetConsoleMode(handle, &mode)) { return UV_TTY; } else { - return UV_UNKNOWN_HANDLE; + return UV_FILE; } case FILE_TYPE_PIPE: diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c new file mode 100644 index 000000000000..1ee1a10c3ead --- /dev/null +++ b/deps/uv/src/win/thread.c @@ -0,0 +1,320 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * 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. + */ + +#include "uv.h" +#include "../uv-common.h" +#include "internal.h" +#include + +#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL) + +#ifdef _MSC_VER /* msvc */ +# define inline __inline +# define NOINLINE __declspec (noinline) +#else /* gcc */ +# define inline inline +# define NOINLINE __attribute__ ((noinline)) +#endif + + +inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock); +inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock); +inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock); +inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock); +inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock); + +inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock); +inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock); +inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock); +inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock); +inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock); +inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock); + + +static NOINLINE void uv__once_inner(uv_once_t* guard, + void (*callback)(void)) { + DWORD result; + HANDLE existing_event, created_event; + HANDLE* event_ptr; + + /* Fetch and align event_ptr */ + event_ptr = (HANDLE*) (((uintptr_t) &guard->event + (sizeof(HANDLE) - 1)) & + ~(sizeof(HANDLE) - 1)); + + created_event = CreateEvent(NULL, 1, 0, NULL); + if (created_event == 0) { + /* Could fail in a low-memory situation? */ + uv_fatal_error(GetLastError(), "CreateEvent"); + } + + existing_event = InterlockedCompareExchangePointer(event_ptr, + created_event, + NULL); + + if (existing_event == NULL) { + /* We won the race */ + callback(); + + result = SetEvent(created_event); + assert(result); + guard->ran = 1; + + } else { + /* We lost the race. Destroy the event we created and wait for the */ + /* existing one to become signaled. */ + CloseHandle(created_event); + result = WaitForSingleObject(existing_event, INFINITE); + assert(result == WAIT_OBJECT_0); + } +} + + +void uv_once(uv_once_t* guard, void (*callback)(void)) { + /* Fast case - avoid WaitForSingleObject. */ + if (guard->ran) { + return; + } + + uv__once_inner(guard, callback); +} + +int uv_mutex_init(uv_mutex_t* mutex) { + InitializeCriticalSection(mutex); + return 0; +} + + +void uv_mutex_destroy(uv_mutex_t* mutex) { + DeleteCriticalSection(mutex); +} + + +void uv_mutex_lock(uv_mutex_t* mutex) { + EnterCriticalSection(mutex); +} + + +int uv_mutex_trylock(uv_mutex_t* mutex) { + if (TryEnterCriticalSection(mutex)) + return 0; + else + return -1; +} + + +void uv_mutex_unlock(uv_mutex_t* mutex) { + LeaveCriticalSection(mutex); +} + + +int uv_rwlock_init(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + return uv__rwlock_srwlock_init(rwlock); + else + return uv__rwlock_fallback_init(rwlock); +} + + +void uv_rwlock_destroy(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + uv__rwlock_srwlock_destroy(rwlock); + else + uv__rwlock_fallback_destroy(rwlock); +} + + +void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + uv__rwlock_srwlock_rdlock(rwlock); + else + uv__rwlock_fallback_rdlock(rwlock); +} + + +int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + return uv__rwlock_srwlock_tryrdlock(rwlock); + else + return uv__rwlock_fallback_tryrdlock(rwlock); +} + + +void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + uv__rwlock_srwlock_rdunlock(rwlock); + else + uv__rwlock_fallback_rdunlock(rwlock); +} + + +void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + uv__rwlock_srwlock_wrlock(rwlock); + else + uv__rwlock_fallback_wrlock(rwlock); +} + + +int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + return uv__rwlock_srwlock_trywrlock(rwlock); + else + return uv__rwlock_fallback_trywrlock(rwlock); +} + + +void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { + if (HAVE_SRWLOCK_API()) + uv__rwlock_srwlock_wrunlock(rwlock); + else + uv__rwlock_fallback_wrunlock(rwlock); +} + + +inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) { + pInitializeSRWLock(&rwlock->srwlock_); + return 0; +} + + +inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) { + (void) rwlock; +} + + +inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) { + pAcquireSRWLockShared(&rwlock->srwlock_); +} + + +inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) { + if (pTryAcquireSRWLockShared(&rwlock->srwlock_)) + return 0; + else + return -1; +} + + +inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) { + pReleaseSRWLockShared(&rwlock->srwlock_); +} + + +inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) { + pAcquireSRWLockExclusive(&rwlock->srwlock_); +} + + +inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) { + if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_)) + return 0; + else + return -1; +} + + +inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) { + pReleaseSRWLockExclusive(&rwlock->srwlock_); +} + + +inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) { + if (uv_mutex_init(&rwlock->fallback_.read_mutex_)) + return -1; + + if (uv_mutex_init(&rwlock->fallback_.write_mutex_)) { + uv_mutex_destroy(&rwlock->fallback_.read_mutex_); + return -1; + } + + rwlock->fallback_.num_readers_ = 0; + + return 0; +} + + +inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) { + uv_mutex_destroy(&rwlock->fallback_.read_mutex_); + uv_mutex_destroy(&rwlock->fallback_.write_mutex_); +} + + +inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) { + uv_mutex_lock(&rwlock->fallback_.read_mutex_); + + if (++rwlock->fallback_.num_readers_ == 1) + uv_mutex_lock(&rwlock->fallback_.write_mutex_); + + uv_mutex_unlock(&rwlock->fallback_.read_mutex_); +} + + +inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) { + int ret; + + ret = -1; + + if (uv_mutex_trylock(&rwlock->fallback_.read_mutex_)) + goto out; + + if (rwlock->fallback_.num_readers_ == 0) + ret = uv_mutex_trylock(&rwlock->fallback_.write_mutex_); + else + ret = 0; + + if (ret == 0) + rwlock->fallback_.num_readers_++; + + uv_mutex_unlock(&rwlock->fallback_.read_mutex_); + +out: + return ret; +} + + +inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) { + uv_mutex_lock(&rwlock->fallback_.read_mutex_); + + if (--rwlock->fallback_.num_readers_ == 0) + uv_mutex_unlock(&rwlock->fallback_.write_mutex_); + + uv_mutex_unlock(&rwlock->fallback_.read_mutex_); +} + + +inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) { + uv_mutex_lock(&rwlock->fallback_.write_mutex_); +} + + +inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) { + return uv_mutex_trylock(&rwlock->fallback_.write_mutex_); +} + + +inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) { + uv_mutex_unlock(&rwlock->fallback_.write_mutex_); +} diff --git a/deps/uv/src/win/threads.c b/deps/uv/src/win/threads.c deleted file mode 100644 index 1fc6b73f8700..000000000000 --- a/deps/uv/src/win/threads.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * 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. - */ - -#include - -#include "uv.h" -#include "../uv-common.h" -#include "internal.h" - - -#ifdef _MSC_VER /* msvc */ -# define NOINLINE __declspec (noinline) -#else /* gcc */ -# define NOINLINE __attribute__ ((noinline)) -#endif - - -static NOINLINE void uv__once_inner(uv_once_t* guard, - void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - HANDLE* event_ptr; - - /* Fetch and align event_ptr */ - event_ptr = (HANDLE*) (((uintptr_t) &guard->event + (sizeof(HANDLE) - 1)) & - ~(sizeof(HANDLE) - 1)); - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - existing_event = InterlockedCompareExchangePointer(event_ptr, - created_event, - NULL); - - if (existing_event == NULL) { - /* We won the race */ - callback(); - - result = SetEvent(created_event); - assert(result); - guard->ran = 1; - - } else { - /* We lost the race. Destroy the event we created and wait for the */ - /* existing one to become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); -} diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index cc21361bc70c..ff6912d0e8e1 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -33,6 +33,13 @@ sNtSetInformationFile pNtSetInformationFile; sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; sCreateSymbolicLinkW pCreateSymbolicLinkW; +sInitializeSRWLock pInitializeSRWLock; +sAcquireSRWLockShared pAcquireSRWLockShared; +sAcquireSRWLockExclusive pAcquireSRWLockExclusive; +sTryAcquireSRWLockShared pTryAcquireSRWLockShared; +sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive; +sReleaseSRWLockShared pReleaseSRWLockShared; +sReleaseSRWLockExclusive pReleaseSRWLockExclusive; void uv_winapi_init() { @@ -86,4 +93,25 @@ void uv_winapi_init() { pCreateSymbolicLinkW = (sCreateSymbolicLinkW) GetProcAddress(kernel32_module, "CreateSymbolicLinkW"); + + pInitializeSRWLock = (sInitializeSRWLock) + GetProcAddress(kernel32_module, "InitializeSRWLock"); + + pAcquireSRWLockShared = (sAcquireSRWLockShared) + GetProcAddress(kernel32_module, "AcquireSRWLockShared"); + + pAcquireSRWLockExclusive = (sAcquireSRWLockExclusive) + GetProcAddress(kernel32_module, "AcquireSRWLockExclusive"); + + pTryAcquireSRWLockShared = (sTryAcquireSRWLockShared) + GetProcAddress(kernel32_module, "TryAcquireSRWLockShared"); + + pTryAcquireSRWLockExclusive = (sTryAcquireSRWLockExclusive) + GetProcAddress(kernel32_module, "TryAcquireSRWLockExclusive"); + + pReleaseSRWLockShared = (sReleaseSRWLockShared) + GetProcAddress(kernel32_module, "ReleaseSRWLockShared"); + + pReleaseSRWLockExclusive = (sReleaseSRWLockExclusive) + GetProcAddress(kernel32_module, "ReleaseSRWLockExclusive"); } diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index e0038f14aca5..8144939940c6 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4350,6 +4350,26 @@ typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW) LPCWSTR lpTargetFileName, DWORD dwFlags); +typedef VOID (WINAPI* sInitializeSRWLock) + (PSRWLOCK SRWLock); + +typedef VOID (WINAPI* sAcquireSRWLockShared) + (PSRWLOCK SRWLock); + +typedef VOID (WINAPI* sAcquireSRWLockExclusive) + (PSRWLOCK SRWLock); + +typedef BOOL (WINAPI* sTryAcquireSRWLockShared) + (PSRWLOCK SRWLock); + +typedef BOOL (WINAPI* sTryAcquireSRWLockExclusive) + (PSRWLOCK SRWLock); + +typedef VOID (WINAPI* sReleaseSRWLockShared) + (PSRWLOCK SRWLock); + +typedef VOID (WINAPI* sReleaseSRWLockExclusive) + (PSRWLOCK SRWLock); /* Ntapi function pointers */ extern sRtlNtStatusToDosError pRtlNtStatusToDosError; @@ -4362,5 +4382,12 @@ extern sNtSetInformationFile pNtSetInformationFile; extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; extern sCreateSymbolicLinkW pCreateSymbolicLinkW; +extern sInitializeSRWLock pInitializeSRWLock; +extern sAcquireSRWLockShared pAcquireSRWLockShared; +extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive; +extern sTryAcquireSRWLockShared pTryAcquireSRWLockShared; +extern sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive; +extern sReleaseSRWLockShared pReleaseSRWLockShared; +extern sReleaseSRWLockExclusive pReleaseSRWLockExclusive; #endif /* UV_WIN_WINAPI_H_ */ diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index c1f23fe996a9..59bdebc03204 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -267,4 +267,44 @@ TEST_IMPL(fs_event_no_callback_on_close) { r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL); return 0; -} \ No newline at end of file +} + + +static void fs_event_fail(uv_fs_event_t* handle, const char* filename, + int events, int status) { + ASSERT(0 && "should never be called"); +} + + +static void timer_cb(uv_timer_t* handle, int status) { + int r; + + ASSERT(status == 0); + + r = uv_fs_event_init(handle->loop, &fs_event, ".", fs_event_fail, 0); + ASSERT(r != -1); + + uv_close((uv_handle_t*)&fs_event, close_cb); + uv_close((uv_handle_t*)handle, close_cb); +} + + +TEST_IMPL(fs_event_immediate_close) { + uv_timer_t timer; + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 1, 0); + ASSERT(r == 0); + + uv_run(loop); + + ASSERT(close_cb_called == 2); + + return 0; +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 9051fdb35ce6..7240157badbf 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -110,10 +110,13 @@ TEST_DECLARE (fs_event_watch_dir) TEST_DECLARE (fs_event_watch_file) TEST_DECLARE (fs_event_watch_file_current_dir) TEST_DECLARE (fs_event_no_callback_on_close) +TEST_DECLARE (fs_event_immediate_close) TEST_DECLARE (fs_readdir_empty_dir) TEST_DECLARE (fs_readdir_file) TEST_DECLARE (fs_open_dir) TEST_DECLARE (threadpool_queue_work_simple) +TEST_DECLARE (thread_mutex) +TEST_DECLARE (thread_rwlock) #ifdef _WIN32 TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) TEST_DECLARE (argument_escaping) @@ -261,10 +264,13 @@ TASK_LIST_START TEST_ENTRY (fs_event_watch_file) TEST_ENTRY (fs_event_watch_file_current_dir) TEST_ENTRY (fs_event_no_callback_on_close) + TEST_ENTRY (fs_event_immediate_close) TEST_ENTRY (fs_readdir_empty_dir) TEST_ENTRY (fs_readdir_file) TEST_ENTRY (fs_open_dir) TEST_ENTRY (threadpool_queue_work_simple) + TEST_ENTRY (thread_mutex) + TEST_ENTRY (thread_rwlock) #if 0 /* These are for testing the test runner. */ diff --git a/deps/uv/test/test-mutexes.c b/deps/uv/test/test-mutexes.c new file mode 100644 index 000000000000..896f46bbed09 --- /dev/null +++ b/deps/uv/test/test-mutexes.c @@ -0,0 +1,63 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * 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. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +/* The mutex and rwlock tests are really poor. + * They're very basic sanity checks and nothing more. + * Apologies if that rhymes. + */ + +TEST_IMPL(thread_mutex) { + uv_mutex_t mutex; + int r; + + r = uv_mutex_init(&mutex); + ASSERT(r == 0); + + uv_mutex_lock(&mutex); + uv_mutex_unlock(&mutex); + uv_mutex_destroy(&mutex); + + return 0; +} + + +TEST_IMPL(thread_rwlock) { + uv_rwlock_t rwlock; + int r; + + r = uv_rwlock_init(&rwlock); + ASSERT(r == 0); + + uv_rwlock_rdlock(&rwlock); + uv_rwlock_rdunlock(&rwlock); + uv_rwlock_wrlock(&rwlock); + uv_rwlock_wrunlock(&rwlock); + uv_rwlock_destroy(&rwlock); + + return 0; +} diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 83129b5c956b..ae6523201597 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -139,13 +139,13 @@ 'src/win/internal.h', 'src/win/loop-watcher.c', 'src/win/pipe.c', + 'src/win/thread.c', 'src/win/process.c', 'src/win/req.c', 'src/win/stream.c', 'src/win/tcp.c', 'src/win/tty.c', 'src/win/threadpool.c', - 'src/win/threads.c', 'src/win/timer.c', 'src/win/udp.c', 'src/win/util.c', @@ -185,6 +185,7 @@ 'src/unix/cares.c', 'src/unix/dl.c', 'src/unix/error.c', + 'src/unix/thread.c', 'src/unix/process.c', 'src/unix/internal.h', 'src/unix/eio/ecb.h', @@ -311,6 +312,7 @@ 'test/test-tcp-write-to-half-open-connection.c', 'test/test-tcp-writealot.c', 'test/test-threadpool.c', + 'test/test-mutexes.c', 'test/test-timer-again.c', 'test/test-timer.c', 'test/test-tty.c', From a808ab4ac42cbcb3e8d37ff7c19da20cf610b388 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 14 Nov 2011 22:27:57 +0100 Subject: [PATCH 13/25] crypto: use the libuv rwlock API --- src/node_crypto.cc | 56 +++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 9d34304af05c..8fe5632130a8 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -83,67 +83,47 @@ static Persistent ext_key_usage_symbol; static Persistent secure_context_constructor; -#ifdef _WIN32 - -static HANDLE* locks; - - -static void crypto_lock_init(void) { - int i, n; - - n = CRYPTO_num_locks(); - locks = new HANDLE[n]; - - for (i = 0; i < n; i++) - if (!(locks[i] = CreateMutex(NULL, FALSE, NULL))) - abort(); -} - - -static void crypto_lock_cb(int mode, int n, const char* file, int line) { - if (mode & CRYPTO_LOCK) - WaitForSingleObject(locks[n], INFINITE); - else - ReleaseMutex(locks[n]); -} - - static unsigned long crypto_id_cb(void) { +#ifdef _WIN32 return (unsigned long) GetCurrentThreadId(); -} - #else /* !_WIN32 */ + return (unsigned long) pthread_self(); +#endif /* !_WIN32 */ +} -static pthread_rwlock_t* locks; +static uv_rwlock_t* locks; static void crypto_lock_init(void) { int i, n; n = CRYPTO_num_locks(); - locks = new pthread_rwlock_t[n]; + locks = new uv_rwlock_t[n]; for (i = 0; i < n; i++) - if (pthread_rwlock_init(locks + i, NULL)) + if (uv_rwlock_init(locks + i)) abort(); } static void crypto_lock_cb(int mode, int n, const char* file, int line) { + assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK)); + assert((mode & CRYPTO_READ) || (mode & CRYPTO_WRITE)); + if (mode & CRYPTO_LOCK) { - if (mode & CRYPTO_READ) pthread_rwlock_rdlock(locks + n); - if (mode & CRYPTO_WRITE) pthread_rwlock_wrlock(locks + n); + if (mode & CRYPTO_READ) + uv_rwlock_rdlock(locks + n); + else + uv_rwlock_wrlock(locks + n); } else { - pthread_rwlock_unlock(locks + n); + if (mode & CRYPTO_READ) + uv_rwlock_rdunlock(locks + n); + else + uv_rwlock_wrunlock(locks + n); } } -static unsigned long crypto_id_cb(void) { - return (unsigned long) pthread_self(); -} - -#endif /* !_WIN32 */ void SecureContext::Initialize(Handle target) { From 76bd523c2313257831f9c526ca72bc9f8043d1e5 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Fri, 18 Nov 2011 17:45:53 +0000 Subject: [PATCH 14/25] Fix crypto statics initialisation --- src/node_crypto.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 6ef9bbf047d5..ca32e050c9ea 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -151,7 +151,7 @@ static unsigned long crypto_id_cb(void) { void SecureContext::Initialize(Handle target) { HandleScope scope; - NODE_STATICS_NEW(node_crypto, CryptoStatics, statics); + CryptoStatics *statics = NODE_STATICS_GET(node_crypto, CryptoStatics); Local t = FunctionTemplate::New(SecureContext::New); statics->secure_context_constructor = Persistent::New(t); @@ -4266,7 +4266,7 @@ Handle RandomBytes(const Arguments& args) { void InitCrypto(Handle target) { HandleScope scope; - CryptoStatics *statics = NODE_STATICS_GET(node_crypto, CryptoStatics); + NODE_STATICS_NEW(node_crypto, CryptoStatics, statics); SSL_library_init(); OpenSSL_add_all_algorithms(); From f7939ebffa88a344503a877978bd17d60fe7c119 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Fri, 18 Nov 2011 17:45:53 +0000 Subject: [PATCH 15/25] Fix crypto statics initialisation --- src/node_crypto.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 6ef9bbf047d5..ca32e050c9ea 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -151,7 +151,7 @@ static unsigned long crypto_id_cb(void) { void SecureContext::Initialize(Handle target) { HandleScope scope; - NODE_STATICS_NEW(node_crypto, CryptoStatics, statics); + CryptoStatics *statics = NODE_STATICS_GET(node_crypto, CryptoStatics); Local t = FunctionTemplate::New(SecureContext::New); statics->secure_context_constructor = Persistent::New(t); @@ -4266,7 +4266,7 @@ Handle RandomBytes(const Arguments& args) { void InitCrypto(Handle target) { HandleScope scope; - CryptoStatics *statics = NODE_STATICS_GET(node_crypto, CryptoStatics); + NODE_STATICS_NEW(node_crypto, CryptoStatics, statics); SSL_library_init(); OpenSSL_add_all_algorithms(); From 585936157c796b0d446cdf68ce753c09b2799638 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 18 Nov 2011 12:03:35 -0800 Subject: [PATCH 16/25] Add missing rm --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2511dce1c0f5..c23b33878c1c 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ clean: distclean: -rm -rf out - -options.gypi + -rm options.gypi test: all python tools/test.py --mode=release simple message From 3f862cf1795fb69378489e24ea6f69cbe9897b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Ma=C5=82ecki?= Date: Tue, 25 Oct 2011 01:57:43 +0200 Subject: [PATCH 17/25] test: `stdin` isn't closed after `resume()` and `pause()` This works on `node v0.4.12`, but doesn't work on `node v0.6.2` --- test/simple/test-stdin-resume-pause.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/simple/test-stdin-resume-pause.js diff --git a/test/simple/test-stdin-resume-pause.js b/test/simple/test-stdin-resume-pause.js new file mode 100644 index 000000000000..2d2af2fc66d3 --- /dev/null +++ b/test/simple/test-stdin-resume-pause.js @@ -0,0 +1,23 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +process.stdin.resume(); +process.stdin.pause(); From b15dac501cfa9416ab72f4a4d4f9887b43169202 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Mon, 21 Nov 2011 13:29:47 +0000 Subject: [PATCH 18/25] Ensure process_wrap builds with or without NODE_FORK_ISOLATE --- src/process_wrap.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 4ded98f77c11..22019cf1a8ec 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -194,9 +194,9 @@ class ProcessWrap : public HandleWrap { Get(String::NewSymbol("windowsVerbatimArguments"))->IsTrue(); #endif + int r; #if defined(NODE_FORK_ISOLATE) // options.fork - int r; Local fork_v = js_options->Get(String::New("fork")); if (fork_v->IsBoolean() && fork_v->BooleanValue()) { Isolate *isolate = node::Isolate::New(); @@ -248,9 +248,12 @@ class ProcessWrap : public HandleWrap { int r = 0; if(!wrap->is_exited_) { +#if defined(NODE_FORK_ISOLATE) if(wrap->is_isolate_) { r = uv_thread_get_shared(&wrap->thread_, IsolateStop, &signal); - } else { + } else +#endif + { r = uv_process_kill(&wrap->process_, signal); } } From a9389ad80a521f741614d6427c5761cbd810f8b7 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 09:24:02 +0000 Subject: [PATCH 19/25] Add NODE_EXTERN for non-win32 platforms --- src/node.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/node.h b/src/node.h index 6bf2755790af..3b3a02f761ef 100644 --- a/src/node.h +++ b/src/node.h @@ -29,7 +29,11 @@ # define NODE_EXTERN __declspec(dllimport) # endif #else -# define NODE_EXTERN /* nothing */ +# ifndef BUILDING_NODE_EXTENSION +# define NODE_EXTERN __attribute__((visibility("default"))) +# else +# define NODE_EXTERN /* nothing */ +# endif #endif #ifdef BUILDING_NODE_EXTENSION @@ -123,14 +127,14 @@ class NodeOptions { class Isolate { public: - static Isolate* GetDefault(); + NODE_EXTERN static Isolate* GetDefault(); static Isolate* GetCurrent(); static uv_loop_t* GetCurrentLoop(); int Start(uv_thread_shared_t *options); - int Start(int argc, char *argv[]); - int Stop(int signum); - static Isolate* New(); - void Dispose(); + NODE_EXTERN int Start(int argc, char *argv[]); + NODE_EXTERN int Stop(int signum); + NODE_EXTERN static Isolate* New(); + NODE_EXTERN void Dispose(); v8::Local ErrnoException(int errorno, const char *syscall = NULL, const char *msg = "", @@ -243,9 +247,9 @@ class Isolate { }; -int Start(int argc, char *argv[]); -int Initialize(int argc, char *argv[]); -void Dispose(); +NODE_EXTERN int Start(int argc, char *argv[]); +NODE_EXTERN int Initialize(int argc, char *argv[]); +NODE_EXTERN void Dispose(); #define NODE_PSYMBOL(s) \ v8::Persistent::New(v8::String::NewSymbol(s)) From 0582c27f9f14c46c2a66d7c1f7acd3d6617bd645 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 09:25:46 +0000 Subject: [PATCH 20/25] Split node executable into executable and shared_library components --- node.gyp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/node.gyp b/node.gyp index e2413979124e..3db04c696854 100644 --- a/node.gyp +++ b/node.gyp @@ -50,8 +50,8 @@ 'targets': [ { - 'target_name': 'node', - 'type': 'executable', + 'target_name': 'libnode', + 'type': 'shared_library', 'dependencies': [ 'deps/http_parser/http_parser.gyp:http_parser', @@ -78,7 +78,6 @@ 'src/node_file.cc', 'src/node_http_parser.cc', 'src/node_javascript.cc', - 'src/node_main.cc', 'src/node_os.cc', 'src/node_script.cc', 'src/node_string.cc', @@ -203,6 +202,36 @@ }, }, + { + 'target_name': 'node', + 'type': 'executable', + + 'dependencies': [ + 'libnode', + ], + + 'include_dirs': [ + 'src', + 'deps/v8/include', + 'deps/uv/include', + ], + + 'sources': [ + 'src/node_main.cc', + # node.gyp is added to the project by default. + 'common.gypi', + ], + + 'defines': [ + 'ARCH="<(target_arch)"', + 'PLATFORM="<(OS)"', + '_LARGEFILE_SOURCE', + '_FILE_OFFSET_BITS=64', + ], + + 'conditions': [], + }, + { 'target_name': 'node_js2c', 'type': 'none', From 85fc959711b142009515deb6f6cc7c3827acc703 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 09:35:30 +0000 Subject: [PATCH 21/25] Use xcode as gyp target on darwin --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 53b63b186c8d..21724f607d68 100755 --- a/configure +++ b/configure @@ -246,4 +246,6 @@ json.dump(output, f, indent=2, skipkeys=True) f.write("\n") f.close() -subprocess.call(['tools/gyp_node','-f', 'make']) +gyp_target = 'xcode' if sys.platform == 'darwin' else 'make' + +subprocess.call(['tools/gyp_node','-f', gyp_target]) From 4dde692103732d78621863d4c9b2e2889e40a76f Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 10:18:19 +0000 Subject: [PATCH 22/25] Removed superfluous executable project --- node-exe/node-exe/main.cpp | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 node-exe/node-exe/main.cpp diff --git a/node-exe/node-exe/main.cpp b/node-exe/node-exe/main.cpp deleted file mode 100644 index b37e688d1cf4..000000000000 --- a/node-exe/node-exe/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void *run(void *arg); - -int main(int argc, char **argv) { - return node::Start(argc, argv); -} From 4bfd79943ee8b78ecec36bccd0fffda19f2252fd Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 10:18:34 +0000 Subject: [PATCH 23/25] Add isolate configure option --- configure | 6 ++++++ node.gyp | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/configure b/configure index 21724f607d68..80da127905c7 100755 --- a/configure +++ b/configure @@ -89,6 +89,11 @@ parser.add_option("--with-dtrace", dest="with_dtrace", help="Build with DTrace (experimental)") +parser.add_option("--isolate", + action="store_true", + dest="isolate", + help="Build with Isolate support") + # CHECKME does this still work with recent releases of V8? parser.add_option("--gdb", action="store_true", @@ -151,6 +156,7 @@ def configure_node(o): o['variables']['node_use_dtrace'] = 'true' if options.with_dtrace else 'false' o['variables']['host_arch'] = host_arch() o['variables']['target_arch'] = target_arch() + o['variables']['node_isolate'] = 'true' if options.isolate else 'false' # TODO move to node.gyp if sys.platform == 'sunos5': diff --git a/node.gyp b/node.gyp index 3db04c696854..0677cfefcde2 100644 --- a/node.gyp +++ b/node.gyp @@ -8,6 +8,7 @@ 'node_use_dtrace': 'false', 'node_use_openssl%': 'true', 'node_use_system_openssl%': 'false', + 'node_isolate': 'true', 'library_files': [ 'src/node.js', 'lib/_debugger.js', @@ -138,6 +139,13 @@ }, { 'defines': [ 'HAVE_OPENSSL=0' ] }], + + [ 'node_isolate=="true"', { + 'defines': [ + 'NODE_FORK_ISOLATE', + 'NODE_LIBRARY' + ], + }], [ 'node_use_dtrace=="true"', { 'sources': [ From c854869dfec657e6543663b9fa8ccd87eb8a3bb4 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 21:55:14 +0000 Subject: [PATCH 24/25] Define V8_SHARED so addons can link to this library --- common.gypi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common.gypi b/common.gypi index 0a4183b1c9fe..c133a2e096b4 100644 --- a/common.gypi +++ b/common.gypi @@ -114,6 +114,9 @@ 'cflags': [ '-Wall', '-pthread', ], 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ], 'ldflags': [ '-pthread', ], + 'defines': [ + 'V8_SHARED=1', + ], 'conditions': [ [ 'target_arch=="ia32"', { 'cflags': [ '-m32' ], @@ -155,6 +158,9 @@ '-Wno-unused-parameter', ], }, + 'defines': [ + 'V8_SHARED=1', + ], 'target_conditions': [ ['_type!="static_library"', { 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']}, From 4a9962139af1cd82e58d8e60a2a8f76c4ab44b33 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 29 Nov 2011 19:16:24 +0000 Subject: [PATCH 25/25] Export Isolate::GetCurrent() --- src/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node.h b/src/node.h index 3b3a02f761ef..f61d3ba329ee 100644 --- a/src/node.h +++ b/src/node.h @@ -128,7 +128,7 @@ class NodeOptions { class Isolate { public: NODE_EXTERN static Isolate* GetDefault(); - static Isolate* GetCurrent(); + NODE_EXTERN static Isolate* GetCurrent(); static uv_loop_t* GetCurrentLoop(); int Start(uv_thread_shared_t *options); NODE_EXTERN int Start(int argc, char *argv[]);