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 00065 // class status. Should not be changed by worker threads! 00066 volatile int status; 00067 volatile int errorcode, syserror; 00068 00069 // input data. Should not be changed by worker threads! 00070 struct InputData 00071 { 00072 QString node, service; 00073 QCString protocolName; 00074 int flags; 00075 int familyMask; 00076 int socktype; 00077 int protocol; 00078 } input; 00079 00080 // mutex 00081 QMutex mutex; 00082 00083 // output data 00084 KResolverResults results; 00085 00086 KResolverPrivate(KResolver* _parent, 00087 const QString& _node = QString::null, 00088 const QString& _service = QString::null) 00089 : parent(_parent), deleteWhenDone(false), waiting(false), 00090 status(0), errorcode(0), syserror(0) 00091 { 00092 input.node = _node; 00093 input.service = _service; 00094 input.flags = 0; 00095 input.familyMask = KResolver::AnyFamily; 00096 input.socktype = 0; 00097 input.protocol = 0; 00098 00099 results.setAddress(_node, _service); 00100 } 00101 }; 00102 00103 namespace Internal 00104 { 00105 class KResolverManager; 00106 class KResolverThread; 00107 00108 struct RequestData 00109 { 00110 // worker threads should not change values in the input data 00111 KNetwork::KResolverPrivate *obj; 00112 const KNetwork::KResolverPrivate::InputData *input; 00113 KNetwork::KResolverWorkerBase *worker; // worker class 00114 RequestData *requestor; // class that requested us 00115 00116 volatile int nRequests; // how many requests that we made we still have left 00117 }; 00118 00119 /* 00120 * @internal 00121 * This class is the resolver manager 00122 */ 00123 class KResolverManager 00124 { 00125 public: 00126 enum EventTypes 00127 { ResolutionCompleted = 1576 }; // arbitrary value; 00128 00129 /* 00130 * This wait condition is used to notify wait states (KResolver::wait) that 00131 * the resolver manager has finished processing one or more objects. All 00132 * objects in wait state will be woken up and will check if they are done. 00133 * If they aren't, they will go back to sleeping. 00134 */ 00135 QWaitCondition notifyWaiters; 00136 00137 private: 00138 /* 00139 * This variable is used to count the number of threads that are running 00140 */ 00141 volatile unsigned short runningThreads; 00142 00143 /* 00144 * This variable is used to count the number of threads that are currently 00145 * waiting for data. 00146 */ 00147 unsigned short availableThreads; 00148 00149 /* 00150 * This wait condition is used to notify worker threads that there is new 00151 * data available that has to be processed. All worker threads wait on this 00152 * waitcond for a limited amount of time. 00153 */ 00154 QWaitCondition feedWorkers; 00155 00156 // this mutex protects the data in this object 00157 QMutex mutex; 00158 00159 // hold a list of all the current threads we have 00160 QPtrList<KResolverThread> workers; 00161 00162 // hold a list of all the new requests we have 00163 QPtrList<RequestData> newRequests; 00164 00165 // hold a list of all the requests in progress we have 00166 QPtrList<RequestData> currentRequests; 00167 00168 // hold a list of all the workers we have 00169 QPtrList<KNetwork::KResolverWorkerFactoryBase> workerFactories; 00170 00171 // private constructor 00172 KResolverManager(); 00173 00174 public: 00175 static KResolverManager* manager() KDE_NO_EXPORT; // creates and returns the global manager 00176 00177 // destructor 00178 ~KResolverManager(); 00179 00180 /* 00181 * Register this thread in the pool 00182 */ 00183 void registerThread(KResolverThread* id); 00184 00185 /* 00186 * Unregister this thread from the pool 00187 */ 00188 void unregisterThread(KResolverThread* id); 00189 00190 /* 00191 * Requests new data to work on. 00192 * 00193 * This function should only be called from a worker thread. This function 00194 * is thread-safe. 00195 * 00196 * If there is data to be worked on, this function will return it. If there is 00197 * none, this function will return a null pointer. 00198 */ 00199 RequestData* requestData(KResolverThread* id, int maxWaitTime); 00200 00201 /* 00202 * Releases the resources and returns the resolved data. 00203 * 00204 * This function should only be called from a worker thread. It is 00205 * thread-safe. It does not post the event to the manager. 00206 */ 00207 void releaseData(KResolverThread *id, RequestData* data); 00208 00209 /* 00210 * Registers a new worker class by way of its factory. 00211 * 00212 * This function is NOT thread-safe. 00213 */ 00214 void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory); 00215 00216 /* 00217 * Enqueues new resolutions. 00218 */ 00219 void enqueue(KNetwork::KResolver *obj, RequestData* requestor); 00220 00221 /* 00222 * Dispatch a new request 00223 */ 00224 void dispatch(RequestData* data); 00225 00226 /* 00227 * Dequeues a resolution. 00228 */ 00229 void dequeue(KNetwork::KResolver *obj); 00230 00231 /* 00232 * Notifies the manager that the given resolution is about to 00233 * be deleted. This function should only be called by the 00234 * KResolver destructor. 00235 */ 00236 void aboutToBeDeleted(KNetwork::KResolver *obj); 00237 00238 /* 00239 * Notifies the manager that new events are ready. 00240 */ 00241 void newEvent(); 00242 00243 /* 00244 * This function is called by the manager to receive a new event. It operates 00245 * on the @ref eventSemaphore semaphore, which means it will block till there 00246 * is at least one event to go. 00247 */ 00248 void receiveEvent(); 00249 00250 private: 00251 /* 00252 * finds a suitable worker for this request 00253 */ 00254 KNetwork::KResolverWorkerBase *findWorker(KNetwork::KResolverPrivate *p); 00255 00256 /* 00257 * finds data for this request 00258 */ 00259 RequestData* findData(KResolverThread*); 00260 00261 /* 00262 * Handle completed requests. 00263 * 00264 * This function is called by releaseData above 00265 */ 00266 void handleFinished(); 00267 00268 /* 00269 * Handle one completed request. 00270 * 00271 * This function is called by handleFinished above. 00272 */ 00273 bool handleFinishedItem(RequestData* item); 00274 00275 /* 00276 * Notifies the parent class that this request is done. 00277 * 00278 * This function deletes the request 00279 */ 00280 void doNotifying(RequestData *p); 00281 00282 /* 00283 * Dequeues and notifies an object that is in Queued state 00284 * Returns true if the object is no longer queued; false if it could not 00285 * be dequeued (i.e., it's running) 00286 */ 00287 bool dequeueNew(KNetwork::KResolver* obj); 00288 }; 00289 00290 /* 00291 * @internal 00292 * This class is a worker thread in the resolver system. 00293 * This class must be thread-safe. 00294 */ 00295 class KResolverThread: public QThread 00296 { 00297 public: 00298 // private constructor. Only the manager can create worker threads 00299 KResolverThread(); 00300 RequestData* data; 00301 00302 protected: 00303 virtual void run(); // here the thread starts 00304 00305 friend class KNetwork::Internal::KResolverManager; 00306 friend class KNetwork::KResolverWorkerBase; 00307 }; 00308 00309 } // namespace Internal 00310 00311 } // namespace KNetwork 00312 00313 00314 #endif
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:26:09 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003