Lock config file

Fixes #19
This commit is contained in:
AsamK 2016-07-07 01:06:08 +02:00
parent d5797ebb69
commit c5ac72a9a5

View file

@ -18,6 +18,8 @@ package org.asamk.signal;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -56,6 +58,9 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
@ -79,6 +84,9 @@ class Manager implements Signal {
private final String attachmentsPath; private final String attachmentsPath;
private final String avatarsPath; private final String avatarsPath;
private FileChannel fileChannel;
private FileLock lock;
private final ObjectMapper jsonProcessot = new ObjectMapper(); private final ObjectMapper jsonProcessot = new ObjectMapper();
private String username; private String username;
private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID;
@ -105,6 +113,8 @@ class Manager implements Signal {
jsonProcessot.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print, you can disable it. jsonProcessot.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print, you can disable it.
jsonProcessot.enable(SerializationFeature.WRITE_NULL_MAP_VALUES); jsonProcessot.enable(SerializationFeature.WRITE_NULL_MAP_VALUES);
jsonProcessot.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); jsonProcessot.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
jsonProcessot.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
jsonProcessot.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
} }
public String getUsername() { public String getUsername() {
@ -141,8 +151,22 @@ class Manager implements Signal {
return node; return node;
} }
private void openFileChannel() throws IOException {
if (fileChannel != null)
return;
fileChannel = new RandomAccessFile(new File(getFileName()), "rw").getChannel();
lock = fileChannel.tryLock();
if (lock == null) {
System.err.println("Config file is in use by another instance, waiting…");
lock = fileChannel.lock();
System.err.println("Config file lock acquired.");
}
}
public void load() throws IOException, InvalidKeyException { public void load() throws IOException, InvalidKeyException {
JsonNode rootNode = jsonProcessot.readTree(new File(getFileName())); openFileChannel();
JsonNode rootNode = jsonProcessot.readTree(Channels.newInputStream(fileChannel));
JsonNode node = rootNode.get("deviceId"); JsonNode node = rootNode.get("deviceId");
if (node != null) { if (node != null) {
@ -227,7 +251,11 @@ class Manager implements Signal {
.putPOJO("contactStore", contactStore) .putPOJO("contactStore", contactStore)
; ;
try { try {
jsonProcessot.writeValue(new File(getFileName()), rootNode); openFileChannel();
fileChannel.position(0);
jsonProcessot.writeValue(Channels.newOutputStream(fileChannel), rootNode);
fileChannel.truncate(fileChannel.position());
fileChannel.force(false);
} catch (Exception e) { } catch (Exception e) {
System.err.println(String.format("Error saving file: %s", e.getMessage())); System.err.println(String.format("Error saving file: %s", e.getMessage()));
} }