From 8404e7eb11845bd0a798b3dd1cad65809e45fd23 Mon Sep 17 00:00:00 2001 From: Stjepan Rajko Date: Fri, 19 Feb 2016 15:24:57 -0700 Subject: [PATCH 1/7] Initialize libssh2 to avoid its thread-unsafe init_if_needed --- generate/templates/templates/binding.gyp | 1 + generate/templates/templates/nodegit.cc | 3 +++ 2 files changed, 4 insertions(+) diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp index 81b7a8708..2b86abbe2 100644 --- a/generate/templates/templates/binding.gyp +++ b/generate/templates/templates/binding.gyp @@ -32,6 +32,7 @@ "include_dirs": [ "vendor/libv8-convert", + "vendor/libssh2/include", " #include +#include + #include "../include/lock_master.h" #include "../include/wrapper.h" #include "../include/promise_completion.h" @@ -40,6 +42,7 @@ void LockMasterGetDiagnostics(const FunctionCallbackInfo& info) { } extern "C" void init(Local target) { + libssh2_init(0); // Initialize libgit2. git_libgit2_init(); From e946dff6a45306780ca99baec368419027e35e83 Mon Sep 17 00:00:00 2001 From: Stjepan Rajko Date: Fri, 19 Feb 2016 15:29:23 -0700 Subject: [PATCH 2/7] Apply locking to openssl --- generate/templates/templates/binding.gyp | 1 + generate/templates/templates/nodegit.cc | 28 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp index 2b86abbe2..d82ec422d 100644 --- a/generate/templates/templates/binding.gyp +++ b/generate/templates/templates/binding.gyp @@ -33,6 +33,7 @@ "include_dirs": [ "vendor/libv8-convert", "vendor/libssh2/include", + "vendor/openssl/openssl/include", " #include +#include #include "../include/lock_master.h" #include "../include/wrapper.h" @@ -41,7 +42,34 @@ void LockMasterGetDiagnostics(const FunctionCallbackInfo& info) { info.GetReturnValue().Set(result); } +static uv_mutex_t *opensslMutexes; + +void OpenSSL_LockingCallback(int mode, int type, const char *, int) { + if (mode & CRYPTO_LOCK) { + uv_mutex_lock(&opensslMutexes[type]); + } else { + uv_mutex_unlock(&opensslMutexes[type]); + } +} + +unsigned long OpenSSL_IDCallback() { + return (unsigned long)uv_thread_self(); +} + +void OpenSSL_ThreadSetup() { + opensslMutexes=(uv_mutex_t *)malloc(CRYPTO_num_locks() * sizeof(uv_mutex_t)); + + for (int i=0; i target) { + // Initialize thread safety in openssl and libssh2 + OpenSSL_ThreadSetup(); libssh2_init(0); // Initialize libgit2. git_libgit2_init(); From 4c2af3363d8e00e3d9347ec64e90d5322838aed7 Mon Sep 17 00:00:00 2001 From: maxkorp Date: Fri, 19 Feb 2016 15:36:41 -0700 Subject: [PATCH 3/7] configure libssh2 against included openssl install --- lifecycleScripts/configureLibssh2.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lifecycleScripts/configureLibssh2.js b/lifecycleScripts/configureLibssh2.js index a7faefed1..efc3920c1 100644 --- a/lifecycleScripts/configureLibssh2.js +++ b/lifecycleScripts/configureLibssh2.js @@ -9,9 +9,19 @@ module.exports = function retrieveExternalDependencies() { return new Promise(function(resolve, reject) { console.info("[nodegit] Configuring libssh2."); - cp.execFile( - rooted("vendor/libssh2/") + "configure", - {cwd: rooted("vendor/libssh2/")}, + var opensslDir = rooted("vendor/openssl/openssl"); + var newEnv = {}; + Object.keys(process.env).forEach(function(key) { + newEnv[key] = process.env[key]; + }); + newEnv.CPPFLAGS = newEnv.CPPFLAGS || ""; + newEnv.CPPFLAGS += " -I" + path.join(opensslDir, "include"); + newEnv.CPPFLAGS = newEnv.CPPFLAGS.trim(); + + cp.exec( + rooted("vendor/libssh2/configure") + + " --with-libssl-prefix=" + opensslDir, + {cwd: rooted("vendor/libssh2/"), env: newEnv}, function(err, stdout, stderr) { if (err) { console.error(err); From b530b0f6b0eb8d228a47f10a1f1111088aace00a Mon Sep 17 00:00:00 2001 From: maxkorp Date: Fri, 19 Feb 2016 16:59:28 -0700 Subject: [PATCH 4/7] log output from node-gyp --- lifecycleScripts/install.js | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/lifecycleScripts/install.js b/lifecycleScripts/install.js index 29a23afc3..3f9614d0f 100644 --- a/lifecycleScripts/install.js +++ b/lifecycleScripts/install.js @@ -1,11 +1,11 @@ var promisify = require("promisify-node"); var path = require("path"); var fs = require("fs"); - +var cp = require("child_process"); var prepareForBuild = require("./prepareForBuild"); var exec = promisify(function(command, opts, callback) { - return require("child_process").exec(command, opts, callback); + return cp.exec(command, opts, callback); }); var fromRegistry; @@ -52,7 +52,9 @@ function installPrebuilt() { function pathForTool(name) { var toolPath = path.resolve(".", "node_modules", ".bin", name); - toolPath = "\"" + toolPath + "\""; + if (process.platform == "win32") { + toolPath += ".cmd"; + } return toolPath; } @@ -72,7 +74,8 @@ function build() { var opts = { cwd: ".", maxBuffer: Number.MAX_VALUE, - env: process.env + env: process.env, + stdio: "inherit" }; var builder = "node-gyp"; @@ -104,26 +107,27 @@ function build() { opts.env.HOME = path.join(home, ".nodegit-gyp"); - var cmd = [ - pathForTool(builder), + var cmd = pathForTool(builder); + var args = [ "rebuild", debug, target, distUrl ] .join(" ") - .trim(); - - return exec(cmd, opts) - .then(function() { - console.info("[nodegit] Compilation complete."); - console.info("[nodegit] Completed installation successfully."); - process.exitCode = 0; - }, - function(err, stderr) { - console.error(err); - console.error(stderr); + .trim() + .split(" "); + return new Promise(function(resolve, reject) { + var child = cp.spawn(cmd, args, opts); + child.on("close", function(code) { + console.log(code); + if (code) { + reject(code); process.exitCode = 13; } - ); + else { + resolve(); + } + }) + }); } From bf01c4647460ec640b7efdbf34517cf40c95c1ae Mon Sep 17 00:00:00 2001 From: Stjepan Rajko Date: Fri, 19 Feb 2016 17:54:50 -0700 Subject: [PATCH 5/7] Prevent libssh2 from redefining ssize_t --- generate/templates/templates/nodegit.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/generate/templates/templates/nodegit.cc b/generate/templates/templates/nodegit.cc index a9be400e1..db55952be 100644 --- a/generate/templates/templates/nodegit.cc +++ b/generate/templates/templates/nodegit.cc @@ -1,13 +1,18 @@ // This is a generated file, modify: generate/templates/nodegit.cc. #include + #include #include #include #include #include -#include #include +// we have to include first so it defines ssize_t +// and then node.h with _SSIZE_T_ defined to prevent it from redefining +// in a conflicting way on 32 bit windows +#define ssize_t ssize_t +#include #include "../include/lock_master.h" #include "../include/wrapper.h" From a2990943c9611d5fe5190e2de7c2eb6d1a4dadc7 Mon Sep 17 00:00:00 2001 From: maxkorp Date: Fri, 19 Feb 2016 17:47:09 -0700 Subject: [PATCH 6/7] fix linter --- lifecycleScripts/install.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lifecycleScripts/install.js b/lifecycleScripts/install.js index 3f9614d0f..56628d212 100644 --- a/lifecycleScripts/install.js +++ b/lifecycleScripts/install.js @@ -128,6 +128,6 @@ function build() { else { resolve(); } - }) + }); }); } From 6a16e677d50b04262ab6f777305dcbb23d402455 Mon Sep 17 00:00:00 2001 From: Stjepan Rajko Date: Mon, 22 Feb 2016 10:09:03 -0700 Subject: [PATCH 7/7] Initialize libssh2 from separate .cc file to avoid type redifinition conflicts This is better than silencing the redefinition in case the two definitions really need to be different. --- generate/templates/manual/include/init_ssh2.h | 6 ++++++ generate/templates/manual/src/init_ssh2.cc | 12 ++++++++++++ generate/templates/templates/binding.gyp | 1 + generate/templates/templates/nodegit.cc | 8 ++------ 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 generate/templates/manual/include/init_ssh2.h create mode 100644 generate/templates/manual/src/init_ssh2.cc diff --git a/generate/templates/manual/include/init_ssh2.h b/generate/templates/manual/include/init_ssh2.h new file mode 100644 index 000000000..d7f92b71a --- /dev/null +++ b/generate/templates/manual/include/init_ssh2.h @@ -0,0 +1,6 @@ +#ifndef INIT_SSH2 +#define INIT_SSH2 + +void init_ssh2(); + +#endif diff --git a/generate/templates/manual/src/init_ssh2.cc b/generate/templates/manual/src/init_ssh2.cc new file mode 100644 index 000000000..a8e2543c2 --- /dev/null +++ b/generate/templates/manual/src/init_ssh2.cc @@ -0,0 +1,12 @@ +// We are initializing libssh2 from a separate .cc file to avoid ssize_t +// redefinition conflicts caused by incliding both node.h and libssh2.h from +// the same file (e.g. nodegit.cc) +// +// The redefinition can also be avoided by #defines but that is risky in case +// the libraries depend on the different definitions. + +#include + +void init_ssh2() { + libssh2_init(0); +} diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp index d82ec422d..9c5649abb 100644 --- a/generate/templates/templates/binding.gyp +++ b/generate/templates/templates/binding.gyp @@ -16,6 +16,7 @@ "sources": [ "src/lock_master.cc", "src/nodegit.cc", + "src/init_ssh2.cc", "src/promise_completion.cc", "src/wrapper.cc", "src/functions/copy.cc", diff --git a/generate/templates/templates/nodegit.cc b/generate/templates/templates/nodegit.cc index db55952be..9c1eef135 100644 --- a/generate/templates/templates/nodegit.cc +++ b/generate/templates/templates/nodegit.cc @@ -8,12 +8,8 @@ #include #include -// we have to include first so it defines ssize_t -// and then node.h with _SSIZE_T_ defined to prevent it from redefining -// in a conflicting way on 32 bit windows -#define ssize_t ssize_t -#include +#include "../include/init_ssh2.h" #include "../include/lock_master.h" #include "../include/wrapper.h" #include "../include/promise_completion.h" @@ -75,7 +71,7 @@ void OpenSSL_ThreadSetup() { extern "C" void init(Local target) { // Initialize thread safety in openssl and libssh2 OpenSSL_ThreadSetup(); - libssh2_init(0); + init_ssh2(); // Initialize libgit2. git_libgit2_init();