root/OpenSceneGraph/trunk/src/OpenThreads/qt/QtThread.cpp @ 13482

Revision 13482, 11.4 kB (checked in by robert, 6 hours ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007  The Open Thread Group
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14//
15// QtThread.cpp - C++ Thread class built on top of Qt threads.
16// ~~~~~~~~~~~
17
18#include "QtThreadPrivateData.h"
19#include <QCoreApplication>
20#include <iostream>
21
22using namespace OpenThreads;
23
24//-----------------------------------------------------------------------------
25// Initialize thread master priority level
26//
27Thread::ThreadPriority Thread::s_masterThreadPriority = Thread::THREAD_PRIORITY_DEFAULT;
28bool Thread::s_isInitialized = false;
29
30//----------------------------------------------------------------------------
31//
32// Description: Set the concurrency level (no-op)
33//
34// Use static public
35//
36int Thread::SetConcurrency(int concurrencyLevel)
37{ return -1; }
38
39//----------------------------------------------------------------------------
40//
41// Description: Get the concurrency level
42//
43// Use static public
44//
45int Thread::GetConcurrency()
46{ return -1; }
47
48//----------------------------------------------------------------------------
49//
50// Decription: Constructor
51//
52// Use: public.
53//
54Thread::Thread()
55{
56    if (!s_isInitialized) Init();
57   
58    QtThreadPrivateData* pd = new QtThreadPrivateData(this);
59    pd->isRunning = false;
60    pd->detached = false;
61    pd->cancelled = false;
62    pd->cancelMode = 0;
63    pd->uniqueId = QtThreadPrivateData::createUniqueID();
64    pd->cpunum = -1;
65    pd->stackSize = 0;
66    pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;
67    pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;
68   
69    _prvData = static_cast<void*>(pd);
70}
71
72//----------------------------------------------------------------------------
73//
74// Description: Destructor
75//
76// Use: public.
77//
78Thread::~Thread()
79{
80    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
81    if (pd->isRunning)
82    {
83        std::cout<<"Error: Thread "<< this <<" still running in destructor"<<std::endl;
84        cancel();
85    }
86    delete pd;
87    _prvData = 0;
88}
89
90Thread* Thread::CurrentThread()
91{
92    if (!s_isInitialized) Thread::Init();
93   
94    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(QThread::currentThread());
95    return (pd ? pd->getMasterThread() : 0);
96}
97
98//-----------------------------------------------------------------------------
99//
100// Description: Initialize Threading
101//
102// Use: public.
103//
104void Thread::Init()
105{
106    s_isInitialized = true;
107}
108
109//-----------------------------------------------------------------------------
110//
111// Description: Get a unique identifier for this thread.
112//
113// Use: public
114//
115int Thread::getThreadId()
116{
117    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
118    return pd->uniqueId;
119}
120
121//-----------------------------------------------------------------------------
122//
123// Description: Get the thread's process id
124//
125// Use: public
126//
127size_t Thread::getProcessId()
128{
129    return (size_t)QCoreApplication::applicationPid();
130}
131
132//-----------------------------------------------------------------------------
133//
134// Description: Determine if the thread is running
135//
136// Use: public
137//
138bool Thread::isRunning()
139{
140    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
141    return pd->isRunning;
142}
143
144//-----------------------------------------------------------------------------
145//
146// Description: Start the thread.
147//
148// Use: public
149//
150int Thread::start()
151{
152    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
153    pd->threadStartedBlock.reset();
154   
155    pd->setStackSize( pd->stackSize );
156    pd->start();
157   
158    // wait till the thread has actually started.
159    pd->threadStartedBlock.block();
160    return 0;
161}
162
163//-----------------------------------------------------------------------------
164//
165// Description: Alternate thread start routine.
166//
167// Use: public
168//
169int Thread::startThread()
170{
171    if (_prvData) return start();
172    else return 0;
173}
174
175//-----------------------------------------------------------------------------
176//
177// Description: Join the thread.
178//
179// Use: public
180//
181int Thread::detach()
182{
183    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
184    pd->detached = true;
185    return 0;
186}
187
188//-----------------------------------------------------------------------------
189//
190// Description: Join the thread.
191//
192// Use: public
193//
194int Thread::join()
195{
196    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
197    if (pd->detached) return -1;
198    return pd->wait() ? 0 : -1;
199}
200
201//-----------------------------------------------------------------------------
202//
203// Description: test the cancel state of the thread.
204//
205// Use: public
206//
207int Thread::testCancel()
208{
209    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
210    if (!pd->cancelled)
211        return 0;
212   
213    if (pd->cancelMode == 2)
214        return -1;
215   
216    if (pd!=QThread::currentThread())
217        return -1;
218   
219    throw QtThreadCanceled();
220}
221
222//-----------------------------------------------------------------------------
223//
224// Description: Cancel the thread.
225//
226// Use: public
227//
228int Thread::cancel()
229{
230    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
231    if (pd->isRunning)
232    {
233        if (pd->cancelMode == 2)
234            return -1;
235       
236        pd->cancelled = true;
237        if (pd->cancelMode == 1)
238        {
239            pd->isRunning = false;
240            pd->terminate();
241        }
242    }
243    return 0;
244}
245
246//-----------------------------------------------------------------------------
247//
248// Description: set the thread to cancel at the next convenient point.
249//
250// Use: public
251//
252int Thread::setCancelModeDeferred()
253{
254    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
255    pd->cancelMode = 0;
256    pd->setAsynchronousTermination(false);
257    return 0;
258}
259
260//-----------------------------------------------------------------------------
261//
262// Description: set the thread to cancel immediately
263//
264// Use: public
265//
266int Thread::setCancelModeAsynchronous()
267{
268    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
269    pd->cancelMode = 1;
270    pd->setAsynchronousTermination(true);
271    return 0;
272}
273
274//-----------------------------------------------------------------------------
275//
276// Description: Disable cancelibility
277//
278// Use: public
279//
280int Thread::setCancelModeDisable()
281{
282    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
283    pd->cancelMode = 2;
284    return 0;
285}
286
287//-----------------------------------------------------------------------------
288//
289// Description: Set the thread's schedule priority (if able)
290//
291// Use: public
292//
293int Thread::setSchedulePriority(ThreadPriority priority)
294{
295    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
296    pd->threadPriority = priority;
297   
298    if (pd->isRunning)
299        pd->applyPriority();
300    return 0;
301}
302
303//-----------------------------------------------------------------------------
304//
305// Description: Get the thread's schedule priority (if able)
306//
307// Use: public
308//
309int Thread::getSchedulePriority()
310{
311    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
312    return pd->threadPriority;
313}
314
315//-----------------------------------------------------------------------------
316//
317// Description: Set the thread's scheduling policy (if able)
318//
319// Use: public
320//
321int Thread::setSchedulePolicy(ThreadPolicy policy)
322{
323    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
324    pd->threadPolicy = policy;
325    return 0;
326}
327
328//-----------------------------------------------------------------------------
329//
330// Description: Set the thread's scheduling policy (if able)
331//
332// Use: public
333//
334int Thread::getSchedulePolicy()
335{
336    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
337    return pd->threadPolicy;
338}
339
340//-----------------------------------------------------------------------------
341//
342// Description: Set the thread's desired stack size
343//
344// Use: public
345//
346int Thread::setStackSize(size_t stackSize)
347{
348    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
349    if (pd->isRunning) return 13;  // return EACESS
350    else pd->stackSize = stackSize;
351    return 0;
352}
353
354//-----------------------------------------------------------------------------
355//
356// Description: Get the thread's stack size.
357//
358// Use: public
359//
360size_t Thread::getStackSize()
361{
362    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
363    return pd->stackSize;
364}
365
366//-----------------------------------------------------------------------------
367//
368// Description:  set processor affinity for the thread
369//
370// Use: public
371//
372int Thread::setProcessorAffinity(unsigned int cpunum)
373{
374    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
375    pd->cpunum = cpunum;
376    if (!pd->isRunning) return 0;
377   
378    // FIXME:
379    // Qt doesn't have a platform-independent thread affinity method at present.
380    // Does it automatically configure threads on different processors, or we have to do it ourselves?
381    return -1;
382}
383
384//-----------------------------------------------------------------------------
385//
386// Description:  Print the thread's scheduling information to stdout.
387//
388// Use: public
389//
390void Thread::printSchedulingInfo()
391{
392    QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
393    std::cout << "Thread "<< pd->getMasterThread() <<" priority: ";
394   
395    switch (pd->threadPriority)
396    {
397    case Thread::THREAD_PRIORITY_MAX:
398        std::cout << "MAXIMAL" << std::endl;
399        break;
400    case Thread::THREAD_PRIORITY_HIGH:
401        std::cout << "HIGH" << std::endl;
402        break;
403    case Thread::THREAD_PRIORITY_DEFAULT:
404    case Thread::THREAD_PRIORITY_NOMINAL:
405        std::cout << "NORMAL" << std::endl;
406        break;
407    case Thread::THREAD_PRIORITY_LOW:
408        std::cout << "LOW" << std::endl;
409        break;
410    case Thread::THREAD_PRIORITY_MIN:
411        std::cout << "MINIMAL" << std::endl;
412        break;
413    }
414}
415
416//-----------------------------------------------------------------------------
417//
418// Description:  Yield the processor
419//
420// Use: protected
421//
422int Thread::YieldCurrentThread()
423{
424    QThread::yieldCurrentThread();
425    return 0;
426}
427
428//-----------------------------------------------------------------------------
429//
430// Description:  sleep
431//
432// Use: public
433//
434int Thread::microSleep(unsigned int microsec)
435{
436    QtThreadPrivateData::microSleep(microsec);
437    return 0;
438}
439
440//-----------------------------------------------------------------------------
441//
442// Description:  Get the number of processors
443//
444int OpenThreads::GetNumberOfProcessors()
445{
446    return QThread::idealThreadCount();
447}
448
449//-----------------------------------------------------------------------------
450//
451// Description:  set processor affinity for current thread
452//
453int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
454{
455    if (cpunum<0) return -1;
456   
457    Thread::Init();
458    Thread* thread = Thread::CurrentThread();
459    if (thread)
460        return thread->setProcessorAffinity(cpunum);
461    else
462        return -1;
463}
Note: See TracBrowser for help on using the browser.