• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDECore

k3resolver_p.h

Go to the documentation of this file.
00001 /*  -*- C++ -*-
00002  *  Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org>
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 #include <config-network.h>
00030 #include <sys/types.h>
00031 
00032 
00033 #include <QByteArray>
00034 #include <QList>
00035 #include <QThread>
00036 #include <QMutex>
00037 #include <QWaitCondition>
00038 #include <QSemaphore>
00039 #include <QEvent>
00040 
00041 #include "k3resolver.h"
00042 
00043 /* decide whether we need a mutex */
00044 #if !defined(HAVE_GETPROTOBYNAME_R) || !defined(HAVE_GETSERVBYNAME_R) || !defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETSERVBYPORT_R)
00045 # define NEED_MUTEX
00046 extern QMutex getXXbyYYmutex;
00047 #endif
00048 
00049 /* some systems have the functions, but don't declare them */
00050 #if defined(HAVE_GETSERVBYNAME_R) && !HAVE_GETSERVBYNAME_R_PROTO
00051 extern "C" {
00052   struct servent;
00053   extern int getservbyname_r(const char* serv, const char* proto,
00054                  struct servent* servbuf,
00055                  char* buf, size_t buflen,
00056                  struct servent** result);
00057   extern int getservbyport_r(int port, const char* proto,
00058                  struct servent* servbuf,
00059                  char* buf, size_t buflen,
00060                  struct servent** result);
00061 
00062   struct protoent;
00063   extern int getprotobyname_r(const char* proto, struct protoent* protobuf,
00064                   char *buf, size_t buflen,
00065                   struct protoent** result);
00066   extern int getprotobynumber_r(int proto, struct protoent* protobuf,
00067                 char *buf, size_t buflen,
00068                 struct protoent** result);
00069 }
00070 #endif
00071 
00072 /* decide whether res_init is thread-safe or not */
00073 #if defined(__GLIBC__)
00074 # undef RES_INIT_THREADSAFE
00075 #endif
00076 
00077 namespace KNetwork
00078 {
00079   // defined in network/qresolverworkerbase.h
00080   class KResolverWorkerBase;
00081   class KResolverWorkerFactoryBase;
00082   class KResolverPrivate;
00083 
00084   namespace Internal
00085   {
00086     class KResolverManager;
00087     class KResolverThread;
00088     struct RequestData;
00089 
00090     struct InputData
00091     {
00092       QString node, service;
00093       QByteArray protocolName;
00094       int flags;
00095       int familyMask;
00096       int socktype;
00097       int protocol;
00098     };
00099   }
00100 
00101   class KResolverPrivate
00102   {
00103   public:
00104     // parent class. Should never be changed!
00105     KResolver* parent;
00106     bool deleteWhenDone : 1;
00107     bool waiting : 1;
00108 
00109     // class status. Should not be changed by worker threads!
00110     volatile int status;
00111     volatile int errorcode, syserror;
00112 
00113     // input data. Should not be changed by worker threads!
00114     Internal::InputData input;
00115 
00116     // mutex
00117     QMutex mutex;
00118 
00119     // output data
00120     KResolverResults results;
00121 
00122     explicit KResolverPrivate(KResolver* _parent,
00123              const QString& _node = QString(),
00124              const QString& _service = QString())
00125       : parent(_parent), deleteWhenDone(false), waiting(false),
00126     status(0), errorcode(0), syserror(0)
00127     {
00128       input.node = _node;
00129       input.service = _service;
00130       input.flags = 0;
00131       input.familyMask = KResolver::AnyFamily;
00132       input.socktype = 0;
00133       input.protocol = 0;
00134 
00135       results.setAddress(_node, _service);
00136     }
00137   };
00138 
00139   namespace Internal
00140   {
00141     struct RequestData
00142     {
00143       // worker threads should not change values in the input data
00144       KNetwork::KResolverPrivate *obj;
00145       const KNetwork::Internal::InputData *input;
00146       KNetwork::KResolverWorkerBase *worker; // worker class
00147       RequestData *requestor; // class that requested us
00148 
00149       volatile int nRequests; // how many requests that we made we still have left
00150     };
00151 
00152     /*
00153      * @internal
00154      * This class is the resolver manager
00155      */
00156     class KResolverManager
00157     {
00158     public:
00159       enum EventTypes
00160     { ResolutionCompleted = 1576 }; // arbitrary value;
00161 
00162       /*
00163        * This wait condition is used to notify wait states (KResolver::wait) that
00164        * the resolver manager has finished processing one or more objects. All
00165        * objects in wait state will be woken up and will check if they are done.
00166        * If they aren't, they will go back to sleeping.
00167        */
00168       QWaitCondition notifyWaiters;
00169 
00170     private:
00171       /*
00172        * This variable is used to count the number of threads that are running
00173        */
00174       volatile unsigned short runningThreads;
00175 
00176       /*
00177        * This variable is used to count the number of threads that are currently
00178        * waiting for data.
00179        */
00180       unsigned short availableThreads;
00181 
00182       /*
00183        * This wait condition is used to notify worker threads that there is new
00184        * data available that has to be processed. All worker threads wait on this
00185        * waitcond for a limited amount of time.
00186        */
00187       QWaitCondition feedWorkers;
00188 
00189       // this mutex protects the data in this object
00190       QMutex mutex;
00191 
00192       // hold a list of all the current threads we have
00193       QList<KResolverThread*> workers;
00194 
00195       // hold a list of all the new requests we have
00196       QList<RequestData*> newRequests;
00197 
00198       // hold a list of all the requests in progress we have
00199       QList<RequestData*> currentRequests;
00200 
00201       // hold a list of all the workers we have
00202       QList<KNetwork::KResolverWorkerFactoryBase*> workerFactories;
00203 
00204       // private constructor
00205       KResolverManager();
00206 
00207     public:
00208       static KResolverManager* manager() KDE_NO_EXPORT; // creates and returns the global manager
00209 
00210       // destructor
00211       ~KResolverManager();
00212 
00213       /*
00214        * Register this thread in the pool
00215        */
00216       void registerThread(KResolverThread* id);
00217 
00218       /*
00219        * Unregister this thread from the pool
00220        */
00221       void unregisterThread(KResolverThread* id);
00222 
00223       /*
00224        * Requests new data to work on.
00225        *
00226        * This function should only be called from a worker thread. This function
00227        * is thread-safe.
00228        *
00229        * If there is data to be worked on, this function will return it. If there is
00230        * none, this function will return a null pointer.
00231        */
00232       RequestData* requestData(KResolverThread* id, int maxWaitTime);
00233 
00234       /*
00235        * Releases the resources and returns the resolved data.
00236        *
00237        * This function should only be called from a worker thread. It is
00238        * thread-safe. It does not post the event to the manager.
00239        */
00240       void releaseData(KResolverThread *id, RequestData* data);
00241 
00242       /*
00243        * Registers a new worker class by way of its factory.
00244        *
00245        * This function is NOT thread-safe.
00246        */
00247       void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory);
00248 
00249       /*
00250        * Enqueues new resolutions.
00251        */
00252       void enqueue(KNetwork::KResolver *obj, RequestData* requestor);
00253 
00254       /*
00255        * Dispatch a new request
00256        */
00257       void dispatch(RequestData* data);
00258 
00259       /*
00260        * Dequeues a resolution.
00261        */
00262       void dequeue(KNetwork::KResolver *obj);
00263 
00264       /*
00265        * Notifies the manager that the given resolution is about to
00266        * be deleted. This function should only be called by the
00267        * KResolver destructor.
00268        */
00269       void aboutToBeDeleted(KNetwork::KResolver *obj);
00270 
00271       /*
00272        * Notifies the manager that new events are ready.
00273        */
00274       void newEvent();
00275 
00276       /*
00277        * This function is called by the manager to receive a new event. It operates
00278        * on the eventSemaphore() semaphore, which means it will block till there
00279        * is at least one event to go.
00280        */
00281       void receiveEvent();
00282 
00283     private:
00284       /*
00285        * finds a suitable worker for this request
00286        */
00287       KNetwork::KResolverWorkerBase *findWorker(KNetwork::KResolverPrivate *p);
00288 
00289       /*
00290        * finds data for this request
00291        */
00292       RequestData* findData(KResolverThread*);
00293 
00294       /*
00295        * Handle completed requests.
00296        *
00297        * This function is called by releaseData above
00298        */
00299       void handleFinished();
00300 
00301       /*
00302        * Handle one completed request.
00303        *
00304        * This function is called by handleFinished above.
00305        */
00306       bool handleFinishedItem(RequestData* item);
00307 
00308       /*
00309        * Notifies the parent class that this request is done.
00310        *
00311        * This function deletes the request
00312        */
00313       void doNotifying(RequestData *p);
00314 
00315       /*
00316        * Dequeues and notifies an object that is in Queued state
00317        * Returns true if the object is no longer queued; false if it could not
00318        * be dequeued (i.e., it's running)
00319        */
00320       bool dequeueNew(KNetwork::KResolver* obj);
00321     };
00322 
00323     /*
00324      * @internal
00325      * This class is a worker thread in the resolver system.
00326      * This class must be thread-safe.
00327      */
00328     class KResolverThread: public QThread
00329     {
00330     private:
00331       // private constructor. Only the manager can create worker threads
00332       KResolverThread();
00333       RequestData* data;
00334 
00335     protected:
00336       virtual void run();       // here the thread starts
00337 
00338       friend class KNetwork::Internal::KResolverManager;
00339       friend class KNetwork::KResolverWorkerBase;
00340 
00341     public:
00342       bool checkResolver(); // see KResolverWorkerBase::checkResolver
00343       void acquireResolver();   // see KResolverWorkerBase::acquireResolver
00344       void releaseResolver();   // see KResolverWorkerBase::releaseResolver
00345     };
00346 
00347   } // namespace Internal
00348 
00349 } // namespace KNetwork
00350 
00351 
00352 #endif

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal