• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

libkleo

  • sources
  • kde-4.12
  • kdepim
  • libkleo
  • backends
  • qgpgme
threadedjobmixin.h
Go to the documentation of this file.
1 /*
2  threadedjobmixin.h
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  Copyright (c) 2008 Klarälvdalens Datakonsult AB
6 
7  Libkleopatra is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of the
10  License, or (at your option) any later version.
11 
12  Libkleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #ifndef __KLEO_THREADEDJOBMIXING_H__
34 #define __KLEO_THREADEDJOBMIXING_H__
35 
36 #include "qgpgmeprogresstokenmapper.h"
37 
38 #include <QMutex>
39 #include <QMutexLocker>
40 #include <QThread>
41 #include <QString>
42 #include <QIODevice>
43 
44 #include <gpgme++/context.h>
45 #include <gpgme++/interfaces/progressprovider.h>
46 
47 #include <boost/shared_ptr.hpp>
48 #include <boost/weak_ptr.hpp>
49 #include <boost/bind.hpp>
50 #include <boost/function.hpp>
51 #include <boost/tuple/tuple.hpp>
52 #include <boost/utility/enable_if.hpp>
53 #include <boost/type_traits/is_same.hpp>
54 
55 #include <cassert>
56 
57 namespace Kleo {
58 namespace _detail {
59 
60  QString audit_log_as_html( GpgME::Context * ctx, GpgME::Error & err );
61 
62  class PatternConverter {
63  const QList<QByteArray> m_list;
64  mutable const char ** m_patterns;
65  public:
66  explicit PatternConverter( const QByteArray & ba );
67  explicit PatternConverter( const QString & s );
68  explicit PatternConverter( const QList<QByteArray> & lba );
69  explicit PatternConverter( const QStringList & sl );
70  ~PatternConverter();
71 
72  const char ** patterns() const;
73  };
74 
75  class ToThreadMover {
76  QObject * const m_object;
77  QThread * const m_thread;
78  public:
79  ToThreadMover( QObject * o, QThread * t ) : m_object( o ), m_thread( t ) {}
80  ToThreadMover( QObject & o, QThread * t ) : m_object( &o ), m_thread( t ) {}
81  ToThreadMover( const boost::shared_ptr<QObject> & o, QThread * t ) : m_object( o.get() ), m_thread( t ) {}
82  ~ToThreadMover() { if ( m_object && m_thread ) m_object->moveToThread( m_thread ); }
83  };
84 
85  template <typename T_result>
86  class Thread : public QThread {
87  public:
88  explicit Thread( QObject * parent=0 ) : QThread( parent ) {}
89 
90  void setFunction( const boost::function<T_result()> & function ) {
91  const QMutexLocker locker( &m_mutex );
92  m_function = function;
93  }
94 
95  T_result result() const {
96  const QMutexLocker locker( &m_mutex );
97  return m_result;
98  }
99 
100  private:
101  /* reimp */ void run() {
102  const QMutexLocker locker( &m_mutex );
103  m_result = m_function();
104  }
105  private:
106  mutable QMutex m_mutex;
107  boost::function<T_result()> m_function;
108  T_result m_result;
109  };
110 
111  template <typename T_base, typename T_result=boost::tuple<GpgME::Error,QString,GpgME::Error> >
112  class ThreadedJobMixin : public T_base, public GpgME::ProgressProvider {
113  public:
114  typedef ThreadedJobMixin<T_base, T_result> mixin_type;
115  typedef T_result result_type;
116 
117  protected:
118  BOOST_STATIC_ASSERT(( boost::tuples::length<T_result>::value > 2 ));
119  BOOST_STATIC_ASSERT((
120  boost::is_same<
121  typename boost::tuples::element<
122  boost::tuples::length<T_result>::value - 2,
123  T_result
124  >::type,
125  QString
126  >::value
127  ));
128  BOOST_STATIC_ASSERT((
129  boost::is_same<
130  typename boost::tuples::element<
131  boost::tuples::length<T_result>::value - 1,
132  T_result
133  >::type,
134  GpgME::Error
135  >::value
136  ));
137 
138  explicit ThreadedJobMixin( GpgME::Context * ctx )
139  : T_base( 0 ), m_ctx( ctx ), m_thread(), m_auditLog(), m_auditLogError()
140  {
141 
142  }
143 
144  void lateInitialization() {
145  assert( m_ctx );
146  QObject::connect( &m_thread, SIGNAL(finished()), this, SLOT(slotFinished()) );
147  m_ctx->setProgressProvider( this );
148  }
149 
150  template <typename T_binder>
151  void run( const T_binder & func ) {
152  m_thread.setFunction( boost::bind( func, this->context() ) );
153  m_thread.start();
154  }
155  template <typename T_binder>
156  void run( const T_binder & func, const boost::shared_ptr<QIODevice> & io ) {
157  if ( io ) io->moveToThread( &m_thread );
158  // the arguments passed here to the functor are stored in a QThread, and are not
159  // necessarily destroyed (living outside the UI thread) at the time the result signal
160  // is emitted and the signal receiver wants to clean up IO devices.
161  // To avoid such races, we pass weak_ptr's to the functor.
162  m_thread.setFunction( boost::bind( func, this->context(), this->thread(), boost::weak_ptr<QIODevice>( io ) ) );
163  m_thread.start();
164  }
165  template <typename T_binder>
166  void run( const T_binder & func, const boost::shared_ptr<QIODevice> & io1, const boost::shared_ptr<QIODevice> & io2 ) {
167  if ( io1 ) io1->moveToThread( &m_thread );
168  if ( io2 ) io2->moveToThread( &m_thread );
169  // the arguments passed here to the functor are stored in a QThread, and are not
170  // necessarily destroyed (living outside the UI thread) at the time the result signal
171  // is emitted and the signal receiver wants to clean up IO devices.
172  // To avoid such races, we pass weak_ptr's to the functor.
173  m_thread.setFunction( boost::bind( func, this->context(), this->thread(), boost::weak_ptr<QIODevice>( io1 ), boost::weak_ptr<QIODevice>( io2 ) ) );
174  m_thread.start();
175  }
176  GpgME::Context * context() const { return m_ctx.get(); }
177 
178  virtual void resultHook( const result_type & ) {}
179 
180  void slotFinished() {
181  const T_result r = m_thread.result();
182  m_auditLog = boost::get<boost::tuples::length<T_result>::value-2>( r );
183  m_auditLogError = boost::get<boost::tuples::length<T_result>::value-1>( r );
184  resultHook( r );
185  emit this->done();
186  doEmitResult( r );
187  this->deleteLater();
188  }
189  /* reimp */ void slotCancel() {
190  if ( m_ctx ) m_ctx->cancelPendingOperation();
191  }
192  /* reimp */ QString auditLogAsHtml() const { return m_auditLog; }
193  /* reimp */ GpgME::Error auditLogError() const { return m_auditLogError; }
194  /* reimp */ void showProgress( const char * what, int type, int current, int total ) {
195  // will be called from the thread exec'ing the operation, so
196  // just bounce everything to the owning thread:
197  // ### hope this is thread-safe (meta obj is const, and
198  // ### portEvent is thread-safe, so should be ok)
199  QMetaObject::invokeMethod( this, "progress", Qt::QueuedConnection,
200  Q_ARG( QString, QGpgMEProgressTokenMapper::map( what, type ) ),
201  Q_ARG( int, current ),
202  Q_ARG( int, total ) );
203  }
204  private:
205  template <typename T1, typename T2>
206  void doEmitResult( const boost::tuple<T1,T2> & tuple ) {
207  emit this->result( boost::get<0>( tuple ), boost::get<1>( tuple ) );
208  }
209 
210  template <typename T1, typename T2, typename T3>
211  void doEmitResult( const boost::tuple<T1,T2,T3> & tuple ) {
212  emit this->result( boost::get<0>( tuple ), boost::get<1>( tuple ), boost::get<2>( tuple ) );
213  }
214 
215  template <typename T1, typename T2, typename T3, typename T4>
216  void doEmitResult( const boost::tuple<T1,T2,T3,T4> & tuple ) {
217  emit this->result( boost::get<0>( tuple ), boost::get<1>( tuple ), boost::get<2>( tuple ), boost::get<3>( tuple ) );
218  }
219 
220  template <typename T1, typename T2, typename T3, typename T4, typename T5>
221  void doEmitResult( const boost::tuple<T1,T2,T3,T4,T5> & tuple ) {
222  emit this->result( boost::get<0>( tuple ), boost::get<1>( tuple ), boost::get<2>( tuple ), boost::get<3>( tuple ), boost::get<4>( tuple ) );
223  }
224 
225  private:
226  boost::shared_ptr<GpgME::Context> m_ctx;
227  Thread<T_result> m_thread;
228  QString m_auditLog;
229  GpgME::Error m_auditLogError;
230  };
231 
232 }
233 }
234 
235 #endif /* __KLEO_THREADEDJOBMIXING_H__ */
236 
Kleo::_detail::Thread::Thread
Thread(QObject *parent=0)
Definition: threadedjobmixin.h:88
Kleo::_detail::ThreadedJobMixin::run
void run(const T_binder &func, const boost::shared_ptr< QIODevice > &io1, const boost::shared_ptr< QIODevice > &io2)
Definition: threadedjobmixin.h:166
Kleo::_detail::PatternConverter
Definition: threadedjobmixin.h:62
QMutex
Kleo::_detail::ThreadedJobMixin::context
GpgME::Context * context() const
Definition: threadedjobmixin.h:176
Kleo::_detail::ThreadedJobMixin::slotCancel
void slotCancel()
Definition: threadedjobmixin.h:189
Kleo::_detail::Thread::result
T_result result() const
Definition: threadedjobmixin.h:95
Kleo::_detail::ThreadedJobMixin::ThreadedJobMixin
ThreadedJobMixin(GpgME::Context *ctx)
Definition: threadedjobmixin.h:138
QString
Kleo::QGpgMEProgressTokenMapper::map
QString map(const char *token, int subtoken)
Definition: qgpgmeprogresstokenmapper.cpp:91
QObject
Kleo::_detail::ThreadedJobMixin::resultHook
virtual void resultHook(const result_type &)
Definition: threadedjobmixin.h:178
Kleo::_detail::ThreadedJobMixin::slotFinished
void slotFinished()
Definition: threadedjobmixin.h:180
Kleo::_detail::ThreadedJobMixin::showProgress
void showProgress(const char *what, int type, int current, int total)
Definition: threadedjobmixin.h:194
Kleo::_detail::Thread::setFunction
void setFunction(const boost::function< T_result()> &function)
Definition: threadedjobmixin.h:90
Kleo::_detail::ThreadedJobMixin::auditLogError
GpgME::Error auditLogError() const
Definition: threadedjobmixin.h:193
boost::shared_ptr
Definition: checksumdefinition.h:46
Kleo::_detail::ToThreadMover
Definition: threadedjobmixin.h:75
Kleo::_detail::ThreadedJobMixin::lateInitialization
void lateInitialization()
Definition: threadedjobmixin.h:144
Kleo::_detail::audit_log_as_html
QString audit_log_as_html(GpgME::Context *ctx, GpgME::Error &err)
Kleo::_detail::PatternConverter::patterns
const char ** patterns() const
Definition: threadedjobmixin.cpp:87
Kleo::_detail::ToThreadMover::ToThreadMover
ToThreadMover(const boost::shared_ptr< QObject > &o, QThread *t)
Definition: threadedjobmixin.h:81
Kleo::_detail::PatternConverter::PatternConverter
PatternConverter(const QByteArray &ba)
Definition: threadedjobmixin.cpp:78
Kleo::_detail::ThreadedJobMixin::BOOST_STATIC_ASSERT
BOOST_STATIC_ASSERT((boost::tuples::length< T_result >::value > 2))
Kleo::_detail::PatternConverter::~PatternConverter
~PatternConverter()
Definition: threadedjobmixin.cpp:97
qgpgmeprogresstokenmapper.h
Kleo::_detail::ThreadedJobMixin::result_type
T_result result_type
Definition: threadedjobmixin.h:115
Kleo::_detail::ThreadedJobMixin::run
void run(const T_binder &func)
Definition: threadedjobmixin.h:151
Kleo::_detail::ThreadedJobMixin::auditLogAsHtml
QString auditLogAsHtml() const
Definition: threadedjobmixin.h:192
Kleo::_detail::ToThreadMover::~ToThreadMover
~ToThreadMover()
Definition: threadedjobmixin.h:82
T_base
Kleo::_detail::ToThreadMover::ToThreadMover
ToThreadMover(QObject *o, QThread *t)
Definition: threadedjobmixin.h:79
Kleo::_detail::ToThreadMover::ToThreadMover
ToThreadMover(QObject &o, QThread *t)
Definition: threadedjobmixin.h:80
Kleo::_detail::Thread
Definition: threadedjobmixin.h:86
Kleo::_detail::ThreadedJobMixin
Definition: threadedjobmixin.h:112
Kleo::_detail::ThreadedJobMixin::run
void run(const T_binder &func, const boost::shared_ptr< QIODevice > &io)
Definition: threadedjobmixin.h:156
Kleo::_detail::ThreadedJobMixin::mixin_type
ThreadedJobMixin< T_base, T_result > mixin_type
Definition: threadedjobmixin.h:114
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:57:49 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkleo

Skip menu "libkleo"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal