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

KDECore

  • kdecore
  • network
k3resolvermanager.cpp
Go to the documentation of this file.
1/* -*- C++ -*-
2 * Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <config.h>
26#include <config-network.h>
27
28#include <sys/types.h>
29#include <netinet/in.h>
30#include <limits.h>
31#include <unistd.h> // only needed for pid_t
32
33#ifdef HAVE_RES_INIT
34# include <sys/stat.h>
35extern "C" {
36# include <arpa/nameser.h>
37}
38# include <time.h>
39# include <resolv.h>
40#endif
41
42#include <QByteArray>
43#include <QCoreApplication>
44#include <QList>
45#include <QMutableListIterator>
46#include <QMutex>
47#include <QQueue>
48#include <QSemaphore>
49
50#include <QThread>
51#include <QTimer>
52#include <QWaitCondition>
53
54#include <kde_file.h>
55#include <kdebug.h>
56#include "k3resolver.h"
57#include "k3resolver_p.h"
58#include "k3resolverworkerbase.h"
59#include "k3resolverstandardworkers_p.h"
60
61using namespace KNetwork;
62using namespace KNetwork::Internal;
63
64/*
65 * Explanation on how the resolver system works
66
67 When KResolver::start is called, it calls KResolverManager::enqueue to add
68 an entry to the queue. KResolverManager::enqueue will verify the availability
69 of a worker thread: if one is available, it will dispatch the request to it.
70 If no threads are available, it will then decide whether to launch a thread
71 or to queue for the future.
72
73 (This process is achieved by always queuing the new request, starting a
74 new thread if necessary and then notifying of the availability of data
75 to all worker threads).
76
77 * Worker thread
78 A new thread, when started, will enter its event loop
79 immediately. That is, it'll first try to acquire new data to
80 process, which means it will lock and unlock the manager mutex in
81 the process.
82
83 If it finds no new data, it'll wait on the feedWorkers condition
84 for a certain maximum time. If that time expires and there's still
85 no data, the thread will exit, in order to save system resources.
86
87 If it finds data, however, it'll set up and call the worker class
88 that has been selected by the manager. Once that worker is done,
89 the thread releases the data through KResolverManager::releaseData.
90
91 * Data requesting/releasing
92 A worker thread always calls upon functions on the resolver manager
93 in order to acquire and release data.
94
95 When data is being requested, the KResolverManager::requestData
96 function will look the currentRequests list and return the first
97 Queued request it finds, while marking it to be InProgress.
98
99 When the worker class has returned, the worker thread will release
100 that data through the KResolverManager::releaseData function. If the
101 worker class has requested no further data (nRequests == 0), the
102 request's status is marked to be Done. It'll then look at the
103 requestor for that data: if it was requested by another worker,
104 it'll decrement the requests count for that one and add the results
105 to a list. And, finally, if the requests count for the requestor
106 becomes 0, it'll repeat this process for the requestor as well
107 (change status to Done, check for a requestor).
108 */
109
110namespace
111{
112
113/*
114 * This class is used to control the access to the
115 * system's resolver API.
116 *
117 * It is necessary to periodically poll /etc/resolv.conf and reload
118 * it if any changes are noticed. This class does exactly that.
119 *
120 * However, there's also the problem of reloading the structure while
121 * some threads are in progress. Therefore, we keep a usage reference count.
122 */
123class ResInitUsage
124{
125public:
126
127#ifdef HAVE_RES_INIT
128 time_t mTime;
129 int useCount;
130
131# ifndef RES_INIT_THREADSAFE
132 QWaitCondition cond;
133 QMutex mutex;
134# endif
135
136 bool shouldResInit()
137 {
138 // check if /etc/resolv.conf has changed
139 KDE_struct_stat st;
140 if (KDE_stat("/etc/resolv.conf", &st) != 0)
141 return false;
142
143 if (mTime != st.st_mtime)
144 {
145 kDebug(179) << "shouldResInit: /etc/resolv.conf updated";
146 return true;
147 }
148 return false;
149 }
150
151 void callResInit()
152 {
153 if (mTime != 0)
154 {
155 // don't call it the first time
156 // let it be initialized naturally
157 kDebug(179) << "callResInit: calling res_init()";
158 res_init();
159 }
160
161 KDE_struct_stat st;
162 if (KDE_stat("/etc/resolv.conf", &st) == 0)
163 mTime = st.st_mtime;
164 }
165
166 ResInitUsage()
167 : mTime(0), useCount(0)
168 { }
169
170 /*
171 * Marks the end of usage to the resolver tools
172 */
173 void release()
174 {
175# ifndef RES_INIT_THREADSAFE
176 QMutexLocker locker(&mutex);
177 if (--useCount == 0)
178 {
179 if (shouldResInit())
180 callResInit();
181
182 // we've reached 0, wake up anyone that's waiting to call res_init
183 cond.wakeAll();
184 }
185# else
186 // do nothing
187# endif
188 }
189
190 /*
191 * Marks the beginning of usage of the resolver API
192 */
193 void acquire()
194 {
195# ifndef RES_INIT_THREADSAFE
196 mutex.lock();
197
198 if (shouldResInit())
199 {
200 if (useCount)
201 {
202 // other threads are already using the API, so wait till
203 // it's all clear
204 // the thread that emits this condition will also call res_init
205 //qDebug("ResInitUsage: waiting for libresolv to be clear");
206 cond.wait(&mutex);
207 }
208 else
209 // we're clear
210 callResInit();
211 }
212 useCount++;
213 mutex.unlock();
214
215# else
216 if (shouldResInit())
217 callResInit();
218
219# endif
220 }
221
222#else
223 ResInitUsage()
224 { }
225
226 bool shouldResInit()
227 { return false; }
228
229 void acquire()
230 { }
231
232 void release()
233 { }
234#endif
235
236} resInit;
237
238} // anonymous namespace
239
240/*
241 * parameters
242 */
243// a thread will try maxThreadRetries to get data, waiting at most
244// maxThreadWaitTime milliseconds between each attempt. After that, it'll
245// exit
246static const int maxThreadWaitTime = 2000; // 2 seconds
247static const int maxThreads = 5;
248
249static pid_t pid; // FIXME -- disable when everything is ok
250
251KResolverThread::KResolverThread()
252 : data(0L)
253{
254}
255
256// remember! This function runs in a separate thread!
257void KResolverThread::run()
258{
259 // initialization
260 // enter the loop already
261
262 //qDebug("KResolverThread(thread %u/%p): started", pid, (void*)QThread::currentThread());
263 KResolverManager::manager()->registerThread(this);
264 while (true)
265 {
266 data = KResolverManager::manager()->requestData(this, ::maxThreadWaitTime);
267 //qDebug("KResolverThread(thread %u/%p) got data %p", KResolverManager::pid,
268 // (void*)QThread::currentThread(), (void*)data);
269 if (data)
270 {
271 // yes, we got data
272 // process it!
273
274 // 1) set up
275 ;
276
277 // 2) run it
278 data->worker->run();
279
280 // 3) release data
281 KResolverManager::manager()->releaseData(this, data);
282
283 // now go back to the loop
284 }
285 else
286 break;
287 }
288
289 KResolverManager::manager()->unregisterThread(this);
290 //qDebug("KResolverThread(thread %u/%p): exiting", pid, (void*)QThread::currentThread());
291}
292
293bool KResolverThread::checkResolver()
294{
295 return resInit.shouldResInit();
296}
297
298void KResolverThread::acquireResolver()
299{
300#if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD)
301 getXXbyYYmutex.lock();
302#endif
303
304 resInit.acquire();
305}
306
307void KResolverThread::releaseResolver()
308{
309#if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD)
310 getXXbyYYmutex.unlock();
311#endif
312
313 resInit.release();
314}
315
316static KResolverManager *globalManager;
317
318KResolverManager* KResolverManager::manager()
319{
320 if (globalManager == 0L)
321 new KResolverManager();
322 return globalManager;
323}
324
325KResolverManager::KResolverManager()
326 : runningThreads(0), availableThreads(0)
327{
328 globalManager = this;
329 initStandardWorkers();
330
331 pid = getpid();
332}
333
334KResolverManager::~KResolverManager()
335{
336 // this should never be called
337
338 // kill off running threads
339 foreach (KResolverThread* worker, workers)
340 worker->terminate();
341}
342
343void KResolverManager::registerThread(KResolverThread* )
344{
345}
346
347void KResolverManager::unregisterThread(KResolverThread*)
348{
349 runningThreads--;
350}
351
352// this function is called by KResolverThread::run
353RequestData* KResolverManager::requestData(KResolverThread *th, int maxWaitTime)
354{
356 // This function is called in a worker thread!!
358
359 // lock the mutex, so that the manager thread or other threads won't
360 // interfere.
361 QMutexLocker locker(&mutex);
362 RequestData *data = findData(th);
363
364 if (data)
365 // it found something, that's good
366 return data;
367
368 // nope, nothing found; sleep for a while
369 availableThreads++;
370 feedWorkers.wait(&mutex, maxWaitTime);
371 availableThreads--;
372
373 data = findData(th);
374 return data;
375}
376
377RequestData* KResolverManager::findData(KResolverThread* th)
378{
380 // This function is called by requestData() above and must
381 // always be called with a locked mutex
383
384 // now find data to be processed
385 QMutableListIterator<RequestData*> it(newRequests);
386 while (it.hasNext())
387 {
388 RequestData *curr = it.next();
389 if (!curr->worker->m_finished)
390 {
391 // found one
392 if (curr->obj)
393 curr->obj->status = KResolver::InProgress;
394 curr->worker->th = th;
395
396 // move it to the currentRequests list
397 it.remove();
398 currentRequests.append(curr);
399
400 return curr;
401 }
402 }
403
404 // found nothing!
405 return 0L;
406}
407
408// this function is called by KResolverThread::run
409void KResolverManager::releaseData(KResolverThread *, RequestData* data)
410{
412 // This function is called in a worker thread!!
414
415 //qDebug("KResolverManager::releaseData(%u/%p): %p has been released", pid,
416// (void*)QThread::currentThread(), (void*)data);
417
418 if (data->obj)
419 {
420 data->obj->status = KResolver::PostProcessing;
421 }
422
423 data->worker->m_finished = true;
424 data->worker->th = 0L; // this releases the object
425
426 // handle finished requests
427 handleFinished();
428}
429
430// this function is called by KResolverManager::releaseData above
431void KResolverManager::handleFinished()
432{
433 bool redo = false;
434 QQueue<RequestData*> doneRequests;
435
436 mutex.lock();
437 if (currentRequests.isEmpty())
438 {
439 mutex.unlock();
440 return;
441 }
442
443 // loop over all items on the currently running list
444 // we loop from the last to the first so that we catch requests
445 // with "requestors" before we catch the requestor itself.
446 QMutableListIterator<RequestData*> it(currentRequests);
447 it.toBack();
448 while (it.hasPrevious())
449 {
450 RequestData *curr = it.previous();
451 if (curr->worker->th == 0L)
452 {
453 if (handleFinishedItem(curr))
454 {
455 it.remove();
456 doneRequests.enqueue(curr);
457
458 if (curr->requestor &&
459 curr->requestor->nRequests == 0 &&
460 curr->requestor->worker->m_finished)
461 // there's a requestor that is now finished
462 redo = true;
463 }
464 }
465 }
466
467 //qDebug("KResolverManager::handleFinished(%u): %d requests to notify", pid, doneRequests.count());
468 while (!doneRequests.isEmpty())
469 doNotifying(doneRequests.dequeue());
470
471 mutex.unlock();
472
473 if (redo)
474 {
475 //qDebug("KResolverManager::handleFinished(%u): restarting processing to catch requestor",
476 // pid);
477 handleFinished();
478 }
479}
480
481// This function is called by KResolverManager::handleFinished above
482bool KResolverManager::handleFinishedItem(RequestData* curr)
483
484{
485 // for all items that aren't currently running, remove from the list
486 // this includes all finished or canceled requests
487
488 if (curr->worker->m_finished && curr->nRequests == 0)
489 {
490 // this one has finished
491 if (curr->obj)
492 curr->obj->status = KResolver::PostProcessing; // post-processing is run in doNotifying()
493
494 if (curr->requestor)
495 --curr->requestor->nRequests;
496
497 //qDebug("KResolverManager::handleFinishedItem(%u): removing %p since it's done",
498 // pid, (void*)curr);
499 return true;
500 }
501 return false;
502}
503
504
505
506void KResolverManager::registerNewWorker(KResolverWorkerFactoryBase *factory)
507{
508 workerFactories.append(factory);
509}
510
511KResolverWorkerBase* KResolverManager::findWorker(KResolverPrivate* p)
512{
514 // this function can be called on any user thread
516
517 // this function is called with an unlocked mutex and it's expected to be
518 // thread-safe!
519 // but the factory list is expected not to be changed asynchronously
520
521 // This function is responsible for finding a suitable worker for the given
522 // input. That means we have to do a costly operation to create each worker
523 // class and call their preprocessing functions. The first one that
524 // says they can process (i.e., preprocess() returns true) will get the job.
525
526 foreach (KResolverWorkerFactoryBase *factory, workerFactories)
527 {
528 KResolverWorkerBase *worker = factory->create();
529
530 // set up the data the worker needs to preprocess
531 worker->input = &p->input;
532
533 if (worker->preprocess())
534 {
535 // good, this one says it can process
536 if (worker->m_finished)
537 p->status = KResolver::PostProcessing;
538 else
539 p->status = KResolver::Queued;
540 return worker;
541 }
542
543 // no, try again
544 delete worker;
545 }
546
547 // found no worker
548 return 0L;
549}
550
551void KResolverManager::doNotifying(RequestData *p)
552{
554 // This function may be called on any thread
555 // any thread at all: user threads, GUI thread, manager thread or worker thread
557
558 // Notification and finalisation
559 //
560 // Once a request has finished the normal processing, we call the
561 // post processing function.
562 //
563 // After that is done, we will consolidate all results in the object's
564 // KResolverResults and then post an event indicating that the signal
565 // be emitted
566 //
567 // In case we detect that the object is waiting for completion, we do not
568 // post the event, for KResolver::wait will take care of emitting the
569 // signal.
570 //
571 // Once we release the mutex on the object, we may no longer reference it
572 // for it might have been deleted.
573
574 // "User" objects are those that are not created by the manager. Note that
575 // objects created by worker threads are considered "user" objects. Objects
576 // created by the manager are those created for KResolver::resolveAsync.
577 // We should delete them.
578
579 if (p->obj)
580 {
581 // lock the object
582 p->obj->mutex.lock();
583 KResolver* parent = p->obj->parent; // is 0 for non-"user" objects
584 KResolverResults& r = p->obj->results;
585
586 if (p->obj->status == KResolver::Canceled)
587 {
588 p->obj->status = KResolver::Canceled;
589 p->obj->errorcode = KResolver::Canceled;
590 p->obj->syserror = 0;
591 r.setError(KResolver::Canceled, 0);
592 }
593 else if (p->worker)
594 {
595 // post processing
596 p->worker->postprocess(); // ignore the result
597
598 // copy the results from the worker thread to the final
599 // object
600 r = p->worker->results;
601
602 // reset address
603 r.setAddress(p->input->node, p->input->service);
604
605 //qDebug("KResolverManager::doNotifying(%u/%p): for %p whose status is %d and has %d results",
606 //pid, (void*)QThread::currentThread(), (void*)p, p->obj->status, r.count());
607
608 p->obj->errorcode = r.error();
609 p->obj->syserror = r.systemError();
610 p->obj->status = !r.isEmpty() ?
611 KResolver::Success : KResolver::Failed;
612 }
613 else
614 {
615 r.empty();
616 r.setError(p->obj->errorcode, p->obj->syserror);
617 }
618
619 // check whether there's someone waiting
620 if (!p->obj->waiting && parent)
621 // no, so we must post an event requesting that the signal be emitted
622 // sorry for the C-style cast, but neither static nor reintepret cast work
623 // here; I'd have to do two casts
624 QCoreApplication::postEvent(parent, new QEvent((QEvent::Type)(ResolutionCompleted)));
625
626 // release the mutex
627 p->obj->mutex.unlock();
628 }
629 else
630 {
631 // there's no object!
632 if (p->worker)
633 p->worker->postprocess();
634 }
635
636 delete p->worker;
637
638 // ignore p->requestor and p->nRequests
639 // they have been dealt with by the main loop
640
641 delete p;
642
643 // notify any objects waiting in KResolver::wait
644 notifyWaiters.wakeAll();
645}
646
647// enqueue a new request
648// this function is called from KResolver::start and
649// from KResolverWorkerBase::enqueue
650void KResolverManager::enqueue(KResolver *obj, RequestData *requestor)
651{
652 RequestData *newrequest = new RequestData;
653 newrequest->nRequests = 0;
654 newrequest->obj = obj->d;
655 newrequest->input = &obj->d->input;
656 newrequest->requestor = requestor;
657
658 // when processing a new request, find the most
659 // suitable worker
660 if ((newrequest->worker = findWorker(obj->d)) == 0L)
661 {
662 // oops, problem
663 // cannot find a worker class for this guy
664 obj->d->status = KResolver::Failed;
665 obj->d->errorcode = KResolver::UnsupportedFamily;
666 obj->d->syserror = 0;
667
668 doNotifying(newrequest);
669 return;
670 }
671
672 // no, queue it
673 // p->status was set in findWorker!
674 if (requestor)
675 requestor->nRequests++;
676
677 if (!newrequest->worker->m_finished)
678 dispatch(newrequest);
679 else if (newrequest->nRequests > 0)
680 {
681 mutex.lock();
682 currentRequests.append(newrequest);
683 mutex.unlock();
684 }
685 else
686 // already done
687 doNotifying(newrequest);
688}
689
690// a new request has been created
691// dispatch it
692void KResolverManager::dispatch(RequestData *data)
693{
694 // As stated in the beginning of the file, this function
695 // is supposed to verify the availability of threads, start
696 // any if necessary
697
698 QMutexLocker locker(&mutex);
699
700 // add to the queue
701 newRequests.append(data);
702
703 // check if we need to start a new thread
704 //
705 // we depend on the variables availableThreads and runningThreads to
706 // know if we are supposed to start any threads:
707 // - if availableThreads > 0, then there is at least one thread waiting,
708 // blocked in KResolverManager::requestData. It can't unblock
709 // while we are holding the mutex locked, therefore we are sure that
710 // our event will be handled
711 // - if availableThreads == 0:
712 // - if runningThreads < maxThreads
713 // we will start a new thread, which will certainly block in
714 // KResolverManager::requestData because we are holding the mutex locked
715 // - if runningThreads == maxThreads
716 // This situation generally means that we have already maxThreads running
717 // and that all of them are processing. We will not start any new threads,
718 // but will instead wait for one to finish processing and request new data
719 //
720 // There's a possible race condition here, which goes unhandled: if one of
721 // threads has timed out waiting for new data and is in the process of
722 // exiting. In that case, availableThreads == 0 and runningThreads will not
723 // have decremented yet. This means that we will not start a new thread
724 // that we could have. However, since there are other threads working, our
725 // event should be handled soon.
726 // It won't be handled if and only if ALL threads are in the process of
727 // exiting. That situation is EXTREMELY unlikely and is not handled either.
728 //
729 if (availableThreads == 0 && runningThreads < maxThreads)
730 {
731 // yes, a new thread should be started
732
733 // find if there's a finished one
734 KResolverThread *th = 0L;
735 for (int i = 0; i < workers.size(); ++i)
736 if (!workers[i]->isRunning())
737 {
738 th = workers[i];
739 break;
740 }
741
742 if (th == 0L)
743 {
744 // no, create one
745 th = new KResolverThread;
746 workers.append(th);
747 }
748
749 th->start();
750 runningThreads++;
751 }
752
753 feedWorkers.wakeAll();
754
755 // clean up idle threads
756 QMutableListIterator<KResolverThread*> it(workers);
757 while (it.hasNext())
758 {
759 KResolverThread *worker = it.next();
760 if (!worker->isRunning())
761 {
762 it.remove();
763 delete worker;
764 }
765 }
766}
767
768// this function is called by KResolverManager::dequeue
769bool KResolverManager::dequeueNew(KResolver* obj)
770{
771 // This function must be called with a locked mutex
772 // Deadlock warning:
773 // always lock the global mutex first if both mutexes must be locked
774
775 KResolverPrivate *d = obj->d;
776
777 // check if it's in the new request list
778 for (QMutableListIterator<RequestData*> it(newRequests);
779 it.hasNext(); )
780 {
781 RequestData *curr = it.next();
782 if (curr->obj == d)
783 {
784 // yes, this object is still in the list
785 // but it has never been processed
786 d->status = KResolver::Canceled;
787 d->errorcode = KResolver::Canceled;
788 d->syserror = 0;
789 it.remove();
790
791 delete curr->worker;
792 delete curr;
793
794 return true;
795 }
796 }
797
798 // check if it's running
799 for (int i = 0; i < currentRequests.size(); ++i)
800 {
801 RequestData* curr = currentRequests[i];
802 if (curr->obj == d)
803 {
804 // it's running. We cannot simply take it out of the list.
805 // it will be handled when the thread that is working on it finishes
806 d->mutex.lock();
807
808 d->status = KResolver::Canceled;
809 d->errorcode = KResolver::Canceled;
810 d->syserror = 0;
811
812 // disengage from the running threads
813 curr->obj = 0L;
814 curr->input = 0L;
815 if (curr->worker)
816 curr->worker->input = 0L;
817
818 d->mutex.unlock();
819 }
820 }
821
822 return false;
823}
824
825// this function is called by KResolver::cancel
826// it's expected to be thread-safe
827void KResolverManager::dequeue(KResolver *obj)
828{
829 QMutexLocker locker(&mutex);
830 dequeueNew(obj);
831}
KNetwork::Internal::KResolverManager
Definition: k3resolver_p.h:157
KNetwork::Internal::KResolverManager::registerThread
void registerThread(KResolverThread *id)
Definition: k3resolvermanager.cpp:343
KNetwork::Internal::KResolverManager::manager
static KResolverManager * manager() KDE_NO_EXPORT
Definition: k3resolvermanager.cpp:318
KNetwork::Internal::KResolverManager::unregisterThread
void unregisterThread(KResolverThread *id)
Definition: k3resolvermanager.cpp:347
KNetwork::Internal::KResolverManager::notifyWaiters
QWaitCondition notifyWaiters
Definition: k3resolver_p.h:168
KNetwork::Internal::KResolverManager::releaseData
void releaseData(KResolverThread *id, RequestData *data)
Definition: k3resolvermanager.cpp:409
KNetwork::Internal::KResolverManager::dispatch
void dispatch(RequestData *data)
Definition: k3resolvermanager.cpp:692
KNetwork::Internal::KResolverManager::enqueue
void enqueue(KNetwork::KResolver *obj, RequestData *requestor)
Definition: k3resolvermanager.cpp:650
KNetwork::Internal::KResolverManager::dequeue
void dequeue(KNetwork::KResolver *obj)
Definition: k3resolvermanager.cpp:827
KNetwork::Internal::KResolverManager::registerNewWorker
void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory)
Definition: k3resolvermanager.cpp:506
KNetwork::Internal::KResolverManager::~KResolverManager
~KResolverManager()
Definition: k3resolvermanager.cpp:334
KNetwork::Internal::KResolverManager::requestData
RequestData * requestData(KResolverThread *id, int maxWaitTime)
Definition: k3resolvermanager.cpp:353
KNetwork::Internal::KResolverManager::ResolutionCompleted
@ ResolutionCompleted
Definition: k3resolver_p.h:160
KNetwork::Internal::KResolverThread
Definition: k3resolver_p.h:329
KNetwork::Internal::KResolverThread::acquireResolver
void acquireResolver()
Definition: k3resolvermanager.cpp:298
KNetwork::Internal::KResolverThread::checkResolver
bool checkResolver()
Definition: k3resolvermanager.cpp:293
KNetwork::Internal::KResolverThread::releaseResolver
void releaseResolver()
Definition: k3resolvermanager.cpp:307
KNetwork::Internal::KResolverThread::run
virtual void run()
Definition: k3resolvermanager.cpp:257
KNetwork::KResolverPrivate
Definition: k3resolver_p.h:102
KNetwork::KResolverPrivate::status
volatile int status
Definition: k3resolver_p.h:110
KNetwork::KResolverPrivate::syserror
volatile int syserror
Definition: k3resolver_p.h:111
KNetwork::KResolverPrivate::parent
KResolver * parent
Definition: k3resolver_p.h:105
KNetwork::KResolverPrivate::results
KResolverResults results
Definition: k3resolver_p.h:120
KNetwork::KResolverPrivate::errorcode
volatile int errorcode
Definition: k3resolver_p.h:111
KNetwork::KResolverPrivate::waiting
bool waiting
Definition: k3resolver_p.h:107
KNetwork::KResolverPrivate::input
Internal::InputData input
Definition: k3resolver_p.h:114
KNetwork::KResolverPrivate::mutex
QMutex mutex
Definition: k3resolver_p.h:117
KNetwork::KResolverResults
Name and service resolution results.
Definition: k3resolver.h:213
KNetwork::KResolverResults::setAddress
void setAddress(const QString &host, const QString &service)
Sets the new nodename and service name.
Definition: k3resolver.cpp:260
KNetwork::KResolverResults::systemError
int systemError() const
Retrieves the system error code, if any.
Definition: k3resolver.cpp:235
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: k3resolver.cpp:229
KNetwork::KResolverResults::setError
void setError(int errorcode, int systemerror=0)
Sets the error codes.
Definition: k3resolver.cpp:241
KNetwork::KResolverWorkerBase
Definition: k3resolverworkerbase.h:65
KNetwork::KResolverWorkerBase::run
virtual bool run()=0
This is the function that should be overridden in derived classes.
KNetwork::KResolverWorkerBase::results
KResolverResults results
Derived classes will put their resolved data in this list, or will leave it empty in case of error.
Definition: k3resolverworkerbase.h:128
KNetwork::KResolverWorkerBase::postprocess
virtual bool postprocess()
This function gets called during post processing for this class.
Definition: k3resolverworkerbase.cpp:105
KNetwork::KResolverWorkerBase::preprocess
virtual bool preprocess()=0
This function gets called during pre processing for this class and you must override it.
KNetwork::KResolverWorkerFactoryBase
Definition: k3resolverworkerbase.h:292
KNetwork::KResolverWorkerFactoryBase::create
virtual KResolverWorkerBase * create() const =0
KNetwork::KResolver
Name and service resolution class.
Definition: k3resolver.h:313
KNetwork::KResolver::Canceled
@ Canceled
Definition: k3resolver.h:412
KNetwork::KResolver::UnsupportedFamily
@ UnsupportedFamily
Definition: k3resolver.h:407
KNetwork::KResolver::Queued
@ Queued
Definition: k3resolver.h:438
KNetwork::KResolver::InProgress
@ InProgress
Definition: k3resolver.h:439
KNetwork::KResolver::Success
@ Success
Definition: k3resolver.h:441
KNetwork::KResolver::Failed
@ Failed
Definition: k3resolver.h:443
KNetwork::KResolver::PostProcessing
@ PostProcessing
Definition: k3resolver.h:440
kDebug
#define kDebug
Definition: kdebug.h:316
getXXbyYYmutex
QMutex getXXbyYYmutex
Definition: k3resolver.cpp:64
k3resolver.h
k3resolver_p.h
maxThreadWaitTime
static const int maxThreadWaitTime
Definition: k3resolvermanager.cpp:246
globalManager
static KResolverManager * globalManager
Definition: k3resolvermanager.cpp:316
maxThreads
static const int maxThreads
Definition: k3resolvermanager.cpp:247
pid
static pid_t pid
Definition: k3resolvermanager.cpp:249
k3resolverstandardworkers_p.h
k3resolverworkerbase.h
kdebug.h
KNetwork::Internal
Definition: k3resolver.h:48
KNetwork::Internal::initStandardWorkers
void initStandardWorkers() KDE_NO_EXPORT
Definition: k3resolverstandardworkers.cpp:1038
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: k3bufferedsocket.h:35
KNetwork::Internal::InputData::service
QString service
Definition: k3resolver_p.h:92
KNetwork::Internal::InputData::node
QString node
Definition: k3resolver_p.h:92
KNetwork::Internal::RequestData
Definition: k3resolver_p.h:142
KNetwork::Internal::RequestData::obj
KNetwork::KResolverPrivate * obj
Definition: k3resolver_p.h:144
KNetwork::Internal::RequestData::input
const KNetwork::Internal::InputData * input
Definition: k3resolver_p.h:145
KNetwork::Internal::RequestData::requestor
RequestData * requestor
Definition: k3resolver_p.h:147
KNetwork::Internal::RequestData::nRequests
volatile int nRequests
Definition: k3resolver_p.h:149
KNetwork::Internal::RequestData::worker
KNetwork::KResolverWorkerBase * worker
Definition: k3resolver_p.h:146
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal