Qt 4.8
Macros | Functions | Variables
qthread_win.cpp File Reference
#include "qthread.h"
#include "qthread_p.h"
#include "qthreadstorage.h"
#include "qmutex.h"
#include <qcoreapplication.h>
#include <qpointer.h>
#include <private/qcoreapplication_p.h>
#include <private/qeventdispatcher_win_p.h>
#include <qt_windows.h>
#include "qfunctions_wince.h"

Go to the source code of this file.

Macros

#define _WIN32_WINNT   0x0400
 

Functions

DWORD WINAPI qt_adopted_thread_watcher_function (LPVOID)
 This function loops and waits for native adopted threads to finish. More...
 
void qt_create_tls ()
 Initializes the QThread system. More...
 
static void qt_free_tls ()
 
void qt_watch_adopted_thread (const HANDLE adoptedThreadHandle, QThread *qthread)
 Adds an adopted thread to the list of threads that Qt watches to make sure the thread data is properly cleaned up. More...
 

Variables

static QVector< QThread * > qt_adopted_qthreads
 
static QVector< HANDLE > qt_adopted_thread_handles
 
static HANDLE qt_adopted_thread_wakeup = 0
 
static DWORD qt_adopted_thread_watcher_id = 0
 
static QMutex qt_adopted_thread_watcher_mutex
 
static DWORD qt_current_thread_data_tls_index = TLS_OUT_OF_INDEXES
 

Macro Definition Documentation

◆ _WIN32_WINNT

#define _WIN32_WINNT   0x0400

Definition at line 44 of file qthread_win.cpp.

Function Documentation

◆ qt_adopted_thread_watcher_function()

DWORD WINAPI qt_adopted_thread_watcher_function ( LPVOID  )

This function loops and waits for native adopted threads to finish.

Warning
This function is not part of the public interface.

When this happens it derefs the QThreadData for the adopted thread to make sure it gets cleaned up properly.

Definition at line 211 of file qthread_win.cpp.

Referenced by qt_watch_adopted_thread().

212 {
213  forever {
215 
216  if (qt_adopted_thread_handles.count() == 1) {
219  break;
220  }
221 
224 
225  DWORD ret = WAIT_TIMEOUT;
226  int count;
227  int offset;
228  int loops = handlesCopy.size() / MAXIMUM_WAIT_OBJECTS;
229  if (handlesCopy.size() % MAXIMUM_WAIT_OBJECTS)
230  ++loops;
231  if (loops == 1) {
232  // no need to loop, no timeout
233  offset = 0;
234  count = handlesCopy.count();
235  ret = WaitForMultipleObjects(handlesCopy.count(), handlesCopy.constData(), false, INFINITE);
236  } else {
237  int loop = 0;
238  do {
239  offset = loop * MAXIMUM_WAIT_OBJECTS;
240  count = qMin(handlesCopy.count() - offset, MAXIMUM_WAIT_OBJECTS);
241  ret = WaitForMultipleObjects(count, handlesCopy.constData() + offset, false, 100);
242  loop = (loop + 1) % loops;
243  } while (ret == WAIT_TIMEOUT);
244  }
245 
246  if (ret == WAIT_FAILED || ret >= WAIT_OBJECT_0 + uint(count)) {
247  qWarning("QThread internal error while waiting for adopted threads: %d", int(GetLastError()));
248  continue;
249  }
250 
251  const int handleIndex = offset + ret - WAIT_OBJECT_0;
252  if (handleIndex == 0){
253  // New handle to watch was added.
254  continue;
255  } else {
256 // printf("(qt) - qt_adopted_thread_watcher_function... called\n");
257  const int qthreadIndex = handleIndex - 1;
258 
262  if (data->isAdopted) {
263  QThread *thread = data->thread;
264  Q_ASSERT(thread);
265  QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
266  Q_ASSERT(!thread_p->finished);
267  thread_p->finish(thread);
268  }
269  data->deref();
270 
272 #if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
273  CloseHandle(qt_adopted_thread_handles.at(handleIndex));
274 #endif
275  qt_adopted_thread_handles.remove(handleIndex);
276  qt_adopted_qthreads.remove(qthreadIndex);
277  }
278  }
279 
280  QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index));
281  if (threadData)
282  threadData->deref();
283 
284  return 0;
285 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
void lock()
Locks the mutex.
Definition: qmutex.cpp:151
void remove(int i)
Removes the element at index position i.
Definition: qvector.h:374
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
bool isAdopted
Definition: qthread_p.h:269
static DWORD qt_current_thread_data_tls_index
Definition: qthread_win.cpp:77
static QMutex qt_adopted_thread_watcher_mutex
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define WAIT_OBJECT_0
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
void deref()
Definition: qthread.cpp:125
static QThreadData * get2(QThread *thread)
Definition: qthread_p.h:219
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
static QVector< HANDLE > qt_adopted_thread_handles
void unlock()
Unlocks the mutex.
Definition: qmutex.cpp:296
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
static void finish(void *)
QThread * thread
Definition: qthread_p.h:260
The QThread class provides a platform-independent way to manage threads.
Definition: qthread.h:59
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
static DWORD qt_adopted_thread_watcher_id
static QVector< QThread * > qt_adopted_qthreads
#define forever
This macro is provided for convenience for writing infinite loops.
Definition: qglobal.h:2452

