Added (and documented :) optional stack size specification for wxThread.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13322 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Ron Lee
2002-01-03 05:53:39 +00:00
parent f882d57e93
commit 6fe7378863
6 changed files with 365 additions and 356 deletions

View File

@@ -74,10 +74,12 @@ stack.
\membersection{wxThread::Create}\label{wxthreadcreate} \membersection{wxThread::Create}\label{wxthreadcreate}
\func{wxThreadError}{Create}{\void} \func{wxThreadError}{Create}{\param{unsigned int }{stackSize = 0}}
Creates a new thread. The thread object is created in the suspended state, and you Creates a new thread. The thread object is created in the suspended state, and you
should call \helpref{Run}{wxthreadrun} to start running it. should call \helpref{Run}{wxthreadrun} to start running it. You may optionally
specify the stack size to be allocated to it (Ignored on platforms that don't
support setting it explicitly, eg. Unix).
\wxheading{Return value} \wxheading{Return value}

View File

@@ -303,8 +303,15 @@ public:
// from _another_ thread (typically the thread that created this one, e.g. // from _another_ thread (typically the thread that created this one, e.g.
// the main thread), not from the thread itself // the main thread), not from the thread itself
// create a new thread - call Run() to start it // create a new thread and optionally set the stack size on
wxThreadError Create(); // platforms that support that - call Run() to start it
// (special cased for watcom which won't accept 0 default)
#ifdef __WATCOMC__
wxThreadError Create(unsigned int stackSize = 10240);
#else
wxThreadError Create(unsigned int stackSize = 0);
#endif
// starts execution of the thread - from the moment Run() is called // starts execution of the thread - from the moment Run() is called
// the execution of wxThread::Entry() may start at any moment, caller // the execution of wxThread::Entry() may start at any moment, caller
@@ -525,3 +532,5 @@ public:
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
#endif // __THREADH__ #endif // __THREADH__
// vi:sts=4:sw=4:et

View File

