Skip to content

Commit

Permalink
File locking fixed + test.
Browse files Browse the repository at this point in the history
  • Loading branch information
svladykin committed Aug 28, 2016
1 parent d05549d commit fcdf112
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 8 deletions.
27 changes: 19 additions & 8 deletions NnClassLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var File = java.io.File;
var Files = java.nio.file.Files;
var SCO = java.nio.file.StandardCopyOption;
var System = java.lang.System;
var Thread = java.lang.Thread;


var DEBUG = java.lang.Boolean.getBoolean('NnClassLoader.debug');
Expand Down Expand Up @@ -153,7 +154,7 @@ function bytesToHex(b) {
}

function withOkLock(fun) {
var ok = file(path(WORK_DIR, ".ok"));
var ok = file(path(WORK_DIR, ".ok-" + MAVEN_VERSION));

if (ok.exists())
return;
Expand All @@ -165,14 +166,25 @@ function withOkLock(fun) {
if (!workDir.exists())
throw "Failed to create directory: " + WORK_DIR;

var lock = file(path(WORK_DIR, ".lock"));
lock.createNewFile();
var lockFile = file(path(WORK_DIR, ".lock"));

var RandomAccessFile = java.io.RandomAccessFile;
var raf = new RandomAccessFile(lock, "rw");
var OverlappingFileLockException = java.nio.channels.OverlappingFileLockException;

var raf = new RandomAccessFile(lockFile, "rw");

try {
var lock = raf.getChannel().lock();
var lock = null;

do {
try {
lock = raf.getChannel().lock();
}
catch(e if e instanceof OverlappingFileLockException) {
Thread.sleep(50);
}
}
while (lock === null);

try {
if (ok.exists())
Expand All @@ -183,8 +195,7 @@ function withOkLock(fun) {
ok.createNewFile();
}
finally {
if (lock != null)
lock.release();
lock.release();
}
}
finally {
Expand Down Expand Up @@ -310,7 +321,7 @@ function debugPrintStream() {
}

function setContextClassLoader(ldr) {
var th = java.lang.Thread.currentThread();
var th = Thread.currentThread();

var oldLdr = th.getContextClassLoader();

Expand Down
107 changes: 107 additions & 0 deletions test/test-file-lock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
var Thread = java.lang.Thread;
var File = java.io.File;
var RandomAccessFile = java.io.RandomAccessFile;
var OverlappingFileLockException = java.nio.channels.OverlappingFileLockException;
var MapMode = java.nio.channels.FileChannel.MapMode;

var stateFile = new File("/tmp/state");

stateFile.createNewFile();

var stateRaf = new RandomAccessFile(stateFile, "rw");
var buf = stateRaf.getChannel().map(MapMode.READ_WRITE, 0, 24);

function put(idx, v) {
buf.putLong(idx * 8, v);
}

function get(idx) {
return buf.getLong(idx * 8);
}

if (stateRaf.length() === 0) {
put(0, 1);
put(1, 2);
put(2, 3);
}

var lockFile = new File('/tmp/my_tmp_lock');
lockFile.createNewFile();

function withLock(fun) {
var raf = new RandomAccessFile(lockFile, "rw");

try {
var lock = null;

do {
try {
lock = raf.getChannel().lock();
}
catch(e if e instanceof OverlappingFileLockException) {
Thread.sleep(1);
}
}
while (lock === null)

try {
fun();
}
finally {
lock.release();
}
}
finally {
raf.close();
}
}

var THREADS = 16;
var ITERATIONS = 100000;

var pool = java.util.concurrent.Executors.newFixedThreadPool(THREADS);

var futs = [];

for (var i = 0; i < THREADS; i++) {
futs.push(pool['submit(Runnable)'](function() {
for (var j = 0; j < ITERATIONS; j++)
withLock(function() {
var min = get(0);
var mid = get(1);
var max = get(2);

// java.lang.System.out.println(" --> " + max + " = " + mid + " + " + min);

// Fibonacci sequence check
if (max !== min + mid)
throw "Error: " + max + " != " + mid + " + " + min;

// Too big value - restart the sequence.
if (max == 23416728348467684) {
min = 1;
mid = 2;
max = 3;
}
else {
var oldMax = max;
var oldMid = mid;

max = max + mid;
mid = oldMax;
min = oldMid;
}

put(0, min);
put(1, mid);
put(2, max);

// buf.force();
})
}));
}

for each( var fut in futs)
fut.get();

print('OK');

0 comments on commit fcdf112

Please sign in to comment.