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 Sat Nov 27 13:41:18 2004 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003