ctkEAInterruptibleThread_p.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef CTKEAINTERRUPTIBLETHREAD_P_H
  16. #define CTKEAINTERRUPTIBLETHREAD_P_H
  17. #include <QThread>
  18. #include <QWaitCondition>
  19. #include <QMutex>
  20. #include <QAtomicInt>
  21. #include <QRunnable>
  22. /**
  23. * A QRunnable subclass with simple reference counting.
  24. */
  25. class ctkEARunnable : public QRunnable
  26. {
  27. public:
  28. int ref;
  29. ctkEARunnable() : ref(0) {}
  30. bool autoDelete() const { return ref != -1; }
  31. void setAutoDelete(bool autoDelete) { ref = autoDelete ? 0 : -1; }
  32. };
  33. class ctkEAScopedRunnableReference
  34. {
  35. public:
  36. ctkEAScopedRunnableReference(ctkEARunnable* runnable)
  37. : runnable(runnable)
  38. {
  39. ++runnable->ref;
  40. }
  41. ~ctkEAScopedRunnableReference()
  42. {
  43. if (!--runnable->ref) delete runnable;
  44. }
  45. private:
  46. ctkEARunnable* runnable;
  47. };
  48. /**
  49. * A QThread subclass which can be interrupted when waiting
  50. * on a wait condition.
  51. */
  52. class ctkEAInterruptibleThread : public QThread, public QMutex
  53. {
  54. Q_OBJECT
  55. public:
  56. /**
  57. * Creates a new interruptible thread object. If <code>command</code>
  58. * is not null, it's run() method will be executed when the thread
  59. * is started.
  60. *
  61. * @param command The runnable to run when starting this thread.
  62. * @param parent The parent object.
  63. * @see run()
  64. */
  65. ctkEAInterruptibleThread(ctkEARunnable* command = 0, QObject* parent = 0);
  66. /**
  67. * Returns a pointer to the currently executing interruptible
  68. * thread object.
  69. *
  70. * @return The currently executing ctkEAInterruptibleThread object
  71. */
  72. static ctkEAInterruptibleThread* currentThread();
  73. /**
  74. * Waits on the wait condition <code>waitCond</code> for the specified
  75. * amount of msecs <code>time</code> until another thread invokes the
  76. * wake() or wakeAll() method on the given wait condition.
  77. * If <code>time</code> is ULONG_MAX
  78. * or 0, this method waits forever (unless interrupted).
  79. *
  80. * <p>
  81. * The given <code>mutex</code> must be locked prior to calling this method.
  82. * This method will unlock the mutex and wait on the wait condition. After
  83. * returning, the mutex will be in its original state.
  84. *
  85. * @see interrupt()
  86. */
  87. void wait(QMutex* mutex, QWaitCondition* waitCond, unsigned long time = ULONG_MAX);
  88. /**
  89. * Waits for this thread to finish execution.
  90. */
  91. void join();
  92. /**
  93. * Interrupts this thread.
  94. *
  95. * <p>
  96. * If this thread is blocked in an invocation of the wait() method, then its
  97. * interrupt status will be cleared and it will receive a ctkEAInterruptedException.
  98. * Otherwise this thread's interrupt status will be set.
  99. */
  100. void interrupt();
  101. /**
  102. * Tests whether the current thread has been interrupted. The interrupted status
  103. * of the thread is cleared by this method. In other words, if this method
  104. * were to be called twice in succession, the second call would return false
  105. * (unless the current thread were interrupted again, after the first call had
  106. * cleared its interrupted status and before the second call had examined it).
  107. *
  108. * @return <code>true</code> if the current thread has been interrupted;
  109. * <code>false</code> otherwise.
  110. */
  111. static bool interrupted();
  112. /**
  113. * Tests whether this thread has been interrupted. The interrupted status
  114. * of the thread is unaffected by this method.
  115. *
  116. * @return <code>true</code> if this thread has been interrupted;
  117. * <code>false</code> otherwise.
  118. */
  119. bool isInterrupted() const;
  120. /**
  121. * If this thread was constructed using a separate ctkEARunnable run object,
  122. * then that ctkEARunnable object's run method is called; otherwise, this
  123. * method calls QThread::run() which will start a local event loop.
  124. */
  125. void run();
  126. private:
  127. ctkEARunnable* command;
  128. bool deleteCmd;
  129. QAtomicPointer<QWaitCondition> currWaitCond_;
  130. mutable QAtomicInt interrupted_;
  131. mutable QAtomicInt isWaiting_;
  132. };
  133. #endif // CTKEAINTERRUPTIBLETHREAD_P_H