Introduced application-wide close lock.
This commit is contained in:
parent
175e657af7
commit
80e8fcd0f6
9 changed files with 73 additions and 7 deletions
|
@ -1,6 +1,11 @@
|
||||||
<body>
|
<body>
|
||||||
[2.0.0]
|
[2.0.0]
|
||||||
<ul>
|
<ul>
|
||||||
<li>Initial second generation release.</li>
|
<li>[@] Initial second generation release.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
[+] added <br/>
|
||||||
|
[#] fixed <br/>
|
||||||
|
[~] changed <br/>
|
||||||
|
[@] other action <br/>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#define NO_PARENT_CATEGORY -1
|
#define NO_PARENT_CATEGORY -1
|
||||||
#define TRAY_ICON_BUBBLE_TIMEOUT 15000
|
#define TRAY_ICON_BUBBLE_TIMEOUT 15000
|
||||||
#define KEY_MESSAGES_VIEW "messages_view_column_"
|
#define KEY_MESSAGES_VIEW "messages_view_column_"
|
||||||
|
#define CLOSE_LOCK_TIMEOUT 2000
|
||||||
|
|
||||||
#define APP_DB_INIT_FILE "db_init.sql"
|
#define APP_DB_INIT_FILE "db_init.sql"
|
||||||
#define APP_DB_INIT_SPLIT "-- !\n"
|
#define APP_DB_INIT_SPLIT "-- !\n"
|
||||||
|
|
|
@ -56,15 +56,15 @@ void MessagesModel::setupFonts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<int> MessagesModel::currentFeeds() const {
|
QList<int> MessagesModel::currentFeeds() const {
|
||||||
return m_currentFeeds;
|
return m_currentFeeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MessagesModel::loadMessages(const QList<int> feed_ids) {
|
void MessagesModel::loadMessages(const QList<int> feed_ids) {
|
||||||
// Conversion of parameter.
|
// Conversion of parameter.
|
||||||
m_currentFeeds = feed_ids;
|
m_currentFeeds = feed_ids;
|
||||||
|
|
||||||
setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")));
|
setFilter(QString("feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")));
|
||||||
select();
|
select();
|
||||||
fetchAll();
|
fetchAll();
|
||||||
}
|
}
|
||||||
|
@ -428,7 +428,7 @@ bool MessagesModel::setAllMessagesDeleted(int deleted) {
|
||||||
|
|
||||||
QSqlQuery query_delete_msg(db_handle);
|
QSqlQuery query_delete_msg(db_handle);
|
||||||
if (!query_delete_msg.prepare(QString("UPDATE messages SET deleted = :deleted "
|
if (!query_delete_msg.prepare(QString("UPDATE messages SET deleted = :deleted "
|
||||||
"WHERE feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")))) {
|
"WHERE feed IN (%1) AND deleted = 0").arg(textualFeeds().join(", ")))) {
|
||||||
qWarning("Query preparation failed for message deletion.");
|
qWarning("Query preparation failed for message deletion.");
|
||||||
|
|
||||||
db_handle.rollback();
|
db_handle.rollback();
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
QPointer<SystemFactory> SystemFactory::s_instance;
|
QPointer<SystemFactory> SystemFactory::s_instance;
|
||||||
|
|
||||||
SystemFactory::SystemFactory(QObject *parent) : QObject(parent) {
|
SystemFactory::SystemFactory(QObject *parent) : QObject(parent) {
|
||||||
|
m_applicationCloseLock = new QReadWriteLock(QReadWriteLock::NonRecursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemFactory::~SystemFactory() {
|
SystemFactory::~SystemFactory() {
|
||||||
qDebug("Destroying SystemFactory instance.");
|
qDebug("Destroying SystemFactory instance.");
|
||||||
|
|
||||||
|
delete m_applicationCloseLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,6 +102,10 @@ SystemFactory *SystemFactory::getInstance() {
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QReadWriteLock *SystemFactory::applicationCloseLock() const {
|
||||||
|
return m_applicationCloseLock;
|
||||||
|
}
|
||||||
|
|
||||||
bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
|
bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
|
||||||
SystemFactory::AutoStartStatus current_status = SystemFactory::getAutoStartStatus();
|
SystemFactory::AutoStartStatus current_status = SystemFactory::getAutoStartStatus();
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,17 @@
|
||||||
|
|
||||||
|
|
||||||
class QReadWriteLock;
|
class QReadWriteLock;
|
||||||
|
class QMutex;
|
||||||
|
|
||||||
class SystemFactory : public QObject {
|
class SystemFactory : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Constructors and destructors.
|
||||||
explicit SystemFactory(QObject *parent = 0);
|
explicit SystemFactory(QObject *parent = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Constructors and destructors.
|
||||||
virtual ~SystemFactory();
|
virtual ~SystemFactory();
|
||||||
|
|
||||||
// Specifies possible states of auto-start functionality.
|
// Specifies possible states of auto-start functionality.
|
||||||
|
@ -40,7 +43,24 @@ class SystemFactory : public QObject {
|
||||||
// Singleton getter.
|
// Singleton getter.
|
||||||
static SystemFactory *getInstance();
|
static SystemFactory *getInstance();
|
||||||
|
|
||||||
|
// Access to application-wide close lock.
|
||||||
|
QReadWriteLock *applicationCloseLock() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// This read-write lock is used by application on its close.
|
||||||
|
// Application locks this lock for WRITTING.
|
||||||
|
// This means that if application locks that lock, then
|
||||||
|
// no other transaction-critical action can acquire lock
|
||||||
|
// for reading and won't be executed, so no critical action
|
||||||
|
// will be running when application quits
|
||||||
|
//
|
||||||
|
// EACH critical action locks this lock for READING.
|
||||||
|
// Several actions can lock this lock for reading.
|
||||||
|
// But of user decides to close the application (in other words,
|
||||||
|
// tries to lock the lock for writting), then no other
|
||||||
|
// action will be allowed to lock for reading.
|
||||||
|
QReadWriteLock *m_applicationCloseLock;
|
||||||
|
|
||||||
static QPointer<SystemFactory> s_instance;
|
static QPointer<SystemFactory> s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ class FeedsView : public QTreeView {
|
||||||
|
|
||||||
void setSortingEnabled(bool enable);
|
void setSortingEnabled(bool enable);
|
||||||
|
|
||||||
|
// Returns list of selected feeds.
|
||||||
QList<FeedsModelFeed*> selectedFeeds() const;
|
QList<FeedsModelFeed*> selectedFeeds() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -25,7 +26,10 @@ class FeedsView : public QTreeView {
|
||||||
void updateCountsOfSelectedFeeds();
|
void updateCountsOfSelectedFeeds();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Sets up appearance of this widget.
|
||||||
void setupAppearance();
|
void setupAppearance();
|
||||||
|
|
||||||
|
|
||||||
void selectionChanged(const QItemSelection &selected,
|
void selectionChanged(const QItemSelection &selected,
|
||||||
const QItemSelection &deselected);
|
const QItemSelection &deselected);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
#include "core/systemfactory.h"
|
||||||
#include "gui/formabout.h"
|
#include "gui/formabout.h"
|
||||||
#include "gui/formsettings.h"
|
#include "gui/formsettings.h"
|
||||||
#include "gui/webbrowser.h"
|
#include "gui/webbrowser.h"
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include <QSessionManager>
|
#include <QSessionManager>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
|
|
||||||
FormMain *FormMain::s_instance;
|
FormMain *FormMain::s_instance;
|
||||||
|
@ -129,6 +131,20 @@ void FormMain::processExecutionMessage(const QString &message) {
|
||||||
|
|
||||||
void FormMain::quit() {
|
void FormMain::quit() {
|
||||||
qDebug("Quitting the application.");
|
qDebug("Quitting the application.");
|
||||||
|
|
||||||
|
// Make sure that we obtain close lock
|
||||||
|
// BEFORE even trying to quit the application.
|
||||||
|
if (SystemFactory::getInstance()->applicationCloseLock()->tryLockForWrite(CLOSE_LOCK_TIMEOUT)) {
|
||||||
|
// Application obtained permission to close
|
||||||
|
// in a safety way.
|
||||||
|
qDebug("Close lock obtained safely.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Request for write lock timed-out. This means
|
||||||
|
// that some critical action can be processed right now.
|
||||||
|
qDebug("Close lock timed-out.");
|
||||||
|
}
|
||||||
|
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +194,7 @@ void FormMain::onSaveState(QSessionManager &manager) {
|
||||||
|
|
||||||
void FormMain::onAboutToQuit() {
|
void FormMain::onAboutToQuit() {
|
||||||
qDebug("Cleaning up resources and saving application state.");
|
qDebug("Cleaning up resources and saving application state.");
|
||||||
|
|
||||||
saveSize();
|
saveSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,11 @@ void MessagesView::setupAppearance() {
|
||||||
setSortingEnabled(true);
|
setSortingEnabled(true);
|
||||||
setAllColumnsShowFocus(true);
|
setAllColumnsShowFocus(true);
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
|
// Make sure that initial sorting is that unread messages are visible
|
||||||
|
// first.
|
||||||
|
// NOTE: This can be rewritten so that it's changeable.
|
||||||
|
sortByColumn(MSG_DB_READ_INDEX, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::keyPressEvent(QKeyEvent *event) {
|
void MessagesView::keyPressEvent(QKeyEvent *event) {
|
||||||
|
@ -198,7 +203,13 @@ void MessagesView::currentChanged(const QModelIndex ¤t,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::loadFeeds(const QList<int> &feed_ids) {
|
void MessagesView::loadFeeds(const QList<int> &feed_ids) {
|
||||||
|
// Load messages.
|
||||||
|
// TODO: Here we could load user-defined default sorting
|
||||||
|
// column/order AND possibly hide/show user-defined columns.
|
||||||
m_sourceModel->loadMessages(feed_ids);
|
m_sourceModel->loadMessages(feed_ids);
|
||||||
|
|
||||||
|
// Messages are loaded, make sure that previously
|
||||||
|
// active message is not shown in browser.
|
||||||
emit currentMessageRemoved();
|
emit currentMessageRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ class MessagesView : public QTreeView {
|
||||||
MessagesModel *sourceModel();
|
MessagesModel *sourceModel();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
// Loads un-deleted messages from selected feeds.
|
||||||
void loadFeeds(const QList<int> &feed_ids);
|
void loadFeeds(const QList<int> &feed_ids);
|
||||||
|
|
||||||
// Message manipulators.
|
// Message manipulators.
|
||||||
|
|
Loading…
Add table
Reference in a new issue