mirror of
https://github.com/cjdelisle/cjdns
synced 2025-10-05 16:22:54 +02:00
Separation of concerns between builder and cjdns-specific build stuff
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
'use strict';
|
||||
var Fs = require('fs');
|
||||
var nThen = require('nthen');
|
||||
var Semaphore = require('../tools/lib/Semaphore');
|
||||
var Semaphore = require('saferphore');
|
||||
var Child = require('child_process');
|
||||
|
||||
var headerLines = [
|
||||
|
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
var Fs = require("fs");
|
||||
var Semaphore = require('../tools/lib/Semaphore');
|
||||
var Semaphore = require('saferphore');
|
||||
var nThen = require('nthen');
|
||||
|
||||
var sema = Semaphore.create(64);
|
||||
|
@@ -1,36 +0,0 @@
|
||||
'use strict';
|
||||
var nThen = require("nthen");
|
||||
var Fs = require("fs");
|
||||
|
||||
module.exports.check = function (builder, func, ldflags, callback) {
|
||||
|
||||
var file = builder.tmpFile();
|
||||
var outputFile = builder.tmpFile();
|
||||
|
||||
nThen(function (waitFor) {
|
||||
|
||||
Fs.writeFile(file, "int main() { " + func + "(); }", waitFor(function (err, ret) {
|
||||
if (err) {
|
||||
waitFor.abort();
|
||||
callback(err);
|
||||
}
|
||||
}));
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
var flags = [];
|
||||
flags.push.apply(flags, ["-x", "c", "-o", outputFile, file]);
|
||||
flags.push.apply(flags, ldflags);
|
||||
|
||||
builder.cc(flags, waitFor(function (ret, out, err) {
|
||||
if (ret && /undefined reference/.test(err)) {
|
||||
callback(undefined, false);
|
||||
} else if (ret) {
|
||||
callback(new Error(err));
|
||||
} else {
|
||||
callback(undefined, true);
|
||||
}
|
||||
}));
|
||||
|
||||
});
|
||||
};
|
@@ -19,136 +19,7 @@ const Fs = require('fs');
|
||||
const Spawn = require('child_process').spawn;
|
||||
const nThen = require('nthen');
|
||||
const Crypto = require('crypto');
|
||||
const Semaphore = require('../tools/lib/Semaphore');
|
||||
const GetVersion = require('./GetVersion');
|
||||
|
||||
/*
|
||||
* Why hello dear packager,
|
||||
*
|
||||
* I suppose you have found this place as you are trying to figure out how to work this into your
|
||||
* build system. You're probably faced with a decision between getting node.js into your build and
|
||||
* "fixing" this build process so it doesn't need such a silly thing. A 500 line script is certainly
|
||||
* not unapproachable, right?
|
||||
* The reason why I am speaking to you now is because I care about you. I want you to be happy
|
||||
* and live a carefree life, and because you are standing on the precipice of a cavern so dark and
|
||||
* deep that while you may well make it out alive, your personal pride and innocence almost
|
||||
* certainly will not. Imagine yourself after months of sleepless nights wallowing in the quicksand,
|
||||
* forever trying to slay the dragon which is always so close yet and so far away. Imagine the deep
|
||||
* hatred you will have for humanity, code, and the creator of this doomsday machine. I beg you to
|
||||
* turn back now while there is still hope. You need not die here, your life is important, and
|
||||
* whether you close this file now or not, in the end you will still end up including node.js in
|
||||
* your build.
|
||||
*
|
||||
* The Creator
|
||||
*/
|
||||
|
||||
// Since many of the compile operations are short, the best
|
||||
// performance seems to be when running 1.25x the number of jobs as
|
||||
// cpu cores. On BSD and iphone systems, os.cpus() is not reliable so
|
||||
// if it returns undefined let's just assume 1
|
||||
const cpus = Os.cpus(); // workaround, nodejs seems to be broken on openbsd (undefined result after second call)
|
||||
const PROCESSORS = Math.floor((typeof cpus === 'undefined' ? 1 : cpus.length) * 1.25);
|
||||
|
||||
const error = function (message) /*:Error*/ {
|
||||
try {
|
||||
throw new Error(message);
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
const throwIfErr = function(err) {
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
};
|
||||
|
||||
const expandArgs = function (args) {
|
||||
const out = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (typeof(args[i]) === 'object') {
|
||||
if (Array.isArray(args[i])) {
|
||||
out.push.apply(out, expandArgs(args[i]));
|
||||
} else {
|
||||
throw new Error("object in arguments [" + args.join() + "]");
|
||||
}
|
||||
} else {
|
||||
out.push(args[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const sema = Semaphore.create(PROCESSORS);
|
||||
const compiler = function (
|
||||
compilerPath /*:string*/,
|
||||
args /*:string[]*/,
|
||||
callback /*:(number, string, string)=>bool|void*/,
|
||||
content /*:string*/
|
||||
) {
|
||||
let stop = false;
|
||||
args = expandArgs(args);
|
||||
sema.take(function (returnAfter) {
|
||||
if (stop) {
|
||||
return returnAfter(function (ret) {
|
||||
callback(1, '', 'interrupted');
|
||||
});
|
||||
}
|
||||
if (process.env.VERBOSE) {
|
||||
console.log(compilerPath + ' ' + args.join(' '));
|
||||
}
|
||||
const gcc = Spawn(compilerPath, args);
|
||||
let err = '';
|
||||
let out = '';
|
||||
|
||||
gcc.stdout.on('data', function (dat) { out += dat.toString(); });
|
||||
gcc.stderr.on('data', function (dat) { err += dat.toString(); });
|
||||
gcc.on('close', returnAfter(function (ret) {
|
||||
if (callback(ret, out, err)) { stop = true; }
|
||||
}));
|
||||
|
||||
gcc.on('error', function (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.error('\x1b[1;31mError: ' + compilerPath + ' is required!\x1b[0m');
|
||||
} else {
|
||||
console.error(
|
||||
'\x1b[1;31mFail run ' + process.cwd() + ': ' + compilerPath + ' '
|
||||
+ args.join(' ') + '\x1b[0m'
|
||||
);
|
||||
console.error('Message:' + err);
|
||||
}
|
||||
|
||||
// handle the error safely
|
||||
console.log(args);
|
||||
});
|
||||
|
||||
if (content) {
|
||||
gcc.stdin.write(content, function (err) {
|
||||
if (err) { throw err; }
|
||||
gcc.stdin.end();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const cc = function (
|
||||
gcc /*:string*/,
|
||||
args /*:string[]*/,
|
||||
callback /*:(?Error, ?string)=>bool|void*/,
|
||||
content /*:string*/
|
||||
) {
|
||||
compiler(gcc, args, function (ret, out, err) {
|
||||
if (ret) {
|
||||
return callback(error("gcc " + args.map(String).join(' ') + "\n\n" + err));
|
||||
}
|
||||
|
||||
if (err !== '') {
|
||||
//process.stdout.write(err);
|
||||
}
|
||||
|
||||
return callback(undefined, out);
|
||||
}, content);
|
||||
};
|
||||
const Saferphore = require('saferphore');
|
||||
|
||||
/*::
|
||||
export type Builder_File_t = {|
|
||||
@@ -184,34 +55,26 @@ export type Builder_t = {|
|
||||
lintFiles: (Builder_Linter_t)=>void,
|
||||
config: Builder_Config_t,
|
||||
tmpFile: (?string)=>string,
|
||||
compilerType: () => Builder_Compiler_t,
|
||||
processors: number,
|
||||
compilerType: () => Builder_Compiler_t
|
||||
|};
|
||||
export type Builder_BaseConfig_t = {|
|
||||
systemName: string,
|
||||
crossCompiling: bool,
|
||||
gcc: string,
|
||||
tempDir: string,
|
||||
optimizeLevel: string,
|
||||
logLevel: string,
|
||||
buildDir?: string,
|
||||
systemName?: ?string,
|
||||
gcc?: ?string,
|
||||
buildDir?: ?string,
|
||||
|};
|
||||
export type Builder_Config_t = {
|
||||
systemName: string,
|
||||
crossCompiling: bool,
|
||||
gcc: string,
|
||||
buildDir: string,
|
||||
tempDir: string,
|
||||
optimizeLevel: string,
|
||||
logLevel: string,
|
||||
includeDirs: string[],
|
||||
cflags: string[],
|
||||
ldflags: string[],
|
||||
libs: string[],
|
||||
version: string,
|
||||
jobs: number,
|
||||
fileCflags: {[string]: string[]},
|
||||
} & {[string]:any};
|
||||
import type { Nthen_WaitFor_t } from 'nthen';
|
||||
import type { Saferphore_t } from 'saferphore';
|
||||
export type Builder_Stage_t = (Builder_t, Nthen_WaitFor_t)=>void;
|
||||
export type Builder_CompileJob_t = { cFile: string, outputFile: ?string };
|
||||
export type Builder_PreCtx_t = {
|
||||
@@ -228,12 +91,108 @@ export type Builder_PreCtx_t = {
|
||||
tests: Array<(Builder_TestRunnerCb_t)=>void>,
|
||||
toCompile: { [string]: Builder_File_t },
|
||||
config: Builder_Config_t,
|
||||
sema: Saferphore_t,
|
||||
};
|
||||
export type Builder_Ctx_t = Builder_PreCtx_t & {
|
||||
builder: Builder_t,
|
||||
state: Builder_State_t,
|
||||
};
|
||||
*/
|
||||
|
||||
const error = function (message) /*:Error*/ {
|
||||
try {
|
||||
throw new Error(message);
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
const expandArgs = function (args) {
|
||||
const out = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (typeof(args[i]) === 'object') {
|
||||
if (Array.isArray(args[i])) {
|
||||
out.push.apply(out, expandArgs(args[i]));
|
||||
} else {
|
||||
throw new Error("object in arguments [" + args.join() + "]");
|
||||
}
|
||||
} else {
|
||||
out.push(args[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const compiler = function (
|
||||
ctx /*:Builder_Ctx_t*/,
|
||||
args /*:string[]*/,
|
||||
callback /*:(number, string, string)=>bool|void*/,
|
||||
content /*:string*/
|
||||
) {
|
||||
let stop = false;
|
||||
args = expandArgs(args);
|
||||
ctx.sema.take(function (returnAfter) {
|
||||
if (stop) {
|
||||
return void returnAfter(function (ret) {
|
||||
callback(1, '', 'interrupted');
|
||||
});
|
||||
}
|
||||
if (process.env.VERBOSE) {
|
||||
console.log(ctx.config.gcc + ' ' + args.join(' '));
|
||||
}
|
||||
const gcc = Spawn(ctx.config.gcc, args);
|
||||
let err = '';
|
||||
let out = '';
|
||||
|
||||
gcc.stdout.on('data', function (dat) { out += dat.toString(); });
|
||||
gcc.stderr.on('data', function (dat) { err += dat.toString(); });
|
||||
gcc.on('close', returnAfter(function (ret) {
|
||||
if (callback(ret, out, err)) { stop = true; }
|
||||
}));
|
||||
|
||||
gcc.on('error', function (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.error('\x1b[1;31mError: ' + ctx.config.gcc + ' is required!\x1b[0m');
|
||||
} else {
|
||||
console.error(
|
||||
'\x1b[1;31mFail run ' + process.cwd() + ': ' + ctx.config.gcc + ' '
|
||||
+ args.join(' ') + '\x1b[0m'
|
||||
);
|
||||
console.error('Message:' + err);
|
||||
}
|
||||
|
||||
// handle the error safely
|
||||
console.log(args);
|
||||
});
|
||||
|
||||
if (content) {
|
||||
gcc.stdin.write(content, function (err) {
|
||||
if (err) { throw err; }
|
||||
gcc.stdin.end();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const cc = function (
|
||||
ctx /*:Builder_Ctx_t*/,
|
||||
args /*:string[]*/,
|
||||
callback /*:(?Error, ?string)=>bool|void*/,
|
||||
content /*:string*/
|
||||
) {
|
||||
compiler(ctx, args, function (ret, out, err) {
|
||||
if (ret) {
|
||||
return callback(error("gcc " + args.map(String).join(' ') + "\n\n" + err));
|
||||
}
|
||||
|
||||
if (err !== '') {
|
||||
//process.stdout.write(err);
|
||||
}
|
||||
|
||||
return callback(undefined, out);
|
||||
}, content);
|
||||
};
|
||||
|
||||
const getStatePrototype = function () /*:Builder_State_t*/ {
|
||||
return {
|
||||
rebuildIfChanges: [],
|
||||
@@ -253,7 +212,7 @@ const getStatePrototype = function () /*:Builder_State_t*/ {
|
||||
|
||||
const tmpFile = function (ctx /*:Builder_Ctx_t*/, name) {
|
||||
name = name || '';
|
||||
return ctx.config.tempDir + '/jsmake-' + name + Crypto.pseudoRandomBytes(10).toString('hex');
|
||||
return ctx.config.buildDir + '/tmp/' + name + Crypto.pseudoRandomBytes(10).toString('hex');
|
||||
};
|
||||
|
||||
const finalizeCtx = function (
|
||||
@@ -264,7 +223,7 @@ const finalizeCtx = function (
|
||||
ctx.state = state;
|
||||
ctx.builder = (Object.freeze({
|
||||
cc: function (args, callback) {
|
||||
compiler(ctx.builder.config.gcc, args, callback, '');
|
||||
compiler(ctx, args, callback, '');
|
||||
},
|
||||
|
||||
buildExecutable: function (cFile, outputFile) {
|
||||
@@ -293,8 +252,6 @@ const finalizeCtx = function (
|
||||
|
||||
compilerType: () => JSON.parse(JSON.stringify(ctx.state.compilerType)),
|
||||
|
||||
// Concurrency...
|
||||
processors: PROCESSORS
|
||||
}) /*:Builder_t*/);
|
||||
return ctx;
|
||||
};
|
||||
@@ -500,7 +457,7 @@ const preprocessFile = function (cFile, ctx, callback)
|
||||
|
||||
nThen((w) => {
|
||||
//debug("CPP");
|
||||
cc(ctx.config.gcc, ['-E', ...cflags, cFile], w(function (err, output) {
|
||||
cc(ctx, ['-E', ...cflags, cFile], w(function (err, output) {
|
||||
if (err) { throw err; }
|
||||
fileContent = output;
|
||||
return false;
|
||||
@@ -635,25 +592,12 @@ const makeTime = function () {
|
||||
|
||||
const link = function (cFile, callback, ctx /*:Builder_Ctx_t*/) {
|
||||
const state = ctx.state;
|
||||
let tempDir;
|
||||
|
||||
const temp = getTempExe(ctx, cFile);
|
||||
|
||||
nThen(function (waitFor) {
|
||||
|
||||
tempDir = tmpFile(ctx);
|
||||
Fs.mkdir(tempDir, {}, waitFor(function (err) {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
// TODO delete all other tmp files
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
nThen((waitFor) => {
|
||||
const linkOrder = getLinkOrder(cFile, state.cFiles);
|
||||
for (let i = 0; i < linkOrder.length; i++) {
|
||||
linkOrder[i] = getOFile(ctx, linkOrder[i]);
|
||||
}
|
||||
|
||||
const fileObj = state.cFiles[cFile];
|
||||
const ldArgs = []
|
||||
.concat(ctx.config.ldflags)
|
||||
@@ -662,37 +606,11 @@ const link = function (cFile, callback, ctx /*:Builder_Ctx_t*/) {
|
||||
.concat(linkOrder)
|
||||
.concat(ctx.config.libs);
|
||||
debug('\x1b[1;31mLinking C executable ' + cFile + '\x1b[0m');
|
||||
|
||||
cc(ctx.config.gcc, ldArgs, waitFor(function (err, ret) {
|
||||
cc(ctx, ldArgs, waitFor(function (err, ret) {
|
||||
if (err) { throw err; }
|
||||
return false;
|
||||
}), '');
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
Fs.readdir(tempDir, waitFor(function (err, files) {
|
||||
if (err) { throw err; }
|
||||
|
||||
files.forEach(function (file) {
|
||||
Fs.unlink(tempDir + '/' + file, waitFor(function (err) {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
});
|
||||
}));
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
Fs.rmdir(tempDir, waitFor(function (err) {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
});
|
||||
}).nThen((_) => callback());
|
||||
};
|
||||
|
||||
const compile = function (ctx, cFile, done) {
|
||||
@@ -700,7 +618,7 @@ const compile = function (ctx, cFile, done) {
|
||||
const file = ctx.state.cFiles[cFile];
|
||||
const oFile = getOFile(ctx, cFile);
|
||||
const iFile = getIFile(ctx, cFile);
|
||||
cc(ctx.config.gcc, ['-c', '-x', 'cpp-output', '-o', oFile, ...file.cflags, iFile], (err) => {
|
||||
cc(ctx, ['-c', '-x', 'cpp-output', '-o', oFile, ...file.cflags, iFile], (err) => {
|
||||
done(err);
|
||||
return typeof(err) !== 'undefined';
|
||||
}, '');
|
||||
@@ -753,7 +671,7 @@ const probeCompiler = function (ctx /*:Builder_Ctx_t*/, callback) {
|
||||
isGCC: false,
|
||||
version: ''
|
||||
};
|
||||
compiler(ctx.config.gcc, ['-v'], waitFor(function (ret, out, err) {
|
||||
compiler(ctx, ['-v'], waitFor(function (ret, out, err) {
|
||||
// TODO(cjd): afl-clang-fast errors when called with -v
|
||||
//if (ret !== 0) { throw new Error("Failed to probe compiler ret[" + ret + "]\n" + err); }
|
||||
if (/Apple LLVM version /.test(err)) {
|
||||
@@ -788,7 +706,7 @@ const probeCompiler = function (ctx /*:Builder_Ctx_t*/, callback) {
|
||||
compilerType.isGCC = true;
|
||||
compilerType.version = err.match(/gcc version ([^ ]+) /)[1];
|
||||
}
|
||||
console.log(JSON.stringify(compilerType));
|
||||
//console.log(JSON.stringify(compilerType));
|
||||
}), '');
|
||||
}).nThen(callback);
|
||||
};
|
||||
@@ -804,6 +722,34 @@ const deepFreeze = (obj) => {
|
||||
}
|
||||
};
|
||||
|
||||
const sweep = (path, done) => {
|
||||
let files = [];
|
||||
nThen((w) => {
|
||||
Fs.readdir(path, w((err, fls) => {
|
||||
if (err) { throw err; }
|
||||
files = fls;
|
||||
}));
|
||||
}).nThen((w) => {
|
||||
files.forEach((f) => {
|
||||
const file = path + '/' + f;
|
||||
Fs.stat(file, w((err, st) => {
|
||||
if (err) { throw err; }
|
||||
if (st.isDirectory()) {
|
||||
sweep(file, w(() => {
|
||||
Fs.rmdir(file, w((err) => {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
}));
|
||||
} else {
|
||||
Fs.unlink(file, w((err) => {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
}
|
||||
}));
|
||||
});
|
||||
}).nThen((_) => done());
|
||||
};
|
||||
|
||||
module.exports.configure = function (
|
||||
params /*:Builder_BaseConfig_t*/,
|
||||
configFunc /*:(Builder_t, Nthen_WaitFor_t)=>void*/
|
||||
@@ -813,11 +759,27 @@ module.exports.configure = function (
|
||||
const time = makeTime();
|
||||
time();
|
||||
|
||||
if (typeof(params.systemName) !== 'string') {
|
||||
throw new Error("system not specified");
|
||||
const systemName = params.systemName || process.platform;
|
||||
const buildDir = params.buildDir || 'build_' + systemName;
|
||||
|
||||
let gcc;
|
||||
if (params.gcc) {
|
||||
gcc = params.gcc;
|
||||
} else if (systemName === 'openbsd') {
|
||||
gcc = 'egcc';
|
||||
} else if (systemName === 'freebsd') {
|
||||
gcc = 'clang';
|
||||
} else {
|
||||
gcc = 'gcc';
|
||||
}
|
||||
|
||||
const buildDir = params.buildDir = params.buildDir || 'build_' + params.systemName;
|
||||
// Since many of the compile operations are short, the best
|
||||
// performance seems to be when running 1.25x the number of jobs as
|
||||
// cpu cores. On BSD and iphone systems, os.cpus() is not reliable so
|
||||
// if it returns undefined let's just assume 1
|
||||
// workaround, nodejs seems to be broken on openbsd (undefined result after second call)
|
||||
const cpus = Os.cpus();
|
||||
const jobs = Math.floor((typeof cpus === 'undefined' ? 1 : cpus.length) * 1.25);
|
||||
|
||||
const pctx /*:Builder_PreCtx_t*/ = {
|
||||
buildStage: (_x,_y)=>{},
|
||||
@@ -832,15 +794,12 @@ module.exports.configure = function (
|
||||
executables: [],
|
||||
tests: [],
|
||||
toCompile: {},
|
||||
sema: Saferphore.create(1),
|
||||
|
||||
config: {
|
||||
crossCompiling: params.crossCompiling,
|
||||
buildDir,
|
||||
gcc: params.gcc,
|
||||
logLevel: params.logLevel,
|
||||
optimizeLevel: params.optimizeLevel,
|
||||
systemName: params.systemName,
|
||||
tempDir: params.tempDir,
|
||||
gcc,
|
||||
systemName,
|
||||
|
||||
version: '',
|
||||
includeDirs: ['.'],
|
||||
@@ -848,6 +807,7 @@ module.exports.configure = function (
|
||||
ldflags: [],
|
||||
libs: [],
|
||||
fileCflags: {},
|
||||
jobs,
|
||||
},
|
||||
};
|
||||
let state = getStatePrototype();
|
||||
@@ -865,6 +825,18 @@ module.exports.configure = function (
|
||||
}));
|
||||
}));
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
Fs.exists(buildDir + '/tmp', waitFor(function (exists) {
|
||||
if (exists) {
|
||||
sweep(buildDir + '/tmp', waitFor());
|
||||
} else {
|
||||
Fs.mkdir(buildDir + '/tmp', {}, waitFor(function (err) {
|
||||
if (err) { throw err; }
|
||||
}));
|
||||
}
|
||||
}));
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
|
||||
// read out the state if it exists
|
||||
@@ -905,19 +877,21 @@ module.exports.configure = function (
|
||||
//if (!ctx.builder) { throw new Error(); }
|
||||
configFunc(ctx.builder, waitFor);
|
||||
|
||||
}).nThen(function (waitFor) {
|
||||
}).nThen(function (_) {
|
||||
ctx.sema = Saferphore.create(ctx.config.jobs);
|
||||
|
||||
if (!ctx.config.version) {
|
||||
GetVersion(waitFor(function(err, data) {
|
||||
if (err === null) {
|
||||
ctx.config.version = ('' + data).replace(/(\r\n|\n|\r)/gm, "");
|
||||
} else {
|
||||
ctx.config.version = 'unknown';
|
||||
}
|
||||
}));
|
||||
if (ctx.config.systemName !== systemName) {
|
||||
throw new Error("systemName cannot be changed in configure phase " +
|
||||
"it must be specified in the initial configuration " +
|
||||
`initial systemName = ${systemName}, changed to ${ctx.config.systemName}`);
|
||||
}
|
||||
|
||||
if (ctx.config.gcc !== gcc) {
|
||||
throw new Error("gcc cannot be changed in configure phase " +
|
||||
"it must be specified in the initial configuration " +
|
||||
`initial gcc = ${gcc}, changed to ${ctx.config.gcc}`);
|
||||
}
|
||||
|
||||
}).nThen(function (_) {
|
||||
deepFreeze(ctx.config);
|
||||
|
||||
debug("Configure " + time() + "ms");
|
||||
@@ -1070,7 +1044,6 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => {
|
||||
deepFreeze(state);
|
||||
}));
|
||||
}).nThen(function (w) {
|
||||
|
||||
Object.keys(ctx.toCompile).forEach((cFile) => {
|
||||
compile(ctx, cFile, w((err) => {
|
||||
if (err) {
|
||||
@@ -1105,7 +1078,7 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => {
|
||||
|
||||
debug("Checking codestyle");
|
||||
|
||||
const sema = Semaphore.create(64);
|
||||
const sema = Saferphore.create(64);
|
||||
|
||||
Object.keys(ctx.toCompile).forEach(function (cFile) {
|
||||
sema.take(waitFor(function (returnAfter) {
|
||||
@@ -1177,5 +1150,6 @@ const postConfigure = (ctx /*:Builder_Ctx_t*/, time) => {
|
||||
|
||||
ctx.completeStage(ctx.builder, waitFor);
|
||||
|
||||
sweep(ctx.config.buildDir + '/tmp', waitFor());
|
||||
});
|
||||
};
|
||||
|
@@ -19,40 +19,24 @@ var nThen = require('nthen');
|
||||
var Codestyle = require('./Codestyle');
|
||||
var Cp = require('./Cp');
|
||||
var Spawn = require('child_process').spawn;
|
||||
var Os = require('os');
|
||||
var FindPython = require('./FindPython');
|
||||
var CanCompile = require('./CanCompile');
|
||||
var Builder = require('./builder');
|
||||
var TestRunner = require('./TestRunner');
|
||||
const CjdnsTest = require('./CjdnsTest');
|
||||
const GetVersion = require('./GetVersion');
|
||||
|
||||
// ['linux','darwin','sunos','win32','freebsd','openbsd','netbsd']
|
||||
var SYSTEM = process.env['SYSTEM'] || process.platform;
|
||||
var GCC = process.env['CC'];
|
||||
var CFLAGS = process.env['CFLAGS'];
|
||||
var LDFLAGS = process.env['LDFLAGS'];
|
||||
|
||||
var NO_MARCH_FLAG = ['arm', 'ppc', 'ppc64'];
|
||||
|
||||
if (GCC) {
|
||||
// Already specified.
|
||||
} else if (SYSTEM === 'openbsd') {
|
||||
GCC = 'egcc';
|
||||
} else if (SYSTEM === 'freebsd') {
|
||||
GCC = 'clang';
|
||||
} else {
|
||||
GCC = 'gcc';
|
||||
}
|
||||
|
||||
Builder.configure({
|
||||
systemName: SYSTEM,
|
||||
crossCompiling: process.env['CROSS'] !== undefined,
|
||||
gcc: GCC,
|
||||
tempDir: process.env['CJDNS_BUILD_TMPDIR'] || '/tmp',
|
||||
optimizeLevel: '-O3',
|
||||
logLevel: process.env['Log_LEVEL'] || 'DEBUG'
|
||||
systemName: process.env['SYSTEM'] || process.platform,
|
||||
gcc: process.env['CC'],
|
||||
}, function (builder, waitFor) {
|
||||
|
||||
builder.config.crossCompiling = process.env['CROSS'] !== undefined;
|
||||
let optimizeLevel = '-O3';
|
||||
|
||||
builder.config.cflags.push(
|
||||
'-std=c99',
|
||||
'-Wall',
|
||||
@@ -62,11 +46,10 @@ Builder.configure({
|
||||
'-Wmissing-prototypes',
|
||||
'-pedantic',
|
||||
'-D', builder.config.systemName + '=1',
|
||||
'-D', 'CJD_PACKAGE_VERSION="' + builder.config.version + '"',
|
||||
'-Wno-unused-parameter',
|
||||
'-fomit-frame-pointer',
|
||||
|
||||
'-D', 'Log_' + builder.config.logLevel,
|
||||
'-D', 'Log_' + (process.env['Log_LEVEL'] || 'DEBUG'),
|
||||
|
||||
'-g',
|
||||
|
||||
@@ -164,18 +147,17 @@ Builder.configure({
|
||||
var cflags = CFLAGS.split(' ');
|
||||
cflags.forEach(function(flag) {
|
||||
if (/^\-O[^02s]$/.test(flag)) {
|
||||
console.log("Skipping " + flag + ", assuming " +
|
||||
builder.config.optimizeLevel + " instead.");
|
||||
console.log("Skipping " + flag + ", assuming " + optimizeLevel + " instead.");
|
||||
} else if (/^\-O[02s]$/.test(flag)) {
|
||||
builder.config.optimizeLevel = flag;
|
||||
optimizeLevel = flag;
|
||||
} else {
|
||||
[].push.apply(builder.config.cflags, cflags);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
builder.config.cflags.push(builder.config.optimizeLevel);
|
||||
if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
|
||||
builder.config.cflags.push(optimizeLevel);
|
||||
if (!/^\-O0$/.test(optimizeLevel)) {
|
||||
builder.config.cflags.push('-D_FORTIFY_SOURCE=2');
|
||||
}
|
||||
|
||||
@@ -189,25 +171,6 @@ Builder.configure({
|
||||
builder.config.cflags.push('-Dandroid=1');
|
||||
}
|
||||
|
||||
if (process.env.NO_LTO) {
|
||||
console.log("Link time optimization disabled");
|
||||
} else {
|
||||
CanCompile.check(builder,
|
||||
'int main() { return 0; }\n',
|
||||
[ builder.config.cflags, '-flto', '-x', 'c' ],
|
||||
waitFor(function (err, can) {
|
||||
if (can) {
|
||||
console.log("Compiler supports link time optimization");
|
||||
builder.config.ldflags.push(
|
||||
'-flto',
|
||||
builder.config.optimizeLevel
|
||||
);
|
||||
} else {
|
||||
console.log("Link time optimization not supported [" + err + "]");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
var uclibc = process.env['UCLIBC'] == '1';
|
||||
var libssp;
|
||||
switch (process.env['SSP_SUPPORT']) {
|
||||
@@ -257,6 +220,19 @@ Builder.configure({
|
||||
CjdnsTest.generate(builder, process.env['SUBNODE'] !== '', waitFor());
|
||||
}
|
||||
|
||||
nThen((w) => {
|
||||
if (builder.config.version) { return; }
|
||||
GetVersion(w(function(err, data) {
|
||||
if (!err) {
|
||||
builder.config.version = ('' + data).replace(/(\r\n|\n|\r)/gm, "");
|
||||
} else {
|
||||
builder.config.version = 'unknown';
|
||||
}
|
||||
}));
|
||||
}).nThen((w) => {
|
||||
builder.config.cflags.push('-D', 'CJD_PACKAGE_VERSION="' + builder.config.version + '"');
|
||||
}).nThen(waitFor());
|
||||
|
||||
var dependencyDir = builder.config.buildDir + '/dependencies';
|
||||
var libuvLib = dependencyDir + '/libuv/out/Release/libuv.a';
|
||||
if (['win32', 'netbsd'].indexOf(builder.config.systemName) >= 0) {//this might be needed for other BSDs
|
||||
@@ -295,9 +271,9 @@ Builder.configure({
|
||||
args.unshift('-fPIC');
|
||||
}
|
||||
|
||||
args.unshift(builder.config.optimizeLevel, '-fomit-frame-pointer');
|
||||
args.unshift(optimizeLevel, '-fomit-frame-pointer');
|
||||
|
||||
if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
|
||||
if (!/^\-O0$/.test(optimizeLevel)) {
|
||||
args.unshift('-D_FORTIFY_SOURCE=2');
|
||||
}
|
||||
|
||||
@@ -408,16 +384,16 @@ Builder.configure({
|
||||
});
|
||||
gyp.on('close', waitFor(function () {
|
||||
var args = [
|
||||
'-j', ''+builder.processors,
|
||||
'-j', ''+builder.config.jobs,
|
||||
'-C', 'out',
|
||||
'BUILDTYPE=Release',
|
||||
'CC=' + builder.config.gcc,
|
||||
'CXX=' + builder.config.gcc,
|
||||
'V=1'
|
||||
];
|
||||
var cflags = [builder.config.optimizeLevel, '-DNO_EMFILE_TRICK=1'];
|
||||
var cflags = [optimizeLevel, '-DNO_EMFILE_TRICK=1'];
|
||||
|
||||
if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
|
||||
if (!/^\-O0$/.test(optimizeLevel)) {
|
||||
cflags.push('-D_FORTIFY_SOURCE=2');
|
||||
}
|
||||
|
||||
|
12
node_modules/nthen/package.json
generated
vendored
12
node_modules/nthen/package.json
generated
vendored
@@ -1,4 +1,10 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"nthen@0.2.1",
|
||||
"/Users/user/wrk/cjdns"
|
||||
]
|
||||
],
|
||||
"_from": "nthen@0.2.1",
|
||||
"_id": "nthen@0.2.1",
|
||||
"_inBundle": false,
|
||||
@@ -16,12 +22,10 @@
|
||||
"fetchSpec": "0.2.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/nthen/-/nthen-0.2.1.tgz",
|
||||
"_shasum": "cf665cada4afd773f2443d77c5d77e79a965531f",
|
||||
"_spec": "nthen@0.2.1",
|
||||
"_spec": "0.2.1",
|
||||
"_where": "/Users/user/wrk/cjdns",
|
||||
"author": {
|
||||
"name": "Caleb James DeLisle"
|
||||
@@ -29,8 +33,6 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/cjdelisle/nthen/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Simple intuitive asynchronous control flow.",
|
||||
"devDependencies": {
|
||||
"flow-bin": "^0.106.2",
|
||||
|
7
node_modules/saferphore/.flowconfig
generated
vendored
Normal file
7
node_modules/saferphore/.flowconfig
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
[ignore]
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
|
||||
[options]
|
1
node_modules/saferphore/.jshintignore
generated
vendored
Normal file
1
node_modules/saferphore/.jshintignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
16
node_modules/saferphore/.jshintrc
generated
vendored
Normal file
16
node_modules/saferphore/.jshintrc
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"laxcomma": true,
|
||||
"laxbreak": true,
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"sub": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"iterator": true,
|
||||
"latedef": true,
|
||||
"nocomma": true,
|
||||
"notypeof": true,
|
||||
"shadow": false,
|
||||
"undef": true,
|
||||
"unused": false
|
||||
}
|
12
node_modules/saferphore/.travis.yml
generated
vendored
Normal file
12
node_modules/saferphore/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- '6'
|
||||
- '5'
|
||||
- '4'
|
||||
- '0.12'
|
||||
|
||||
script:
|
||||
- npm run-script test
|
||||
- npm run-script lint
|
||||
- npm run-script flow
|
50
node_modules/saferphore/index.js
generated
vendored
Normal file
50
node_modules/saferphore/index.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*@flow*/
|
||||
/*::
|
||||
export type Saferphore_ReturnAfter_t = ((...any)=>void)=>(...any)=>void;
|
||||
export type Saferphore_t = {
|
||||
take: ((Saferphore_ReturnAfter_t)=>void)=>void,
|
||||
};
|
||||
*/
|
||||
;(function () {
|
||||
"use strict";
|
||||
var create = function (resourceCount /*:number*/) /*:Saferphore_t*/ {
|
||||
var queue = [];
|
||||
var check;
|
||||
var mkRa = function () /*:Saferphore_ReturnAfter_t*/ {
|
||||
var outerCalled = 0;
|
||||
return function (func) {
|
||||
if (outerCalled++) { throw new Error("returnAfter() called multiple times"); }
|
||||
var called = 0;
|
||||
return function () {
|
||||
if (called++) {
|
||||
throw new Error("returnAfter wrapped callback called multiple times");
|
||||
}
|
||||
if (func) { func.apply(null, arguments); }
|
||||
resourceCount++;
|
||||
check();
|
||||
};
|
||||
};
|
||||
};
|
||||
check = function () {
|
||||
if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); }
|
||||
if (resourceCount === 0 || queue.length === 0) { return; }
|
||||
resourceCount--;
|
||||
queue.shift()(mkRa());
|
||||
};
|
||||
return {
|
||||
take: function (func) {
|
||||
queue.push(func);
|
||||
check();
|
||||
}
|
||||
};
|
||||
};
|
||||
if (typeof(window) === 'object') {
|
||||
if (window.define && window.define.amd) {
|
||||
window.define({ create: create });
|
||||
} else {
|
||||
window.Saferphore = { create: create };
|
||||
}
|
||||
} else if (typeof(module) === 'object' && module.exports) {
|
||||
module.exports.create = create;
|
||||
}
|
||||
}());
|
51
node_modules/saferphore/package.json
generated
vendored
Normal file
51
node_modules/saferphore/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"saferphore@0.0.2",
|
||||
"/Users/user/wrk/cjdns"
|
||||
]
|
||||
],
|
||||
"_from": "saferphore@0.0.2",
|
||||
"_id": "saferphore@0.0.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-gjdCGXxrSKi1oSWJH0vx99WtB2wkjbXPQf6ALHEskLo0e4Vgd57txhracaeLlPt2r4rUiJBe+thriuxS85q7JA==",
|
||||
"_location": "/saferphore",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "saferphore@0.0.2",
|
||||
"name": "saferphore",
|
||||
"escapedName": "saferphore",
|
||||
"rawSpec": "0.0.2",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "0.0.2"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.2.tgz",
|
||||
"_spec": "0.0.2",
|
||||
"_where": "/Users/user/wrk/cjdns",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cjdelisle/saferphore/issues"
|
||||
},
|
||||
"description": "Node Semaphore which has protection against double-returning",
|
||||
"devDependencies": {
|
||||
"flow-bin": "^0.115.0",
|
||||
"jshint": "~2.9.1"
|
||||
},
|
||||
"homepage": "https://github.com/cjdelisle/saferphore#readme",
|
||||
"license": "MIT",
|
||||
"name": "saferphore",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cjdelisle/saferphore.git"
|
||||
},
|
||||
"scripts": {
|
||||
"flow": "flow",
|
||||
"lint": "jshint --verbose --config .jshintrc --exclude-path .jshintignore .",
|
||||
"test": "node test"
|
||||
},
|
||||
"version": "0.0.2"
|
||||
}
|
30
node_modules/saferphore/readme.md
generated
vendored
Normal file
30
node_modules/saferphore/readme.md
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Saferphore - Node semaphore with protection against double-returning
|
||||
|
||||
# node
|
||||
npm install --save saferphore
|
||||
|
||||
# Browser
|
||||
bower install --save saferphore
|
||||
|
||||
|
||||
```javascript
|
||||
const Saferphore = require('saferphore');
|
||||
|
||||
var sem = Saferphore.create(4);
|
||||
for (var i = 0; i < 10000; i++) {
|
||||
sem.take(function (returnAfter) {
|
||||
Fs.writeFile('file_' + i, 'hi', returnAfter(function (err) {
|
||||
if (err) { throw err; }
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
You can only return what you take, if you try to call returnAfter() twice then it will throw a
|
||||
clear error instead of creating a leaky semaphore.
|
||||
|
||||
```javascript
|
||||
sem.take(function (returnAfter) {
|
||||
stream.on('data', returnAfter(processData)); // BZZZZZZZT error when it's called more than once
|
||||
});
|
||||
```
|
54
node_modules/saferphore/test.js
generated
vendored
Normal file
54
node_modules/saferphore/test.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
var Saferphore = require('./index');
|
||||
var assert = function (x) { if (!x) { throw new Error(); } };
|
||||
|
||||
var basicTest = function () {
|
||||
var sem = Saferphore.create(4);
|
||||
var out = [];
|
||||
(new Array(10)).join().split(',').forEach(function (x,y) {
|
||||
sem.take(function (returnAfter) {
|
||||
out.push(y);
|
||||
setTimeout(returnAfter(function () {
|
||||
if (out.length === 10) {
|
||||
if (out.join() !== "0,1,2,3,4,5,6,7,8,9") { throw new Error(); }
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
if (out.join() !== "0,1,2,3") {
|
||||
throw new Error(out.join());
|
||||
}
|
||||
};
|
||||
|
||||
var doubleCallTest = function () {
|
||||
var sem = Saferphore.create(4);
|
||||
var catcher = setTimeout(function () {
|
||||
throw new Error();
|
||||
}, 1000);
|
||||
sem.take(function (returnAfter) {
|
||||
setTimeout(returnAfter(function () {
|
||||
setTimeout(function () {
|
||||
clearTimeout(catcher);
|
||||
try { returnAfter()(); } catch (e) { return; }
|
||||
throw new Error();
|
||||
});
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
var doubleCallbackTest = function () {
|
||||
var sem = Saferphore.create(4);
|
||||
var catcher = setTimeout(function () {
|
||||
throw new Error();
|
||||
}, 1000);
|
||||
sem.take(function (returnAfter) {
|
||||
var wrapped = returnAfter();
|
||||
wrapped();
|
||||
try { wrapped(); } catch (e) { clearTimeout(catcher); return; }
|
||||
throw new Error();
|
||||
});
|
||||
};
|
||||
|
||||
basicTest();
|
||||
doubleCallTest();
|
||||
doubleCallbackTest();
|
225
package-lock.json
generated
225
package-lock.json
generated
@@ -1,233 +1,18 @@
|
||||
{
|
||||
"name": "cjdns",
|
||||
"version": "0.17.2",
|
||||
"version": "0.17.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
|
||||
"integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
|
||||
"requires": {
|
||||
"exit": "0.1.2",
|
||||
"glob": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"console-browserify": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
|
||||
"integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
|
||||
"requires": {
|
||||
"date-now": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"date-now": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
|
||||
"integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz",
|
||||
"integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA=="
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
|
||||
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
|
||||
"integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
|
||||
"integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw="
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
||||
"integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
|
||||
"requires": {
|
||||
"domelementtype": "1",
|
||||
"domhandler": "2.3",
|
||||
"domutils": "1.5",
|
||||
"entities": "1.0",
|
||||
"readable-stream": "1.1"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"jshint": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/jshint/-/jshint-2.12.0.tgz",
|
||||
"integrity": "sha512-TwuuaUDmra0JMkuqvqy+WGo2xGHSNjv1BA1nTIgtH2K5z1jHuAEeAgp7laaR+hLRmajRjcrM71+vByBDanCyYA==",
|
||||
"requires": {
|
||||
"cli": "~1.0.0",
|
||||
"console-browserify": "1.1.x",
|
||||
"exit": "0.1.x",
|
||||
"htmlparser2": "3.8.x",
|
||||
"lodash": "~4.17.19",
|
||||
"minimatch": "~3.0.2",
|
||||
"shelljs": "0.3.x",
|
||||
"strip-json-comments": "1.0.x"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"nthen": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/nthen/-/nthen-0.2.1.tgz",
|
||||
"integrity": "sha512-QW3p6gxOaHHLFM+2HcytugGUiji4pNpLkNAtPQi2gX2+hSmndnNSDYbDSUdIEy7vGJ+LkocZ3EvgwxeKfToZGg=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"shelljs": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
|
||||
"integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
|
||||
"integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"saferphore": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.2.tgz",
|
||||
"integrity": "sha512-gjdCGXxrSKi1oSWJH0vx99WtB2wkjbXPQf6ALHEskLo0e4Vgd57txhracaeLlPt2r4rUiJBe+thriuxS85q7JA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "cjdns",
|
||||
"version": "0.17.2",
|
||||
"version": "0.17.3",
|
||||
"dependencies": {
|
||||
"jshint": "^2.12.0",
|
||||
"nthen": "^0.2.1"
|
||||
"nthen": "^0.2.1",
|
||||
"saferphore": "0.0.2"
|
||||
}
|
||||
}
|
||||
|
@@ -1,24 +1,51 @@
|
||||
module.exports.create = function (resourceCount) {
|
||||
var queue = [];
|
||||
var returnAfter = function (func) {
|
||||
var called = 0;
|
||||
return function () {
|
||||
if (called++) { throw new Error("Function called multiple times"); }
|
||||
if (func) { func.apply(null, arguments); }
|
||||
resourceCount++;
|
||||
check();
|
||||
/*@flow*/
|
||||
/*::
|
||||
export type Saferphore_ReturnAfter_t = ((...any)=>void)=>(...any)=>void;
|
||||
export type Saferphore_t = {
|
||||
take: ((Saferphore_ReturnAfter_t)=>void)=>void,
|
||||
};
|
||||
*/
|
||||
;(function () {
|
||||
"use strict";
|
||||
var create = function (resourceCount /*:number*/) /*:Saferphore_t*/ {
|
||||
var queue = [];
|
||||
var check;
|
||||
var mkRa = function () /*:Saferphore_ReturnAfter_t*/ {
|
||||
var outerCalled = 0;
|
||||
return function (func) {
|
||||
if (outerCalled++) { throw new Error("returnAfter() called multiple times"); }
|
||||
var called = 0;
|
||||
return function () {
|
||||
if (called++) {
|
||||
throw new Error("returnAfter wrapped callback called multiple times");
|
||||
}
|
||||
if (func) { func.apply(null, arguments); }
|
||||
resourceCount++;
|
||||
check();
|
||||
};
|
||||
};
|
||||
};
|
||||
check = function () {
|
||||
if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); }
|
||||
if (resourceCount === 0 || queue.length === 0) { return; }
|
||||
resourceCount--;
|
||||
queue.shift()(mkRa());
|
||||
};
|
||||
return {
|
||||
take: function (func) {
|
||||
queue.push(func);
|
||||
check();
|
||||
}
|
||||
};
|
||||
};
|
||||
var check = function () {
|
||||
if (resourceCount < 0) { throw new Error("(resourceCount < 0) should never happen"); }
|
||||
if (resourceCount === 0 || queue.length === 0) { return; }
|
||||
resourceCount--;
|
||||
queue.shift()(returnAfter);
|
||||
};
|
||||
return {
|
||||
take: function (func) {
|
||||
queue.push(func);
|
||||
check();
|
||||
if (typeof(window) === 'object') {
|
||||
if (window.define && window.define.amd) {
|
||||
window.define({ create: create });
|
||||
} else {
|
||||
window.Saferphore = { create: create };
|
||||
}
|
||||
};
|
||||
};
|
||||
} else if (typeof(module) === 'object' && module.exports) {
|
||||
module.exports.create = create;
|
||||
}
|
||||
}());
|
||||
|
@@ -18,7 +18,7 @@ var Bencode = require('./bencode');
|
||||
var Crypto = require('crypto');
|
||||
var Fs = require('fs');
|
||||
var nThen = require('nthen');
|
||||
var Semaphore = require('../Semaphore.js');
|
||||
var Semaphore = require('saferphore');
|
||||
|
||||
var TIMEOUT_MILLISECONDS = 10000;
|
||||
|
||||
|
Reference in New Issue
Block a user