James Moger
2012-02-20 5e58f0a0ebfcf523fa1bd7cc74e3808140c75261
Workaround 1 sec resolution of File.lastModified on Linux (issue-55)

Shockingly, File.lastModified() does not always support millisecond
resolution on all platforms even if the underlying filesystem supports
it. Added a forceReload flag (in addition to last modified checks) to
ensure that user backends and configuration properties are properly
reloaded.
3 files modified
26 ■■■■ changed files
src/com/gitblit/ConfigUserService.java 8 ●●●● patch | view | raw | blame | history
src/com/gitblit/FileSettings.java 15 ●●●●● patch | view | raw | blame | history
src/com/gitblit/FileUserService.java 3 ●●●● patch | view | raw | blame | history
src/com/gitblit/ConfigUserService.java
@@ -83,6 +83,8 @@
    private volatile long lastModified;
    private volatile boolean forceReload;
    public ConfigUserService(File realmFile) {
        this.realmFile = realmFile;
    }
@@ -711,6 +713,9 @@
        }
        config.save();
        // manually set the forceReload flag because not all JVMs support real
        // millisecond resolution of lastModified. (issue-55)
        forceReload = true;
        // If the write is successful, delete the current file and rename
        // the temporary copy to the original filename.
@@ -735,7 +740,8 @@
     * Reads the realm file and rebuilds the in-memory lookup tables.
     */
    protected synchronized void read() {
        if (realmFile.exists() && (realmFile.lastModified() > lastModified)) {
        if (realmFile.exists() && (forceReload || (realmFile.lastModified() != lastModified))) {
            forceReload = false;
            lastModified = realmFile.lastModified();
            users.clear();
            cookies.clear();
src/com/gitblit/FileSettings.java
@@ -38,6 +38,8 @@
    private volatile long lastModified;
    private volatile boolean forceReload;
    public FileSettings(String file) {
        super(FileSettings.class);
        this.propertiesFile = new File(file);
@@ -49,7 +51,7 @@
     */
    @Override
    protected synchronized Properties read() {
        if (propertiesFile.exists() && (propertiesFile.lastModified() > lastModified)) {
        if (propertiesFile.exists() && (forceReload || (propertiesFile.lastModified() > lastModified))) {
            FileInputStream is = null;
            try {
                Properties props = new Properties();
@@ -60,6 +62,7 @@
                properties.clear();
                properties.putAll(props);
                lastModified = propertiesFile.lastModified();
                forceReload = false;
            } catch (FileNotFoundException f) {
                // IGNORE - won't happen because file.exists() check above
            } catch (Throwable t) {
@@ -88,6 +91,9 @@
            content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue());
        }
        FileUtils.writeContent(propertiesFile, content);
        // manually set the forceReload flag because not all JVMs support real
        // millisecond resolution of lastModified. (issue-55)
        forceReload = true;
        return true;
    }
    
@@ -102,6 +108,13 @@
        return lastModified;
    }
    /**
     * @return the state of the force reload flag
     */
    protected boolean forceReload() {
        return forceReload;
    }
    @Override
    public String toString() {
        return propertiesFile.getAbsolutePath();
src/com/gitblit/FileUserService.java
@@ -624,8 +624,9 @@
    @Override
    protected synchronized Properties read() {
        long lastRead = lastModified();
        boolean reload = forceReload();
        Properties allUsers = super.read();
        if (lastRead != lastModified()) {
        if (reload || (lastRead != lastModified())) {
            // reload hash cache
            cookies.clear();
            teams.clear();