@@ -63,15 +63,15 @@ static bool gs_waitingForThread = FALSE ;
class wxMacStCritical class wxMacStCritical
{ {
public : public :
wxMacStCritical() wxMacStCritical()
{ {
ThreadBeginCritical() ; ThreadBeginCritical() ;
} }
~wxMacStCritical() ~wxMacStCritical()
{ {
ThreadEndCritical() ; ThreadEndCritical() ;
} }
} ; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxMutex implementation // wxMutex implementation
@@ -82,7 +82,7 @@ class wxMutexInternal
public: public:
wxMutexInternal() wxMutexInternal()
{ {
m_owner = kNoThreadID ; m_owner = kNoThreadID ;
} }
~wxMutexInternal() ~wxMutexInternal()
@@ -113,20 +113,20 @@ wxMutex::~wxMutex()
wxMutexError wxMutex::Lock() wxMutexError wxMutex::Lock()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
OSErr err ; OSErr err ;
ThreadID current = kNoThreadID; ThreadID current = kNoThreadID;
err = ::MacGetCurrentThread(&current); err = ::MacGetCurrentThread(&current);
// if we are not the owner, add this thread to the list of waiting threads, stop this thread // if we are not the owner, add this thread to the list of waiting threads, stop this thread
// and invoke the scheduler to continue executing the owner's thread // and invoke the scheduler to continue executing the owner's thread
while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current) while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current)
{ {
m_internal->m_waiters.Add(current); m_internal->m_waiters.Add(current);
err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner); err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner);
err = ::ThreadBeginCritical(); err = ::ThreadBeginCritical();
} }
m_internal->m_owner = current; m_internal->m_owner = current;
m_locked++; m_locked++;
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
@@ -134,16 +134,16 @@ wxMutexError wxMutex::Lock()
wxMutexError wxMutex::TryLock() wxMutexError wxMutex::TryLock()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
OSErr err ; OSErr err ;
ThreadID current = kNoThreadID; ThreadID current = kNoThreadID;
::MacGetCurrentThread(&current); ::MacGetCurrentThread(&current);
// if we are not the owner, give an error back // if we are not the owner, give an error back
if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current ) if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current )
return wxMUTEX_BUSY; return wxMUTEX_BUSY;
m_internal->m_owner = current; m_internal->m_owner = current;
m_locked++; m_locked++;
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
@@ -151,31 +151,31 @@ wxMutexError wxMutex::TryLock()
wxMutexError wxMutex::Unlock() wxMutexError wxMutex::Unlock()
{ {
OSErr err; OSErr err;
err = ::ThreadBeginCritical(); err = ::ThreadBeginCritical();
if (m_locked > 0) if (m_locked > 0)
m_locked--; m_locked--;
// this mutex is not owned by anybody anmore // this mutex is not owned by anybody anmore
m_internal->m_owner = kNoThreadID; m_internal->m_owner = kNoThreadID;
// now pass on to the first waiting thread // now pass on to the first waiting thread
ThreadID firstWaiting = kNoThreadID; ThreadID firstWaiting = kNoThreadID;
bool found = false; bool found = false;
while (!m_internal->m_waiters.IsEmpty() && !found) while (!m_internal->m_waiters.IsEmpty() && !found)
{ {
firstWaiting = m_internal->m_waiters[0]; firstWaiting = m_internal->m_waiters[0];
err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID); err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
// in case this was not successful (dead thread), we just loop on and reset the id // in case this was not successful (dead thread), we just loop on and reset the id
found = (err != threadNotFoundErr); found = (err != threadNotFoundErr);
if ( !found ) if ( !found )
firstWaiting = kNoThreadID ; firstWaiting = kNoThreadID ;
m_internal->m_waiters.RemoveAt(0) ; m_internal->m_waiters.RemoveAt(0) ;
} }
// now we have a valid firstWaiting thread, which has been scheduled to run next, just end the // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
// critical section and invoke the scheduler // critical section and invoke the scheduler
err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting); err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
} }
@@ -189,7 +189,7 @@ class wxConditionInternal
public: public:
wxConditionInternal() wxConditionInternal()
{ {
m_excessSignals = 0 ; m_excessSignals = 0 ;
} }
~wxConditionInternal() ~wxConditionInternal()
{ {
@@ -197,20 +197,20 @@ public:
bool Wait(unsigned long msectimeout) bool Wait(unsigned long msectimeout)
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
if ( m_excessSignals > 0 ) if ( m_excessSignals > 0 )
{ {
--m_excessSignals ; --m_excessSignals ;
return TRUE ; return TRUE ;
} }
else if ( msectimeout == 0 ) else if ( msectimeout == 0 )
{ {
return FALSE ; return FALSE ;
} }
else else
{ {
} }
/* /*
waiters++; waiters++;
// FIXME this should be MsgWaitForMultipleObjects() as well probably // FIXME this should be MsgWaitForMultipleObjects() as well probably
@@ -222,13 +222,13 @@ public:
*/ */
return TRUE ; return TRUE ;
} }
void Signal() void Signal()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
} }
wxArrayLong m_waiters ; wxArrayLong m_waiters ;
wxInt32 m_excessSignals ; wxInt32 m_excessSignals ;
}; };
wxCondition::wxCondition() wxCondition::wxCondition()
@@ -243,7 +243,7 @@ wxCondition::~wxCondition()
void wxCondition::Wait() void wxCondition::Wait()
{ {
(void)m_internal->Wait(0xFFFFFFFFL ); (void)m_internal->Wait(0xFFFFFFFFL);
} }
bool wxCondition::Wait(unsigned long sec, bool wxCondition::Wait(unsigned long sec,
@@ -259,7 +259,7 @@ void wxCondition::Signal()
// someone waits on it. In any case, the system will return it to a non // someone waits on it. In any case, the system will return it to a non
// signalled state afterwards. If multiple threads are waiting, only one // signalled state afterwards. If multiple threads are waiting, only one
// will be woken up. // will be woken up.
m_internal->Signal() ; m_internal->Signal() ;
} }
void wxCondition::Broadcast() void wxCondition::Broadcast()
@@ -305,7 +305,7 @@ public:
} }
// create a new (suspended) thread (for the given thread object) // create a new (suspended) thread (for the given thread object)
bool Create(wxThread *thread); bool Create(wxThread *thread, unsigned int stackSize);
// suspend/resume/terminate // suspend/resume/terminate
bool Suspend(); bool Suspend();
@@ -327,15 +327,14 @@ public:
ThreadID GetId() const { return m_tid; } ThreadID GetId() const { return m_tid; }
// thread function // thread function
static pascal void* MacThreadStart(wxThread* arg); static pascal void* MacThreadStart(wxThread* arg);
private: private:
wxThreadState m_state; // state, see wxThreadState enum wxThreadState m_state; // state, see wxThreadState enum
unsigned int m_priority; // thread priority in "wx" units unsigned int m_priority; // thread priority in "wx" units
ThreadID m_tid; // thread id ThreadID m_tid; // thread id
void * m_result ; void* m_result;
static ThreadEntryUPP s_threadEntry ; static ThreadEntryUPP s_threadEntry ;
public :
}; };
static wxArrayPtrVoid s_threads ; static wxArrayPtrVoid s_threads ;
@@ -372,22 +371,22 @@ pascal void* wxThreadInternal::MacThreadStart(wxThread *thread)
} }
void wxThreadInternal::SetPriority(unsigned int priority) void wxThreadInternal::SetPriority(unsigned int priority)
{ {
// Priorities don't exist on Mac // Priorities don't exist on Mac
} }
bool wxThreadInternal::Create(wxThread *thread) bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
{ {
if ( s_threadEntry == NULL ) if ( s_threadEntry == NULL )
{ {
s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ; s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;
} }
OSErr err = NewThread(kCooperativeThread, OSErr err = NewThread( kCooperativeThread,
s_threadEntry, s_threadEntry,
(void*) thread , (void*) thread,
0 , stackSize,
kNewSuspend , kNewSuspend,
&m_result , &m_result,
&m_tid ) ; &m_tid );
if ( err != noErr ) if ( err != noErr )
{ {
@@ -405,47 +404,47 @@ bool wxThreadInternal::Create(wxThread *thread)
bool wxThreadInternal::Suspend() bool wxThreadInternal::Suspend()
{ {
OSErr err ; OSErr err ;
::ThreadBeginCritical(); ::ThreadBeginCritical();
if ( m_state != STATE_RUNNING ) if ( m_state != STATE_RUNNING )
{ {
::ThreadEndCritical() ; ::ThreadEndCritical() ;
wxLogSysError(_("Can not suspend thread %x"), m_tid); wxLogSysError(_("Can not suspend thread %x"), m_tid);
return FALSE; return FALSE;
} }
m_state = STATE_PAUSED; m_state = STATE_PAUSED;
err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID); err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID);
return TRUE; return TRUE;
} }
bool wxThreadInternal::Resume() bool wxThreadInternal::Resume()
{ {
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
wxASSERT( err == noErr ) ; wxASSERT( err == noErr ) ;
wxASSERT( current != m_tid ) ; wxASSERT( current != m_tid ) ;
::ThreadBeginCritical(); ::ThreadBeginCritical();
if ( m_state != STATE_PAUSED && m_state != STATE_NEW ) if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
{ {
::ThreadEndCritical() ; ::ThreadEndCritical() ;
wxLogSysError(_("Can not resume thread %x"), m_tid); wxLogSysError(_("Can not resume thread %x"), m_tid);
return FALSE; return FALSE;
} }
err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID); err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);
wxASSERT( err == noErr ) ; wxASSERT( err == noErr ) ;
m_state = STATE_RUNNING; m_state = STATE_RUNNING;
::ThreadEndCritical() ; ::ThreadEndCritical() ;
::YieldToAnyThread() ; ::YieldToAnyThread() ;
return TRUE; return TRUE;
} }
@@ -453,18 +452,18 @@ bool wxThreadInternal::Resume()
// ---------------- // ----------------
wxThread *wxThread::This() wxThread *wxThread::This()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
for ( int i = 0 ; i < s_threads.Count() ; ++i ) for ( int i = 0 ; i < s_threads.Count() ; ++i )
{ {
if ( ( (wxThread*) s_threads[i] )->GetId() == current ) if ( ( (wxThread*) s_threads[i] )->GetId() == current )
return (wxThread*) s_threads[i] ; return (wxThread*) s_threads[i] ;
} }
wxLogSysError(_("Couldn't get the current thread pointer")); wxLogSysError(_("Couldn't get the current thread pointer"));
return NULL; return NULL;
@@ -472,10 +471,10 @@ wxThread *wxThread::This()
bool wxThread::IsMain() bool wxThread::IsMain()
{ {
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
return current == gs_idMainThread; return current == gs_idMainThread;
} }
@@ -485,21 +484,21 @@ bool wxThread::IsMain()
void wxThread::Yield() void wxThread::Yield()
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
void wxThread::Sleep(unsigned long milliseconds) void wxThread::Sleep(unsigned long milliseconds)
{ {
clock_t start = clock() ; clock_t start = clock() ;
do do
{ {
YieldToAnyThread() ; YieldToAnyThread() ;
} while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ; } while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ;
} }
int wxThread::GetCPUCount() int wxThread::GetCPUCount()
{ {
// we will use whatever MP API will be used for the new MP Macs // we will use whatever MP API will be used for the new MP Macs
return 1; return 1;
} }
@@ -535,18 +534,18 @@ wxThread::wxThread(wxThreadKind kind)
wxThread::~wxThread() wxThread::~wxThread()
{ {
s_threads.Remove( (void*) this ) ; s_threads.Remove( (void*) this ) ;
delete m_internal; delete m_internal;
} }
// create/start thread // create/start thread
// ------------------- // -------------------
wxThreadError wxThread::Create() wxThreadError wxThread::Create(unsigned int stackSize)
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
if ( !m_internal->Create(this) ) if ( !m_internal->Create(this, stackSize) )
return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_RESOURCE;
return wxTHREAD_NO_ERROR; return wxTHREAD_NO_ERROR;
@@ -649,16 +648,16 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
#if wxUSE_GUI #if wxUSE_GUI
// simply wait for the thread to terminate // simply wait for the thread to terminate
while( TestDestroy() ) while( TestDestroy() )
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
#else // !wxUSE_GUI #else // !wxUSE_GUI
// simply wait for the thread to terminate // simply wait for the thread to terminate
while( TestDestroy() ) while( TestDestroy() )
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
#endif // wxUSE_GUI/!wxUSE_GUI #endif // wxUSE_GUI/!wxUSE_GUI
if ( IsMain() ) if ( IsMain() )
@@ -727,7 +726,7 @@ void wxThread::Exit(ExitCode status)
delete this; delete this;
} }
m_internal->SetResult( status ) ; m_internal->SetResult( status ) ;
/* /*
#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) #if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
@@ -798,20 +797,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
bool wxThreadModule::OnInit() bool wxThreadModule::OnInit()
{ {
long response; long response;
bool hasThreadManager ; bool hasThreadManager ;
hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1; hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1;
#if !TARGET_CARBON #if !TARGET_CARBON
#if GENERATINGCFM #if GENERATINGCFM
// verify presence of shared library // verify presence of shared library
hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress); hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress);
#endif #endif
#endif #endif
if ( !hasThreadManager ) if ( !hasThreadManager )
{ {
wxMessageBox( "Error" , "Thread Support is not available on this System" , wxOK ) ; wxMessageBox( "Error" , "Thread Support is not available on this System" , wxOK ) ;
return FALSE ; return FALSE ;
} }
// no error return for GetCurrentThreadId() // no error return for GetCurrentThreadId()
MacGetCurrentThread( &gs_idMainThread ) ; MacGetCurrentThread( &gs_idMainThread ) ;
@@ -848,7 +847,7 @@ bool WXDLLEXPORT wxGuiOwnedByMainThread()
// wake up the main thread // wake up the main thread
void WXDLLEXPORT wxWakeUpMainThread() void WXDLLEXPORT wxWakeUpMainThread()
{ {
wxMacWakeUp() ; wxMacWakeUp() ;
} }
bool WXDLLEXPORT wxIsWaitingForThread() bool WXDLLEXPORT wxIsWaitingForThread()
@@ -858,3 +857,4 @@ bool WXDLLEXPORT wxIsWaitingForThread()
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
// vi:sts=4:sw=4:et

View File

@@ -63,15 +63,15 @@ static bool gs_waitingForThread = FALSE ;
class wxMacStCritical class wxMacStCritical
{ {
public : public :
wxMacStCritical() wxMacStCritical()
{ {
ThreadBeginCritical() ; ThreadBeginCritical() ;
} }
~wxMacStCritical() ~wxMacStCritical()
{ {
ThreadEndCritical() ; ThreadEndCritical() ;
} }
} ; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxMutex implementation // wxMutex implementation
@@ -82,7 +82,7 @@ class wxMutexInternal
public: public:
wxMutexInternal() wxMutexInternal()
{ {
m_owner = kNoThreadID ; m_owner = kNoThreadID ;
} }
~wxMutexInternal() ~wxMutexInternal()
@@ -113,20 +113,20 @@ wxMutex::~wxMutex()
wxMutexError wxMutex::Lock() wxMutexError wxMutex::Lock()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
OSErr err ; OSErr err ;
ThreadID current = kNoThreadID; ThreadID current = kNoThreadID;
err = ::MacGetCurrentThread(&current); err = ::MacGetCurrentThread(&current);
// if we are not the owner, add this thread to the list of waiting threads, stop this thread // if we are not the owner, add this thread to the list of waiting threads, stop this thread
// and invoke the scheduler to continue executing the owner's thread // and invoke the scheduler to continue executing the owner's thread
while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current) while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current)
{ {
m_internal->m_waiters.Add(current); m_internal->m_waiters.Add(current);
err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner); err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner);
err = ::ThreadBeginCritical(); err = ::ThreadBeginCritical();
} }
m_internal->m_owner = current; m_internal->m_owner = current;
m_locked++; m_locked++;
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
@@ -134,16 +134,16 @@ wxMutexError wxMutex::Lock()
wxMutexError wxMutex::TryLock() wxMutexError wxMutex::TryLock()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
OSErr err ; OSErr err ;
ThreadID current = kNoThreadID; ThreadID current = kNoThreadID;
::MacGetCurrentThread(&current); ::MacGetCurrentThread(&current);
// if we are not the owner, give an error back // if we are not the owner, give an error back
if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current ) if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current )
return wxMUTEX_BUSY; return wxMUTEX_BUSY;
m_internal->m_owner = current; m_internal->m_owner = current;
m_locked++; m_locked++;
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
@@ -151,31 +151,31 @@ wxMutexError wxMutex::TryLock()
wxMutexError wxMutex::Unlock() wxMutexError wxMutex::Unlock()
{ {
OSErr err; OSErr err;
err = ::ThreadBeginCritical(); err = ::ThreadBeginCritical();
if (m_locked > 0) if (m_locked > 0)
m_locked--; m_locked--;
// this mutex is not owned by anybody anmore // this mutex is not owned by anybody anmore
m_internal->m_owner = kNoThreadID; m_internal->m_owner = kNoThreadID;
// now pass on to the first waiting thread // now pass on to the first waiting thread
ThreadID firstWaiting = kNoThreadID; ThreadID firstWaiting = kNoThreadID;
bool found = false; bool found = false;
while (!m_internal->m_waiters.IsEmpty() && !found) while (!m_internal->m_waiters.IsEmpty() && !found)
{ {
firstWaiting = m_internal->m_waiters[0]; firstWaiting = m_internal->m_waiters[0];
err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID); err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
// in case this was not successful (dead thread), we just loop on and reset the id // in case this was not successful (dead thread), we just loop on and reset the id
found = (err != threadNotFoundErr); found = (err != threadNotFoundErr);
if ( !found ) if ( !found )
firstWaiting = kNoThreadID ; firstWaiting = kNoThreadID ;
m_internal->m_waiters.RemoveAt(0) ; m_internal->m_waiters.RemoveAt(0) ;
} }
// now we have a valid firstWaiting thread, which has been scheduled to run next, just end the // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
// critical section and invoke the scheduler // critical section and invoke the scheduler
err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting); err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);
return wxMUTEX_NO_ERROR; return wxMUTEX_NO_ERROR;
} }
@@ -189,7 +189,7 @@ class wxConditionInternal
public: public:
wxConditionInternal() wxConditionInternal()
{ {
m_excessSignals = 0 ; m_excessSignals = 0 ;
} }
~wxConditionInternal() ~wxConditionInternal()
{ {
@@ -197,20 +197,20 @@ public:
bool Wait(unsigned long msectimeout) bool Wait(unsigned long msectimeout)
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
if ( m_excessSignals > 0 ) if ( m_excessSignals > 0 )
{ {
--m_excessSignals ; --m_excessSignals ;
return TRUE ; return TRUE ;
} }
else if ( msectimeout == 0 ) else if ( msectimeout == 0 )
{ {
return FALSE ; return FALSE ;
} }
else else
{ {
} }
/* /*
waiters++; waiters++;
// FIXME this should be MsgWaitForMultipleObjects() as well probably // FIXME this should be MsgWaitForMultipleObjects() as well probably
@@ -222,13 +222,13 @@ public:
*/ */
return TRUE ; return TRUE ;
} }
void Signal() void Signal()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
} }
wxArrayLong m_waiters ; wxArrayLong m_waiters ;
wxInt32 m_excessSignals ; wxInt32 m_excessSignals ;
}; };
wxCondition::wxCondition() wxCondition::wxCondition()
@@ -243,7 +243,7 @@ wxCondition::~wxCondition()
void wxCondition::Wait() void wxCondition::Wait()
{ {
(void)m_internal->Wait(0xFFFFFFFFL ); (void)m_internal->Wait(0xFFFFFFFFL);
} }
bool wxCondition::Wait(unsigned long sec, bool wxCondition::Wait(unsigned long sec,
@@ -259,7 +259,7 @@ void wxCondition::Signal()
// someone waits on it. In any case, the system will return it to a non // someone waits on it. In any case, the system will return it to a non
// signalled state afterwards. If multiple threads are waiting, only one // signalled state afterwards. If multiple threads are waiting, only one
// will be woken up. // will be woken up.
m_internal->Signal() ; m_internal->Signal() ;
} }
void wxCondition::Broadcast() void wxCondition::Broadcast()
@@ -305,7 +305,7 @@ public:
} }
// create a new (suspended) thread (for the given thread object) // create a new (suspended) thread (for the given thread object)
bool Create(wxThread *thread); bool Create(wxThread *thread, unsigned int stackSize);
// suspend/resume/terminate // suspend/resume/terminate
bool Suspend(); bool Suspend();
@@ -327,15 +327,14 @@ public:
ThreadID GetId() const { return m_tid; } ThreadID GetId() const { return m_tid; }
// thread function // thread function
static pascal void* MacThreadStart(wxThread* arg); static pascal void* MacThreadStart(wxThread* arg);
private: private:
wxThreadState m_state; // state, see wxThreadState enum wxThreadState m_state; // state, see wxThreadState enum
unsigned int m_priority; // thread priority in "wx" units unsigned int m_priority; // thread priority in "wx" units
ThreadID m_tid; // thread id ThreadID m_tid; // thread id
void * m_result ; void* m_result;
static ThreadEntryUPP s_threadEntry ; static ThreadEntryUPP s_threadEntry ;
public :
}; };
static wxArrayPtrVoid s_threads ; static wxArrayPtrVoid s_threads ;
@@ -372,22 +371,22 @@ pascal void* wxThreadInternal::MacThreadStart(wxThread *thread)
} }
void wxThreadInternal::SetPriority(unsigned int priority) void wxThreadInternal::SetPriority(unsigned int priority)
{ {
// Priorities don't exist on Mac // Priorities don't exist on Mac
} }
bool wxThreadInternal::Create(wxThread *thread) bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
{ {
if ( s_threadEntry == NULL ) if ( s_threadEntry == NULL )
{ {
s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ; s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;
} }
OSErr err = NewThread(kCooperativeThread, OSErr err = NewThread( kCooperativeThread,
s_threadEntry, s_threadEntry,
(void*) thread , (void*) thread,
0 , stackSize,
kNewSuspend , kNewSuspend,
&m_result , &m_result,
&m_tid ) ; &m_tid );
if ( err != noErr ) if ( err != noErr )
{ {
@@ -405,47 +404,47 @@ bool wxThreadInternal::Create(wxThread *thread)
bool wxThreadInternal::Suspend() bool wxThreadInternal::Suspend()
{ {
OSErr err ; OSErr err ;
::ThreadBeginCritical(); ::ThreadBeginCritical();
if ( m_state != STATE_RUNNING ) if ( m_state != STATE_RUNNING )
{ {
::ThreadEndCritical() ; ::ThreadEndCritical() ;
wxLogSysError(_("Can not suspend thread %x"), m_tid); wxLogSysError(_("Can not suspend thread %x"), m_tid);
return FALSE; return FALSE;
} }
m_state = STATE_PAUSED; m_state = STATE_PAUSED;
err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID); err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID);
return TRUE; return TRUE;
} }
bool wxThreadInternal::Resume() bool wxThreadInternal::Resume()
{ {
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
wxASSERT( err == noErr ) ; wxASSERT( err == noErr ) ;
wxASSERT( current != m_tid ) ; wxASSERT( current != m_tid ) ;
::ThreadBeginCritical(); ::ThreadBeginCritical();
if ( m_state != STATE_PAUSED && m_state != STATE_NEW ) if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
{ {
::ThreadEndCritical() ; ::ThreadEndCritical() ;
wxLogSysError(_("Can not resume thread %x"), m_tid); wxLogSysError(_("Can not resume thread %x"), m_tid);
return FALSE; return FALSE;
} }
err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID); err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);
wxASSERT( err == noErr ) ; wxASSERT( err == noErr ) ;
m_state = STATE_RUNNING; m_state = STATE_RUNNING;
::ThreadEndCritical() ; ::ThreadEndCritical() ;
::YieldToAnyThread() ; ::YieldToAnyThread() ;
return TRUE; return TRUE;
} }
@@ -453,18 +452,18 @@ bool wxThreadInternal::Resume()
// ---------------- // ----------------
wxThread *wxThread::This() wxThread *wxThread::This()
{ {
wxMacStCritical critical ; wxMacStCritical critical ;
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
for ( int i = 0 ; i < s_threads.Count() ; ++i ) for ( int i = 0 ; i < s_threads.Count() ; ++i )
{ {
if ( ( (wxThread*) s_threads[i] )->GetId() == current ) if ( ( (wxThread*) s_threads[i] )->GetId() == current )
return (wxThread*) s_threads[i] ; return (wxThread*) s_threads[i] ;
} }
wxLogSysError(_("Couldn't get the current thread pointer")); wxLogSysError(_("Couldn't get the current thread pointer"));
return NULL; return NULL;
@@ -472,10 +471,10 @@ wxThread *wxThread::This()
bool wxThread::IsMain() bool wxThread::IsMain()
{ {
ThreadID current ; ThreadID current ;
OSErr err ; OSErr err ;
err = MacGetCurrentThread( &current ) ; err = MacGetCurrentThread( &current ) ;
return current == gs_idMainThread; return current == gs_idMainThread;
} }
@@ -485,21 +484,21 @@ bool wxThread::IsMain()
void wxThread::Yield() void wxThread::Yield()
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
void wxThread::Sleep(unsigned long milliseconds) void wxThread::Sleep(unsigned long milliseconds)
{ {
clock_t start = clock() ; clock_t start = clock() ;
do do
{ {
YieldToAnyThread() ; YieldToAnyThread() ;
} while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ; } while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ;
} }
int wxThread::GetCPUCount() int wxThread::GetCPUCount()
{ {
// we will use whatever MP API will be used for the new MP Macs // we will use whatever MP API will be used for the new MP Macs
return 1; return 1;
} }
@@ -535,18 +534,18 @@ wxThread::wxThread(wxThreadKind kind)
wxThread::~wxThread() wxThread::~wxThread()
{ {
s_threads.Remove( (void*) this ) ; s_threads.Remove( (void*) this ) ;
delete m_internal; delete m_internal;
} }
// create/start thread // create/start thread
// ------------------- // -------------------
wxThreadError wxThread::Create() wxThreadError wxThread::Create(unsigned int stackSize)
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
if ( !m_internal->Create(this) ) if ( !m_internal->Create(this, stackSize) )
return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_RESOURCE;
return wxTHREAD_NO_ERROR; return wxTHREAD_NO_ERROR;
@@ -649,16 +648,16 @@ wxThreadError wxThread::Delete(ExitCode *pRc)
#if wxUSE_GUI #if wxUSE_GUI
// simply wait for the thread to terminate // simply wait for the thread to terminate
while( TestDestroy() ) while( TestDestroy() )
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
#else // !wxUSE_GUI #else // !wxUSE_GUI
// simply wait for the thread to terminate // simply wait for the thread to terminate
while( TestDestroy() ) while( TestDestroy() )
{ {
::YieldToAnyThread() ; ::YieldToAnyThread() ;
} }
#endif // wxUSE_GUI/!wxUSE_GUI #endif // wxUSE_GUI/!wxUSE_GUI
if ( IsMain() ) if ( IsMain() )
@@ -727,7 +726,7 @@ void wxThread::Exit(ExitCode status)
delete this; delete this;
} }
m_internal->SetResult( status ) ; m_internal->SetResult( status ) ;
/* /*
#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) #if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
@@ -798,20 +797,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
bool wxThreadModule::OnInit() bool wxThreadModule::OnInit()
{ {
long response; long response;
bool hasThreadManager ; bool hasThreadManager ;
hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1; hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1;
#if !TARGET_CARBON #if !TARGET_CARBON
#if GENERATINGCFM #if GENERATINGCFM
// verify presence of shared library // verify presence of shared library
hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress); hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress);
#endif #endif
#endif #endif
if ( !hasThreadManager ) if ( !hasThreadManager )
{ {
wxMessageBox( "Error" , "Thread Support is not available on this System" , wxOK ) ; wxMessageBox( "Error" , "Thread Support is not available on this System" , wxOK ) ;
return FALSE ; return FALSE ;
} }
// no error return for GetCurrentThreadId() // no error return for GetCurrentThreadId()
MacGetCurrentThread( &gs_idMainThread ) ; MacGetCurrentThread( &gs_idMainThread ) ;
@@ -848,7 +847,7 @@ bool WXDLLEXPORT wxGuiOwnedByMainThread()
// wake up the main thread // wake up the main thread
void WXDLLEXPORT wxWakeUpMainThread() void WXDLLEXPORT wxWakeUpMainThread()
{ {
wxMacWakeUp() ; wxMacWakeUp() ;
} }
bool WXDLLEXPORT wxIsWaitingForThread() bool WXDLLEXPORT wxIsWaitingForThread()
@@ -858,3 +857,4 @@ bool WXDLLEXPORT wxIsWaitingForThread()
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
// vi:sts=4:sw=4:et

View File

@@ -351,8 +351,8 @@ wxCriticalSection::wxCriticalSection()
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
// Done this way to stop warnings during compilation about statement // Done this way to stop warnings during compilation about statement
// always being false // always being false
int csSize = sizeof(CRITICAL_SECTION); int csSize = sizeof(CRITICAL_SECTION);
int bSize = sizeof(m_buffer); int bSize = sizeof(m_buffer);
wxASSERT_MSG( csSize <= bSize, wxASSERT_MSG( csSize <= bSize,
_T("must increase buffer size in wx/thread.h") ); _T("must increase buffer size in wx/thread.h") );
#endif #endif
@@ -411,7 +411,7 @@ public:
} }
// create a new (suspended) thread (for the given thread object) // create a new (suspended) thread (for the given thread object)
bool Create(wxThread *thread); bool Create(wxThread *thread, unsigned int stackSize);
// suspend/resume/terminate // suspend/resume/terminate
bool Suspend(); bool Suspend();
@@ -514,7 +514,7 @@ void wxThreadInternal::SetPriority(unsigned int priority)
} }
} }
bool wxThreadInternal::Create(wxThread *thread) bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
{ {
// for compilers which have it, we should use C RTL function for thread // for compilers which have it, we should use C RTL function for thread
// creation instead of Win32 API one because otherwise we will have memory // creation instead of Win32 API one because otherwise we will have memory
@@ -522,22 +522,18 @@ bool wxThreadInternal::Create(wxThread *thread)
#ifdef wxUSE_BEGIN_THREAD #ifdef wxUSE_BEGIN_THREAD
m_hThread = (HANDLE)_beginthreadex m_hThread = (HANDLE)_beginthreadex
( (
NULL, // default security NULL, // default security
#ifdef __WATCOMC__ stackSize,
10240, // stack size can't be NULL in Watcom wxThreadInternal::WinThreadStart, // entry point
#else thread,
0, // default stack size CREATE_SUSPENDED,
#endif (unsigned int *)&m_tid
wxThreadInternal::WinThreadStart, // entry point
thread,
CREATE_SUSPENDED,
(unsigned int *)&m_tid
); );
#else // compiler doesn't have _beginthreadex #else // compiler doesn't have _beginthreadex
m_hThread = ::CreateThread m_hThread = ::CreateThread
( (
NULL, // default security NULL, // default security
0, // default stack size stackSize, // default stack size
wxThreadInternal::WinThreadStart, // thread entry point wxThreadInternal::WinThreadStart, // thread entry point
(LPVOID)thread, // parameter (LPVOID)thread, // parameter
CREATE_SUSPENDED, // flags CREATE_SUSPENDED, // flags
@@ -756,11 +752,11 @@ wxThread::~wxThread()
// create/start thread // create/start thread
// ------------------- // -------------------
wxThreadError wxThread::Create() wxThreadError wxThread::Create(unsigned int stackSize)
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
if ( !m_internal->Create(this) ) if ( !m_internal->Create(this, stackSize) )
return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_RESOURCE;
return wxTHREAD_NO_ERROR; return wxTHREAD_NO_ERROR;
@@ -1244,3 +1240,5 @@ bool WXDLLEXPORT wxIsWaitingForThread()
} }
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
// vi:sts=4:sw=4:et

View File

@@ -938,7 +938,7 @@ wxThread::wxThread(wxThreadKind kind)
m_isDetached = kind == wxTHREAD_DETACHED; m_isDetached = kind == wxTHREAD_DETACHED;
} }
wxThreadError wxThread::Create() wxThreadError wxThread::Create(unsigned int WXUNUSED(stackSize))
{ {
if ( m_internal->GetState() != STATE_NEW ) if ( m_internal->GetState() != STATE_NEW )
{ {