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 */
1.4.2