aboutsummaryrefslogtreecommitdiff
path: root/smartpensyncer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'smartpensyncer.cc')
-rw-r--r--smartpensyncer.cc145
1 files changed, 115 insertions, 30 deletions
diff --git a/smartpensyncer.cc b/smartpensyncer.cc
index 551162e..cdf9bc6 100644
--- a/smartpensyncer.cc
+++ b/smartpensyncer.cc
@@ -21,6 +21,7 @@
#include <QtCore/QThread>
#include <QtCore/QDebug>
#include <quazip/quazipfile.h>
+#include <cstdio>
#include "paperreplay.h"
#include "notebookmodel.h"
#include "smartpensyncer.h"
@@ -28,33 +29,98 @@
#define BUFFER_SIZE 16 * 1024
namespace {
-static QDateTime getTimestampFileDate(const QString &path)
+class LockFile
{
- QFileInfo info(path);
- qDebug() << "Checking timestamp" << info.filePath();
+public:
+ LockFile(const QString &path);
+ ~LockFile();
+
+ bool lock();
+
+private:
+ QString _path;
+ FILE * _file;
+ bool _locked;
+};
+
+class TimestampFile
+{
+public:
+ TimestampFile(const QString &path);
+
+ QDateTime get();
+ void set();
+
+private:
+ QFileInfo _fi;
+};
+
+LockFile::LockFile(const QString &path)
+ : _path(path), _file(0), _locked(false)
+{
+
+}
+
+LockFile::~LockFile()
+{
+ if (_file) {
+ fclose(_file);
+ }
+ if (_locked) {
+ if (!QFile::remove(_path)) {
+ qWarning() << "Cannot remove lock file:" << _path;
+ }
+ }
+}
+
+bool LockFile::lock()
+{
+ Q_ASSERT(!_locked);
+
+ QFileInfo info(_path);
if (info.exists()) {
- return info.lastModified();
+ if (info.created().secsTo(QDateTime::currentDateTime()) > 10 * 60) {
+ if (QFile::remove(info.filePath())) {
+ qDebug() << "Removing stale lock file:" << info.absoluteFilePath();
+ }
+ } else {
+ return false;
+ }
+ }
+
+ _file = ::fopen(info.absoluteFilePath().toLocal8Bit().data(), "wx");
+ if (_file) {
+ _locked = true;
+ return true;
} else {
- return QDateTime();
+ return false;
}
}
-static void setTimestampFileDate(const QString &path)
+TimestampFile::TimestampFile(const QString &path)
+ : _fi(path)
{
- QFile f(path);
- if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- qWarning() << "Could not set timestamp file:" << path;
- return;
+}
+
+QDateTime TimestampFile::get()
+{
+ qDebug() << "Checking timestamp" << _fi.filePath();
+ if (_fi.exists()) {
+ return _fi.lastModified();
+ } else {
+ return QDateTime();
}
- f.close();
}
-void removeTimestampFile(const QString &path)
+void TimestampFile::set()
{
- QFile f(path);
- if (!f.remove()) {
- qWarning() << "Cannot remove timestamp file:" << path;
+ QFile f(_fi.filePath());
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ qWarning() << "Could not set timestamp file:" << _fi.absoluteFilePath();
+ return;
}
+ f.close();
+ _fi.refresh();
}
}
@@ -81,6 +147,11 @@ QString SmartpenSyncer::penName() const
return _penName;
}
+bool SmartpenSyncer::hasErrors() const
+{
+ return _errored;
+}
+
void SmartpenSyncer::abort()
{
_aborted = true;
@@ -123,10 +194,14 @@ void SmartpenSyncer::run()
bool SmartpenSyncer::syncPen()
{
- QDateTime lastSyncTime = getTimestampFileDate(_penDataDir.filePath(".lastsync"));
- QList<Smartpen::ChangeReport> changes = _pen->getChangeList(lastSyncTime);
+ LockFile lock(_penDataDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Pen is already being synchronized; delete this file if it is not:" << _penDataDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- setTimestampFileDate(_penDataDir.filePath(".sync.lck"));
+ TimestampFile lastSync(_penDataDir.filePath(".lastsync"));
+ QList<Smartpen::ChangeReport> changes = _pen->getChangeList(lastSync.get());
foreach(const Smartpen::ChangeReport &change, changes) {
if (!change.guid.isEmpty()) {
@@ -140,10 +215,14 @@ bool SmartpenSyncer::syncPen()
return false;
}
}
+
+ if (_aborted) {
+ qWarning() << "Aborting sync";
+ return false;
+ }
}
- setTimestampFileDate(_penDataDir.filePath(".lastsync"));
- removeTimestampFile(_penDataDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}
@@ -157,17 +236,20 @@ bool SmartpenSyncer::syncNotebook(const Smartpen::ChangeReport &change)
}
}
- setTimestampFileDate(notebookDir.filePath(".sync.lck"));
+ LockFile lock(notebookDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Notebook is already being synchronized; delete this file if it is not:" << notebookDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- QDateTime lastSyncTime = getTimestampFileDate(notebookDir.filePath(".lastsync"));
- QByteArray lspData = _pen->getLspData(change.guid, lastSyncTime);
+ TimestampFile lastSync(notebookDir.filePath(".lastsync"));
+ QByteArray lspData = _pen->getLspData(change.guid, lastSync.get());
if (!extractZip(lspData, notebookDir)) {
return false;
}
- setTimestampFileDate(notebookDir.filePath(".lastsync"));
- removeTimestampFile(notebookDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}
@@ -181,17 +263,20 @@ bool SmartpenSyncer::syncPaperReplay()
}
}
- setTimestampFileDate(replayDir.filePath(".sync.lck"));
+ LockFile lock(replayDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Paper replay is already being synchronized; delete this file if it is not:" << replayDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- QDateTime lastSyncTime = getTimestampFileDate(replayDir.filePath(".lastsync"));
- QByteArray replayData = _pen->getPaperReplay(lastSyncTime);
+ TimestampFile lastSync(replayDir.filePath(".lastsync"));
+ QByteArray replayData = _pen->getPaperReplay(lastSync.get());
if (!extractZip(replayData, replayDir)) {
return false;
}
- setTimestampFileDate(replayDir.filePath(".lastsync"));
- removeTimestampFile(replayDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}