kdecore Library API Documentation

kresolver_p.h

00001 /* -*- C++ -*- 00002 * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> 00003 * 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining 00006 * a copy of this software and associated documentation files (the 00007 * "Software"), to deal in the Software without restriction, including 00008 * without limitation the rights to use, copy, modify, merge, publish, 00009 * distribute, sublicense, and/or sell copies of the Software, and to 00010 * permit persons to whom the Software is furnished to do so, subject to 00011 * the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #ifndef KRESOLVER_P_H 00026 #define KRESOLVER_P_H 00027 00028 #include <config.h> 00029 00030 #include <qstring.h> 00031 #include <qcstring.h> 00032 #include <qvaluelist.h> 00033 #include <qptrlist.h> 00034 #include <qptrqueue.h> 00035 #include <qthread.h> 00036 #include <qmutex.h> 00037 #include <qwaitcondition.h> 00038 #include <qsemaphore.h> 00039 #include <qevent.h> 00040 00041 #include "kdemacros.h" 00042 #include "kresolver.h" 00043 00044 /* decide whether we need a mutex */ 00045 #if !defined(HAVE_GETPROTOBYNAME_R) || !defined(HAVE_GETSERVBYNAME_R) || !defined(HAVE_GETHOSTBYNAME_R) 00046 # define NEED_MUTEX 00047 extern QMutex getXXbyYYmutex; 00048 #endif 00049 00050 namespace KNetwork 00051 { 00052 00053 // defined in network/qresolverworkerbase.h 00054 class KResolverWorkerBase; 00055 class KResolverWorkerFactoryBase; 00056 00057 class KResolverPrivate 00058 { 00059 public: 00060 // parent class. Should never be changed! 00061 KResolver* parent; 00062 bool deleteWhenDone : 1; 00063 bool waiting : 1; 00064 mutable bool emitSignal : 1; 00065 00066 // class status. Should not be changed by worker threads! 00067 volatile int status; 00068 volatile int errorcode, syserror; 00069 00070 // input data. Should not be changed by worker threads! 00071 struct InputData 00072 { 00073 QString node, service; 00074 QCString protocolName; 00075 int flags; 00076 int familyMask; 00077 int socktype; 00078 int protocol; 00079 } input; 00080 00081 // mutex 00082 QMutex mutex; 00083 00084 // output data 00085 KResolverResults results; 00086 00087 KResolverPrivate(KResolver* _parent, 00088 const QString& _node = QString::null, 00089 const QString& _service = QString::null) 00090 : parent(_parent), deleteWhenDone(false), waiting(false), emitSignal(true), 00091 status(0), errorcode(0), syserror(0) 00092 { 00093 input.node = _node; 00094 input.service = _service; 00095 input.flags = 0; 00096 input.familyMask = KResolver::AnyFamily; 00097 input.socktype = 0; 00098 input.protocol = 0; 00099 00100 results.setAddress(_node, _service); 00101 } 00102 }; 00103 00104 namespace Internal 00105 { 00106 class KResolverManager; 00107 class KResolverThread; 00108 00109 struct RequestData 00110 { 00111 // worker threads should not change values in the input data 00112 KNetwork::KResolverPrivate *obj; 00113 const KNetwork::KResolverPrivate::InputData *input; 00114 KNetwork::KResolverWorkerBase *worker; // worker class 00115 RequestData *requestor; // class that requested us 00116 00117 volatile int nRequests; // how many requests that we made we still have left 00118 }; 00119 00120 /* 00121 * @internal 00122 * This class is the resolver manager 00123 */ 00124 class KResolverManager 00125 { 00126 public: 00127 enum EventTypes 00128 { ResolutionCompleted = 1576 }; // arbitrary value; 00129 00130 /* 00131 * This wait condition is used to notify wait states (KResolver::wait) that 00132 * the resolver manager has finished processing one or more objects. All 00133 * objects in wait state will be woken up and will check if they are done. 00134 * If they aren't, they will go back to sleeping. 00135 */ 00136 QWaitCondition notifyWaiters; 00137 00138 private: 00139 /* 00140 * This variable is used to count the number of threads that are running 00141 */ 00142 volatile unsigned short runningThreads; 00143 00144 /* 00145 * This variable is used to count the number of threads that are currently 00146 * waiting for data. 00147 */ 00148 unsigned short availableThreads; 00149 00150 /* 00151 * This wait condition is used to notify worker threads that there is new 00152 * data available that has to be processed. All worker threads wait on this 00153 * waitcond for a limited amount of time. 00154 */ 00155 QWaitCondition feedWorkers; 00156 00157 // this mutex protects the data in this object 00158 QMutex mutex; 00159 00160 // hold a list of all the current threads we have 00161 QPtrList<KResolverThread> workers; 00162 00163 // hold a list of all the new requests we have 00164 QPtrList<RequestData> newRequests; 00165 00166 // hold a list of all the requests in progress we have 00167 QPtrList<RequestData> currentRequests; 00168 00169 // hold a list of all the workers we have 00170 QPtrList<KNetwork::KResolverWorkerFactoryBase> workerFactories; 00171 00172 // private constructor 00173 KResolverManager(); 00174 00175 public: 00176 static KResolverManager* manager() KDE_NO_EXPORT; // creates and returns the global manager 00177 00178 // destructor 00179 ~KResolverManager(); 00180 00181 /* 00182 * Register this thread in the pool 00183 */ 00184 void registerThread(KResolverThread* id); 00185 00186 /* 00187 * Unregister this thread from the pool 00188 */ 00189 void unregisterThread(KResolverThread* id); 00190 00191 /* 00192 * Requests new data to work on. 00193 * 00194 * This function should only be called from a worker thread. This function 00195 * is thread-safe. 00196 * 00197 * If there is data to be worked on, this function will return it. If there is 00198 * none, this function will return a null pointer. 00199 */ 00200 RequestData* requestData(KResolverThread* id, int maxWaitTime); 00201 00202 /* 00203 * Releases the resources and returns the resolved data. 00204 * 00205 * This function should only be called from a worker thread. It is 00206 * thread-safe. It does not post the event to the manager. 00207 */ 00208 void releaseData(KResolverThread *id, RequestData* data); 00209 00210 /* 00211 * Registers a new worker class by way of its factory. 00212 * 00213 * This function is NOT thread-safe. 00214 */ 00215 void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory); 00216 00217 /* 00218 * Enqueues new resolutions. 00219 */ 00220 void enqueue(KNetwork::KResolver *obj, RequestData* requestor); 00221 00222 /* 00223 * Dispatch a new request 00224 */ 00225 void dispatch(RequestData* data); 00226 00227 /* 00228 * Dequeues a resolution. 00229 */ 00230 void dequeue(KNetwork::KResolver *obj); 00231 00232 /* 00233 * Notifies the manager that the given resolution is about to 00234 * be deleted. This function should only be called by the 00235 * KResolver destructor. 00236 */ 00237 void aboutToBeDeleted(KNetwork::KResolver *obj); 00238 00239 /* 00240 * Notifies the manager that new events are ready. 00241 */ 00242 void newEvent(); 00243 00244 /* 00245 * This function is called by the manager to receive a new event. It operates 00246 * on the @ref eventSemaphore semaphore, which means it will block till there 00247 * is at least one event to go. 00248 */ 00249 void receiveEvent(); 00250 00251 private: 00252 /* 00253 * finds a suitable worker for this request 00254 */ 00255 KNetwork::KResolverWorkerBase *findWorker(KNetwork::KResolverPrivate *p); 00256 00257 /* 00258 * finds data for this request 00259 */ 00260 RequestData* findData(KResolverThread*); 00261 00262 /* 00263 * Handle completed requests. 00264 * 00265 * This function is called by releaseData above 00266 */ 00267 void handleFinished(); 00268 00269 /* 00270 * Handle one completed request. 00271 * 00272 * This function is called by handleFinished above. 00273 */ 00274 bool handleFinishedItem(RequestData* item); 00275 00276 /* 00277 * Notifies the parent class that this request is done. 00278 * 00279 * This function deletes the request 00280 */ 00281 void doNotifying(RequestData *p); 00282 00283 /* 00284 * Dequeues and notifies an object that is in Queued state 00285 * Returns true if the object is no longer queued; false if it could not 00286 * be dequeued (i.e., it's running) 00287 */ 00288 bool dequeueNew(KNetwork::KResolver* obj); 00289 }; 00290 00291 /* 00292 * @internal 00293 * This class is a worker thread in the resolver system. 00294 * This class must be thread-safe. 00295 */ 00296 class KResolverThread: public QThread 00297 { 00298 public: 00299 // private constructor. Only the manager can create worker threads 00300 KResolverThread(); 00301 RequestData* data; 00302 00303 protected: 00304 virtual void run(); // here the thread starts 00305 00306 friend class KNetwork::Internal::KResolverManager; 00307 friend class KNetwork::KResolverWorkerBase; 00308 }; 00309 00310 } // namespace Internal 00311 00312 } // namespace KNetwork 00313 00314 00315 #endif
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:10 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003