◆ qt_create_tls()

void qt_create_tls ( )

Initializes the QThread system.

Warning
This function is not part of the public interface.

Definition at line 78 of file qthread_win.cpp.

Referenced by QThread::initialize(), qt_adopted_thread_watcher_function(), and qt_free_tls().

79 {
81  return;
82  static QMutex mutex;
83  QMutexLocker locker(&mutex);
85 }
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
static DWORD qt_current_thread_data_tls_index
Definition: qthread_win.cpp:77
#define TLS_OUT_OF_INDEXES
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101

◆ qt_free_tls()

static void qt_free_tls ( )
static

Definition at line 87 of file qthread_win.cpp.

88 {
92  }
93 }
static DWORD qt_current_thread_data_tls_index
Definition: qthread_win.cpp:77
#define TLS_OUT_OF_INDEXES

◆ qt_watch_adopted_thread()

void qt_watch_adopted_thread ( const HANDLE  adoptedThreadHandle,
QThread qthread 
)

Adds an adopted thread to the list of threads that Qt watches to make sure the thread data is properly cleaned up.

Warning
This function is not part of the public interface. This function starts the watcher thread if necessary.

Definition at line 176 of file qthread_win.cpp.

Referenced by qt_free_tls().

177 {
179 
180  if (GetCurrentThreadId() == qt_adopted_thread_watcher_id) {
181 #if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
182  CloseHandle(adoptedThreadHandle);
183 #endif
184  return;
185  }
186 
187  qt_adopted_thread_handles.append(adoptedThreadHandle);
188  qt_adopted_qthreads.append(qthread);
189 
190  // Start watcher thread if it is not already running.
191  if (qt_adopted_thread_watcher_id == 0) {
192  if (qt_adopted_thread_wakeup == 0) {
193  qt_adopted_thread_wakeup = CreateEvent(0, false, false, 0);
195  }
196 
198  } else {
199  SetEvent(qt_adopted_thread_wakeup);
200  }
201 }
static QMutex qt_adopted_thread_watcher_mutex
DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
This function loops and waits for native adopted threads to finish.
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
static QVector< HANDLE > qt_adopted_thread_handles
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static QReadWriteLock lock
Definition: proxyconf.cpp:399
static HANDLE qt_adopted_thread_wakeup
void prepend(const T &t)
Inserts value at the beginning of the vector.
Definition: qvector.h:378
static DWORD qt_adopted_thread_watcher_id
static QVector< QThread * > qt_adopted_qthreads

Variable Documentation

◆ qt_adopted_qthreads

QVector<QThread *> qt_adopted_qthreads
static

Definition at line 163 of file qthread_win.cpp.

◆ qt_adopted_thread_handles

QVector<HANDLE> qt_adopted_thread_handles
static

Definition at line 162 of file qthread_win.cpp.

Referenced by qt_adopted_thread_watcher_function().

◆ qt_adopted_thread_wakeup

HANDLE qt_adopted_thread_wakeup = 0
static

Definition at line 166 of file qthread_win.cpp.

Referenced by qt_watch_adopted_thread().

◆ qt_adopted_thread_watcher_id

DWORD qt_adopted_thread_watcher_id = 0
static

Definition at line 165 of file qthread_win.cpp.

Referenced by qt_adopted_thread_watcher_function(), and qt_watch_adopted_thread().

◆ qt_adopted_thread_watcher_mutex

QMutex qt_adopted_thread_watcher_mutex
static

Definition at line 164 of file qthread_win.cpp.

◆ qt_current_thread_data_tls_index

DWORD qt_current_thread_data_tls_index = TLS_OUT_OF_INDEXES
static

Definition at line 77 of file qthread_win.cpp.

Referenced by qt_adopted_thread_watcher_function(), qt_create_tls(), and qt_free_tls().