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

KDECore

  • sources
  • kde-4.12
  • kdelibs
  • 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>
35 extern "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 
61 using namespace KNetwork;
62 using 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 
110 namespace
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  */
123 class ResInitUsage
124 {
125 public:
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
246 static const int maxThreadWaitTime = 2000; // 2 seconds
247 static const int maxThreads = 5;
248 
249 static pid_t pid; // FIXME -- disable when everything is ok
250 
251 KResolverThread::KResolverThread()
252  : data(0L)
253 {
254 }
255 
256 // remember! This function runs in a separate thread!
257 void 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 
293 bool KResolverThread::checkResolver()
294 {
295  return resInit.shouldResInit();
296 }
297 
298 void KResolverThread::acquireResolver()
299 {
300 #if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD)
301  getXXbyYYmutex.lock();
302 #endif
303 
304  resInit.acquire();
305 }
306 
307 void KResolverThread::releaseResolver()
308 {
309 #if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD)
310  getXXbyYYmutex.unlock();
311 #endif
312 
313  resInit.release();
314 }
315 
316 static KResolverManager *globalManager;
317 
318 KResolverManager* KResolverManager::manager()
319 {
320  if (globalManager == 0L)
321  new KResolverManager();
322  return globalManager;
323 }
324 
325 KResolverManager::KResolverManager()
326  : runningThreads(0), availableThreads(0)
327 {
328  globalManager = this;
329  initStandardWorkers();
330 
331  pid = getpid();
332 }
333 
334 KResolverManager::~KResolverManager()
335 {
336  // this should never be called
337 
338  // kill off running threads
339  foreach (KResolverThread* worker, workers)
340  worker->terminate();
341 }
342 
343 void KResolverManager::registerThread(KResolverThread* )
344 {
345 }
346 
347 void KResolverManager::unregisterThread(KResolverThread*)
348 {
349  runningThreads--;
350 }
351 
352 // this function is called by KResolverThread::run
353 RequestData* 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 
377 RequestData* 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
409 void 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
431 void 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
482 bool 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 
506 void KResolverManager::registerNewWorker(KResolverWorkerFactoryBase *factory)
507 {
508  workerFactories.append(factory);
509 }
510 
511 KResolverWorkerBase* 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 
551 void 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
650 void 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
692 void 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
769 bool 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
827 void KResolverManager::dequeue(KResolver *obj)
828 {
829  QMutexLocker locker(&mutex);
830  dequeueNew(obj);
831 }
k3resolverworkerbase.h
KNetwork::KResolverPrivate::waiting
bool waiting
Definition: k3resolver_p.h:107
KFileSystemType::Type
Type
Definition: kfilesystemtype_p.h:28
kdebug.h
KNetwork::KResolverWorkerFactoryBase::create
virtual KResolverWorkerBase * create() const =0
KNetwork::Internal::KResolverManager::releaseData
void releaseData(KResolverThread *id, RequestData *data)
Definition: k3resolvermanager.cpp:409
KNetwork::KResolver::UnsupportedFamily
Definition: k3resolver.h:407
KNetwork::KResolverPrivate::parent
KResolver * parent
Definition: k3resolver_p.h:105
KNetwork::Internal::initStandardWorkers
void initStandardWorkers() KDE_NO_EXPORT
Definition: k3resolverstandardworkers.cpp:1038
getXXbyYYmutex
QMutex getXXbyYYmutex
Definition: k3resolver.cpp:64
KNetwork::KResolver
Name and service resolution class.
Definition: k3resolver.h:312
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::Internal::InputData::node
QString node
Definition: k3resolver_p.h:92
KNetwork::Internal::KResolverManager::registerThread
void registerThread(KResolverThread *id)
Definition: k3resolvermanager.cpp:343
pid
static pid_t pid
Definition: k3resolvermanager.cpp:249
KNetwork::KResolverResults
Name and service resolution results.
Definition: k3resolver.h:212
KNetwork::KResolverPrivate
Definition: k3resolver_p.h:101
KNetwork::Internal::RequestData::nRequests
volatile int nRequests
Definition: k3resolver_p.h:149
KNetwork::KResolver::PostProcessing
Definition: k3resolver.h:440
KNetwork::Internal::RequestData::obj
KNetwork::KResolverPrivate * obj
Definition: k3resolver_p.h:144
KNetwork::Internal::KResolverManager::unregisterThread
void unregisterThread(KResolverThread *id)
Definition: k3resolvermanager.cpp:347
KNetwork::KResolverPrivate::status
volatile int status
Definition: k3resolver_p.h:110
KNetwork::KResolver::Failed
Definition: k3resolver.h:443
KNetwork::KResolverPrivate::results
KResolverResults results
Definition: k3resolver_p.h:120
KNetwork::KResolverPrivate::syserror
volatile int syserror
Definition: k3resolver_p.h:111
KNetwork::Internal::KResolverManager::~KResolverManager
~KResolverManager()
Definition: k3resolvermanager.cpp:334
KNetwork::KResolverResults::systemError
int systemError() const
Retrieves the system error code, if any.
Definition: k3resolver.cpp:235
KNetwork::Internal::KResolverThread
Definition: k3resolver_p.h:328
KNetwork::Internal::KResolverManager::notifyWaiters
QWaitCondition notifyWaiters
Definition: k3resolver_p.h:168
KNetwork::Internal::InputData::service
QString service
Definition: k3resolver_p.h:92
KNetwork::KResolver::Queued
Definition: k3resolver.h:438
KNetwork::Internal::KResolverManager
Definition: k3resolver_p.h:156
KNetwork::Internal::RequestData::requestor
RequestData * requestor
Definition: k3resolver_p.h:147
KNetwork::KResolver::InProgress
Definition: k3resolver.h:439
k3resolverstandardworkers_p.h
KNetwork::KResolverWorkerBase::run
virtual bool run()=0
This is the function that should be overridden in derived classes.
KNetwork::Internal::KResolverManager::manager
static KResolverManager * manager() KDE_NO_EXPORT
Definition: k3resolvermanager.cpp:318
k3resolver.h
KNetwork::Internal::KResolverManager::dispatch
void dispatch(RequestData *data)
Definition: k3resolvermanager.cpp:692
KNetwork::Internal::RequestData::input
const KNetwork::Internal::InputData * input
Definition: k3resolver_p.h:145
KNetwork::Internal::KResolverManager::ResolutionCompleted
Definition: k3resolver_p.h:160
maxThreadWaitTime
static const int maxThreadWaitTime
Definition: k3resolvermanager.cpp:246
KNetwork::Internal::KResolverManager::requestData
RequestData * requestData(KResolverThread *id, int maxWaitTime)
Definition: k3resolvermanager.cpp:353
KNetwork::Internal::KResolverManager::registerNewWorker
void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory)
Definition: k3resolvermanager.cpp:506
KNetwork::Internal::KResolverThread::checkResolver
bool checkResolver()
Definition: k3resolvermanager.cpp:293
KNetwork::Internal::RequestData
Definition: k3resolver_p.h:141
KNetwork::Internal::KResolverManager::enqueue
void enqueue(KNetwork::KResolver *obj, RequestData *requestor)
Definition: k3resolvermanager.cpp:650
KNetwork::KResolverPrivate::errorcode
volatile int errorcode
Definition: k3resolver_p.h:111
KNetwork::KResolverPrivate::mutex
QMutex mutex
Definition: k3resolver_p.h:117
KNetwork::KResolverPrivate::input
Internal::InputData input
Definition: k3resolver_p.h:114
KNetwork::Internal::KResolverThread::acquireResolver
void acquireResolver()
Definition: k3resolvermanager.cpp:298
KNetwork::KResolverResults::setAddress
void setAddress(const QString &host, const QString &service)
Sets the new nodename and service name.
Definition: k3resolver.cpp:260
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...
kDebug
#define kDebug
Definition: kdebug.h:316
KNetwork::KResolver::Canceled
Definition: k3resolver.h:412
KNetwork::KResolverResults::setError
void setError(int errorcode, int systemerror=0)
Sets the error codes.
Definition: k3resolver.cpp:241
KNetwork::Internal::KResolverManager::dequeue
void dequeue(KNetwork::KResolver *obj)
Definition: k3resolvermanager.cpp:827
KNetwork::Internal::RequestData::worker
KNetwork::KResolverWorkerBase * worker
Definition: k3resolver_p.h:146
KNetwork::KResolverWorkerBase
Definition: k3resolverworkerbase.h:64
globalManager
static KResolverManager * globalManager
Definition: k3resolvermanager.cpp:316
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: k3resolver.cpp:229
KNetwork::KResolverWorkerFactoryBase
Definition: k3resolverworkerbase.h:291
KNetwork::Internal::KResolverThread::releaseResolver
void releaseResolver()
Definition: k3resolvermanager.cpp:307
k3resolver_p.h
maxThreads
static const int maxThreads
Definition: k3resolvermanager.cpp:247
KNetwork::KResolver::Success
Definition: k3resolver.h:441
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:07 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



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