File indexing completed on 2024-04-28 15:21:01

0001 /*  -*- C++ -*-
0002  *  Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org>
0003  *
0004  *
0005  *  Permission is hereby granted, free of charge, to any person obtaining
0006  *  a copy of this software and associated documentation files (the
0007  *  "Software"), to deal in the Software without restriction, including
0008  *  without limitation the rights to use, copy, modify, merge, publish,
0009  *  distribute, sublicense, and/or sell copies of the Software, and to
0010  *  permit persons to whom the Software is furnished to do so, subject to
0011  *  the following conditions:
0012  *
0013  *  The above copyright notice and this permission notice shall be included
0014  *  in all copies or substantial portions of the Software.
0015  *
0016  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0017  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0019  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
0020  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
0021  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0022  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023  */
0024 
0025 #ifndef KRESOLVERWORKERBASE_H
0026 #define KRESOLVERWORKERBASE_H
0027 
0028 #include "k3resolver.h"
0029 
0030 // forward declarations
0031 class QString;
0032 template <class T> class QValueList;
0033 
0034 namespace KNetwork
0035 {
0036 
0037 namespace Internal
0038 {
0039 class KResolverThread;
0040 struct InputData;
0041 }
0042 
0043 /**
0044  * @class KResolverWorkerBase k3resolverworkerbase.h k3resolverworkerbase.h
0045  *
0046  * @internal
0047  *
0048  * This class is the base functionality for a resolver worker. That is,
0049  * the class that does the actual work.
0050  *
0051  * In the future, this class might be exposed to allow plug-ins. So, try and
0052  * make it binary compatible.
0053  *
0054  * Note that hostnames are still encoded in Unicode at this point. It's up to
0055  * the worker class to decide which encoding to use. In the case of DNS,
0056  * an ASCII Compatible Encoding (ACE) must be used.
0057  * See KResolver::domainToAscii().
0058  *
0059  * Also specially note that the run method in this class is called in a
0060  * thread that is not the program's main thread. So do not do anything there
0061  * that you shouldn't!
0062  *
0063  * @deprecated Use KSocketFactory or KLocalSocket instead
0064  */
0065 class KResolverWorkerBase
0066 {
0067 public:
0068 
0069     /**
0070      * Helper class for locking the resolver subsystem.
0071      * Similar to QMutexLocker.
0072      *
0073      * @author Luís Pedro Coelho
0074      */
0075     class ResolverLocker
0076     {
0077     public:
0078         /**
0079          * Constructor. Acquires a lock.
0080          */
0081         ResolverLocker(KResolverWorkerBase *parent)
0082             : parent(parent)
0083         {
0084             parent->acquireResolver();
0085         }
0086 
0087         /**
0088          * Destructor. Releases the lock.
0089          */
0090         ~ResolverLocker()
0091         {
0092             parent->releaseResolver();
0093         }
0094 
0095         /**
0096          * Releases the lock and then reacquires it.
0097          * It may be necessary to call this if the resolving function
0098          * decides to retry.
0099          */
0100         void openClose()
0101         {
0102             parent->releaseResolver();
0103             parent->acquireResolver();
0104         }
0105 
0106     private:
0107         /// @internal
0108         KResolverWorkerBase *parent;
0109     };
0110 private:
0111     // this will be like our d pointer
0112     KNetwork::Internal::KResolverThread *th;
0113     const KNetwork::Internal::InputData *input;
0114     friend class KNetwork::Internal::KResolverThread;
0115     friend class KNetwork::Internal::KResolverManager;
0116     friend class KResolverWorkerBase::ResolverLocker;
0117 
0118     int m_finished : 1;
0119     int m_reserved : 31;      // reserved
0120 
0121 public:
0122     /**
0123      * Derived classes will put their resolved data in this list, or will
0124      * leave it empty in case of error.
0125      *
0126      * Status and error codes should also be stored in this object (the
0127      * setError() function does that).
0128      */
0129     KResolverResults results;
0130 
0131 public:
0132     // default constructor
0133     KResolverWorkerBase();
0134 
0135     // virtual destructor
0136     virtual ~KResolverWorkerBase();
0137 
0138     /**
0139      * This is the hostname to be looked for
0140      */
0141     QString nodeName() const;
0142 
0143     /**
0144      * And this is the service name
0145      */
0146     QString serviceName() const;
0147 
0148     /**
0149      * gets the flags
0150      */
0151     int flags() const;
0152 
0153     /**
0154      * gets the family mask
0155      */
0156     int familyMask() const;
0157 
0158     /**
0159      * gets the socket type
0160      */
0161     int socketType() const;
0162 
0163     /**
0164      * gets the protocol number
0165      */
0166     int protocol() const;
0167 
0168     /**
0169      * gets the protocol name, if applicable
0170      */
0171     QByteArray protocolName() const;
0172 
0173     /**
0174      * Call this function to indicate that processing
0175      * has finished. This is useful in the preprocessing
0176      * stage, to indicate that run() doesn't have to be
0177      * called.
0178      */
0179     void finished();
0180 
0181 protected:
0182     // like a QThread
0183     /**
0184      * This is the function that should be overridden in derived classes.
0185      *
0186      * Derived classes will do their blocking job in this function and return
0187      * either success or failure to work (not the lookup). That is, whether the
0188      * lookup result was a domain found or not, if we got our answer, we should
0189      * indicate success. The error itself must be set with setError().
0190      *
0191      * \b Important: this function gets called in a separate thread!
0192      *
0193      * @return true on success
0194      */
0195     virtual bool run() = 0;
0196 
0197     /**
0198      * This function gets called during pre processing for this class and you must
0199      * override it.
0200      *
0201      * \b Important: this function gets called in the main event thread. And it MUST
0202      * NOT block.
0203      *
0204      * This function can be used for an object to determine if it will be able
0205      * to resolve the given data or not even before launching into a blocking
0206      * operation. This function should return true if the object is capable of
0207      * handling this kind of data; false otherwise. Note that the return value
0208      * of 'true' means that the object's blocking answer will be considered authoritative.
0209      *
0210      * This function MUST NOT queue further requests. Leave that to run().
0211      *
0212      * This function is pure virtual; you must override it.
0213      *
0214      * @return true on success
0215      */
0216     virtual bool preprocess() = 0;
0217 
0218     /**
0219      * This function gets called during post processing for this class.
0220      *
0221      * \b Important: this function gets called in the main event thread. And it MUST
0222      * NOT block.
0223      *
0224      * @returns true on success
0225      */
0226     virtual bool postprocess();
0227 
0228     /**
0229      * Sets the error
0230      */
0231     inline void setError(int errorcode, int syserror = 0)
0232     {
0233         results.setError(errorcode, syserror);
0234     }
0235 
0236     /**
0237      * Enqueue the given resolver for post-processing.
0238      *
0239      * Use this function to make the manager call for another resolution.
0240      * This is suitable for workers that do post-processing.
0241      *
0242      * The manager will make sure that any requests enqueued by this function
0243      * are done before calling the postprocessing function, which you should
0244      * override.
0245      *
0246      * \b Important: do use KResolver's own enqueueing functions (i.e., KResolver::start()).
0247      * Instead, use this function.
0248      *
0249      * @returns true on successful queuing or false if a problem ocurred
0250      */
0251     bool enqueue(KResolver *other);
0252 
0253     /**
0254      * @overload
0255      */
0256     bool enqueue(KResolverWorkerBase *worker);
0257 
0258     /**
0259      * Checks the resolver subsystem status.
0260      * @returns true if the resolver subsystem changed, false otherwise.
0261      *          If this function returns true, it might be necessary to
0262      *          restart the resolution altogether.
0263      */
0264     bool checkResolver();
0265 
0266     /**
0267      * This function has to be called from the resolver workers that require
0268      * use of the DNS resolver code (i.e., res_* functions, generally in
0269      * libresolv). It indicates that the function is starting a resolution
0270      * and that the resolver backend shouldn't change asynchronously.
0271      *
0272      * If any pending res_init's are required, they will be performed before
0273      * this function returns.
0274      */
0275     void acquireResolver();
0276 
0277     /**
0278      * This function is the counterpart for acquireResolver() - the worker
0279      * thread indicates that it's done with the resolver.
0280      */
0281     void releaseResolver();
0282 
0283 };
0284 
0285 /**
0286  * @class KResolverWorkerFactoryBase k3resolverworkerbase.h k3resolverworkerbase.h
0287  *
0288  * @internal
0289  *
0290  * This class provides functionality for creating and registering worker classes.
0291  *
0292  * @deprecated Use KSocketFactory or KLocalSocket instead
0293  */
0294 class KResolverWorkerFactoryBase
0295 {
0296 public:
0297     virtual ~KResolverWorkerFactoryBase() {}
0298     virtual KResolverWorkerBase *create() const = 0;
0299     /**
0300      * Wrapper call to register workers
0301      *
0302      * It is NOT thread-safe!
0303      */
0304     static void registerNewWorker(KResolverWorkerFactoryBase *factory);
0305 };
0306 
0307 /**
0308  * @class KResolverWorkerFactory k3resolverworkerbase.h k3resolverworkerbase.h
0309  *
0310  * @internal
0311  *
0312  * This class provides functionality for creating and registering worker classes.
0313  *
0314  * @deprecated Use KSocketFactory or KLocalSocket instead
0315  */
0316 template<class Worker>
0317 class KResolverWorkerFactory: public KResolverWorkerFactoryBase
0318 {
0319 public:
0320     KResolverWorkerBase *create() const override
0321     {
0322         return new Worker;
0323     }
0324 };
0325 
0326 }               // namespace KNetwork
0327 
0328 #endif