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 Sat Jan 22 16:43:45 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003