Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

threadutil.h

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #ifndef THREADUTIL_H
00021 #define THREADUTIL_H
00022 
00023 #include <qvaluelist.h>
00024 #include <qobject.h>
00025 #include <qguardedptr.h>
00026 
00027 class QSocketNotifier;
00028 
00029 namespace ThreadUtil
00030 {
00031 
00032     class Mutex
00033     {
00034         friend class WaitCondition;
00035     public:
00036         Mutex();
00037         ~Mutex();
00038 
00039         void lock();
00040         void unlock();
00041         bool tryLock();
00042         bool isLocked();
00043 
00044     private:
00045         struct Data;
00046         Data *d;
00047 
00048         Mutex( const Mutex & );
00049         Mutex &operator=( const Mutex & );
00050     };
00051 
00052     class AutoLock
00053     {
00054     public:
00055         AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); }
00056         ~AutoLock() { m_mutex.unlock(); }
00057 
00058         Mutex *operator &() const { return &m_mutex; }
00059 
00060     private:
00061         Mutex &m_mutex;
00062     };
00063 
00064     class WaitCondition
00065     {
00066     public:
00067         WaitCondition();
00068         ~WaitCondition();
00069 
00070         bool wait();
00071         bool wait( Mutex &mutex );
00072 
00073         void wakeOne();
00074         void wakeAll();
00075 
00076     private:
00077         struct Data;
00078         Data *d;
00079 
00080         WaitCondition( const WaitCondition & );
00081         WaitCondition &operator=( const WaitCondition & );
00082     };
00083 
00084     class Thread
00085     {
00086     public:
00087         struct Data;
00088         friend struct Data;
00089 
00090         Thread();
00091         virtual ~Thread();
00092 
00093         void start();
00094         void terminate();
00095 
00096         bool wait();
00097 
00098         bool isRunning() const;
00099 
00100         static void exit();
00101     protected:
00102         virtual void run() = 0;
00103 
00104     private:
00105         Data *d;
00106     };
00107 
00108     class OnewayNotifier : public QObject
00109     {
00110         Q_OBJECT
00111     public:
00112         OnewayNotifier();
00113         ~OnewayNotifier();
00114 
00115         void notify();
00116 
00117     signals:
00118         void awake();
00119 
00120     private slots:
00121         void wakeUp();
00122 
00123     private:
00124         int m_readFd;
00125         int m_writeFd;
00126         QSocketNotifier *m_notifier;
00127     };
00128 
00129 
00130     class Channel;
00131 
00132     class ChannelMessage
00133     {
00134         friend class Channel;
00135     public:
00136         ChannelMessage( int type = -1, int data = -1, const char* msg = 0 );
00137         virtual ~ChannelMessage();
00138 
00139         int type() const { return m_type; }
00140         int data() const { return m_data; }
00141         const char* msg()const { return m_msg;  }
00142 
00143         void reply();
00144 
00145     private:
00146         ChannelMessage( const ChannelMessage & );
00147         ChannelMessage &operator=( const ChannelMessage );
00148 
00149         int m_type;
00150         int m_data;
00151         const char *m_msg;
00152         bool m_isCall : 1;
00153         bool m_replied : 1;
00154         bool m_inEventHandler : 1;
00155         Mutex m_guard;
00156         WaitCondition m_condition;
00157     };
00158 
00159     class Channel : public QObject
00160     {
00161         Q_OBJECT
00162     public:
00163         enum SendType { OneWay, WaitForReply };
00164         Channel( QObject *parent = 0, const char *name = 0 );
00165         virtual ~Channel();
00166 
00167         void send( ChannelMessage *message, SendType type );
00168 
00169     protected:
00170         virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0;
00171 
00172     private slots:
00173         void deliver();
00174 
00175     private:
00176         OnewayNotifier m_notifier;
00177 
00178         struct MsgEnvelope
00179         {
00180             MsgEnvelope() : type( OneWay ), msg( 0 ) {}
00181             MsgEnvelope( SendType _type , ChannelMessage *_msg )
00182                 : type( _type ), msg( _msg ) {}
00183 
00184             SendType type;
00185             ChannelMessage *msg;
00186         };
00187 
00188         void deliverOne( const MsgEnvelope &envelope );
00189 
00190         typedef QValueList<MsgEnvelope> MsgEnvelopeList;
00191 
00192         MsgEnvelopeList m_pendingMessages;
00193         Mutex m_pendingMessagesGuard;
00194 
00195         struct Private;
00196         Private *d;
00197     };
00198 
00199 }
00200 
00201 #endif // THREADUTIL_H
00202 /* vim: et sw=4 ts=4
00203  */

Generated on Sat Nov 5 16:17:33 2005 for OPIE by  doxygen 1.4.2