[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdelibs/ksecretsservice] /: Add a new queued job class which will
From:       Michael Leupold <lemma () confuego ! org>
Date:       2011-09-04 15:26:47
Message-ID: 20110904152647.44812A607A () git ! kde ! org
[Download RAW message or body]

Git commit 821d76eb051b02cc3561e334e50c020fa812d26a by Michael Leupold.
Committed on 10/08/2010 at 10:50.
Pushed by vrusu into branch 'ksecretsservice'.

Add a new queued job class which will be used as a replacement for AsyncCall and will \
also help implementing gui jobs.

svn path=/trunk/playground/base/ksecretservice/; revision=1161477

A  +96   -0    jobqueue.cpp     [License: GPL (v2/3)]
A  +76   -0    jobqueue_p.h     [License: GPL (v2/3)]
A  +119  -0    queuedjob.h     [License: GPL (v2/3)]
A  +7    -0    CMakeLists.txt
A  +61   -0    jobqueue.h     [License: GPL (v2/3)]
A  +75   -0    queuedjob.cpp     [License: GPL (v2/3)]

http://commits.kde.org/kdelibs/821d76eb051b02cc3561e334e50c020fa812d26a

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..2095d54
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET (ksecretservice_lib_SRCS
+   jobqueue.cpp
+   queuedjob.cpp
+)
+
+KDE4_ADD_LIBRARY (ksecretservicelib STATIC ${ksecretservice_lib_SRCS})
+TARGET_LINK_LIBRARIES (ksecretservicelib ${QT_QTCORE_LIBRARY})
diff --git a/jobqueue.cpp b/jobqueue.cpp
new file mode 100644
index 0000000..5cdee0c
--- /dev/null
+++ b/jobqueue.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "jobqueue.h"
+#include "queuedjob.h"
+#include "jobqueue_p.h"
+
+#include <QtCore/QTimer>
+
+JobQueuePrivate::JobQueuePrivate()
+{
+}
+
+JobQueuePrivate::~JobQueuePrivate()
+{
+   // TODO: make sure there's no jobs left running when we go down
+}
+
+void JobQueuePrivate::enqueue(QueuedJob *job, bool inFront)
+{
+   Q_ASSERT(job);
+   if (inFront) {
+      m_jobs.prepend(job);
+   } else {
+      m_jobs.enqueue(job);
+   }
+   
+   if (m_currentJob.isNull()) {
+      QTimer::singleShot(0, this, SLOT(process()));
+   }
+}
+
+void JobQueuePrivate::process()
+{
+   // check if already processing
+   if (!m_currentJob.isNull()) {
+      return;
+   }
+   
+   // get a job to execute
+   // as the job queue consists of QPointers, jobs which have been dismissed
+   // (deleted) are automatically weeded out.
+   while (m_currentJob.isNull()) {
+      if (m_jobs.isEmpty()) {
+         return;
+      }
+      m_currentJob = m_jobs.dequeue();
+   }
+   
+   connect(m_currentJob.data(), SIGNAL(result(QueuedJob*)),
+                                SLOT(jobFinished(QueuedJob*)));
+}
+
+void JobQueuePrivate::jobFinished(QueuedJob *job)
+{
+   Q_UNUSED(job);
+   Q_ASSERT(job == m_currentJob);
+   m_currentJob = 0;
+   // keep processing if there's more jobs
+   if (!m_jobs.isEmpty()) {
+      QTimer::singleShot(0, this, SLOT(process()));
+   }
+}
+
+JobQueue::JobQueue() : d(new JobQueuePrivate)
+{
+}
+
+JobQueue::~JobQueue()
+{
+   delete d;
+}
+
+void JobQueue::enqueue(QueuedJob *job, bool inFront)
+{
+   d->enqueue(job, inFront);
+}
+
+#include "jobqueue_p.moc"
diff --git a/jobqueue.h b/jobqueue.h
new file mode 100644
index 0000000..9275906
--- /dev/null
+++ b/jobqueue.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef JOBQUEUE_H
+#define JOBQUEUE_H
+
+// forward declarations
+class QueuedJob;
+class JobQueuePrivate;
+
+/**
+ * Generic class which is used for queueing objects of class QueuedJob
+ * and executing them one after another.
+ *
+ * This class does intentionally not inherit QObject so it can be inherited
+ * by other QObject-based classes.
+ */
+class JobQueue
+{
+public:
+   /**
+    * Constructor.
+    */
+   JobQueue();
+   
+   /**
+    * Destructor.
+    */
+   virtual ~JobQueue();
+   
+   /**
+    * Enqueue a job for processing.
+    *
+    * @param job the job to enqueue
+    * @param inFront true to enqueue the job in front so it is the next
+    *                job to be processed
+    */
+   void enqueue(QueuedJob *job, bool inFront = false);
+   
+private:
+   JobQueuePrivate *d;
+};
+
+#endif // JOBQUEUE_H
diff --git a/jobqueue_p.h b/jobqueue_p.h
new file mode 100644
index 0000000..77f1a79
--- /dev/null
+++ b/jobqueue_p.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef JOBQUEUE_P_H
+#define JOBQUEUE_P_H
+
+#include <QObject>
+#include <QQueue>
+#include <QPointer>
+
+// forward declarations
+class QueuedJob;
+
+/**
+ * Private JobQueue class that implements most of the logic.
+ */
+class JobQueuePrivate : public QObject
+{
+   Q_OBJECT
+
+public:
+   /**
+    * Constructor.
+    */
+   JobQueuePrivate();
+   
+   /**
+    * Destructor.
+    */
+   ~JobQueuePrivate();
+   
+   /**
+    * Enqueue a job for processing.
+    *
+    * @param job the job to enqueue
+    * @param inFront true to enqueue the job in front so it is the next
+    *                job to be processed
+    */
+   void enqueue(QueuedJob *job, bool inFront);
+
+private Q_SLOTS:
+   /**
+    * Start processing jobs.
+    */
+   void process();
+   
+   /**
+    * Used to receive result() signals of the current QueuedJob.
+    *
+    * @param job the job that sends its result
+    */
+   void jobFinished(QueuedJob *job);
+   
+private:
+   QQueue<QPointer<QueuedJob> > m_jobs;
+   QPointer<QueuedJob> m_currentJob;
+};
+
+#endif // JOBQUEUE_P_H
diff --git a/queuedjob.cpp b/queuedjob.cpp
new file mode 100644
index 0000000..a6d8828
--- /dev/null
+++ b/queuedjob.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "queuedjob.h"
+#include "jobqueue.h"
+
+class QueuedJobPrivate
+{
+public:
+   JobQueue *m_queue;
+   bool m_finished;
+   bool m_enqueued;
+};
+
+QueuedJob::QueuedJob(JobQueue *queue)
+ : d(new QueuedJobPrivate)
+{
+   Q_ASSERT(queue);
+   
+   d->m_queue = queue;
+   d->m_finished = false;
+   d->m_enqueued = false;
+}
+
+QueuedJob::~QueuedJob()
+{
+   delete d;
+}
+
+bool QueuedJob::isImmediate() const
+{
+   return false;
+}
+
+bool QueuedJob::isFinished() const
+{
+   return d->m_finished;
+}
+
+void QueuedJob::enqueue(bool inFront)
+{
+   // if the job has already been finished or enqueued, handle this
+   // gracefully.
+   if (d->m_enqueued || d->m_finished) {
+      return;
+   }
+   d->m_queue->enqueue(this, inFront);
+   d->m_enqueued = true;
+}
+
+void QueuedJob::emitResult()
+{
+   d->m_finished = true;
+   emit result(this);
+   deleteLater();
+}
+
+#include "queuedjob.moc"
diff --git a/queuedjob.h b/queuedjob.h
new file mode 100644
index 0000000..b0941b2
--- /dev/null
+++ b/queuedjob.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QUEUEDJOB_H
+#define QUEUEDJOB_H
+
+#include <QtCore/QObject>
+
+// forward declaration
+class JobQueue;
+class QueuedJobPrivate;
+
+/**
+ * Job-class that provides the ability to queue jobs in a JobQueue.
+ *
+ * @note Just like KJob, QueuedJob is meant to be used in a fire-and-forget
+ *       way. It's deleting itself when it has finished using deleteLater()
+ *       so the job instance disappears after the next event loop run.
+ */
+class QueuedJob : public QObject
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param queue queue the job will be enqueued into
+    */
+   explicit QueuedJob(JobQueue *queue);
+   
+   /**
+    * Destructor.
+    */
+   virtual ~QueuedJob();
+   
+   /**
+    * Checks if this call can be made immediately/synchronously.
+    *
+    * @return true if the call can be made immediately, false if it needs to
+    *         be queued
+    * @note The base implementation always returns false, so if your job class
+    *       isn't immediate, you don't have to reimplement this method.
+    */
+   virtual bool isImmediate() const;
+   
+   /**
+    * Check whether this job is finished.
+    *
+    * @return true if the job is finished, false else
+    */
+   bool isFinished() const;
+   
+   /**
+    * Enqueue this job into the JobQueue passed in its constructor.
+    *
+    * @param inFront true to enqueue the job in front so it is the next job
+    *                to be processed
+    */
+   void enqueue(bool inFront = false);
+   
+   /**
+    * Execute this job synchronously. Implementation of this method should
+    * not involve an event-loop and it should only be available if the job
+    * advertised that it can be called immediately.
+    *
+    * @note This method may emit the result but it doesn't have to. If it
+    *       doesn't call emitResult() it has to ensure that the object gets
+    *       deleted using deleteLater() by itself.
+    */
+   virtual void exec() = 0;
+   
+   /**
+    * Start the job asynchronously.
+    *
+    * When the job is finished, result() is emitted.
+    */
+   virtual void start() = 0;
+
+protected:
+   /**
+    * Emit the result of this job, notifying every object listening that
+    * it's finished.
+    */
+   void emitResult();
+   
+Q_SIGNALS:
+   /**
+    * Emit the result of this job.
+    *
+    * As this signal can't be emitted directly from derived classes, use
+    * emitResult() to mark the job as finished and emit this signal.
+    *
+    * @param job The job that finished (this object)
+    */
+   void result(QueuedJob *job);
+   
+private:
+   QueuedJobPrivate *d;
+};
+
+#endif // QUEUEDJOB_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic