home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-02 | 4.9 KB | 249 lines | [TEXT/CWIE] |
- #ifndef __THREADMANAGER__
- #include "ThreadManager.h"
- #endif
-
- #include "Toolbox.h"
- #include "Exceptions.h"
-
- class TThread;
-
- struct ThreadTableEntry
- {
- ThreadID id;
- TThread* obj;
- };
-
- typedef struct ThreadTable
- {
- long size;
- ThreadTableEntry data[1];
- } ThreadTable, *ThreadTablePtr, **ThreadTableHdl;
-
- #define sizeofThreadTable(n) (sizeof(ThreadTable) - sizeof(ThreadTableEntry) + ((n) * sizeof(ThreadTableEntry)))
- #define kThreadTableChunk 4
-
- //--------------------------------------------------------------------------------
-
- ThreadManager* ThreadManager::gThreadManager = nil;
- long ThreadManager::gThreadGestalt = 0;
- long ThreadManager::gThreadCount = 0;
- ThreadTaskRef ThreadManager::gTaskRef = nil;
-
- static ThreadTableHdl gThreadTable = nil;
- static ThreadID gThreadHintID = kNoThreadID;
- static long gThreadHintIndex = 0;
-
- //--------------------------------------------------------------------------------
-
- #if qDebug
- ThreadManager& ThreadManager::GetThreadManager()
- {
- if (!gThreadManager)
- {
- Debugger();
- }
-
- return *gThreadManager;
- }
- #endif
-
- //--------------------------------------------------------------------------------
-
- ThreadManager::ThreadManager()
- {
- WarnIf(gThreadManager != nil, "Instantiating a second ThreadManager");
-
- gThreadManager = this;
- }
-
- //--------------------------------------------------------------------------------
-
- ThreadManager::~ThreadManager()
- {
- gThreadManager = nil;
- }
-
- //--------------------------------------------------------------------------------
-
- bool ThreadManager::Validate()
- {
- if (Inherited::Validate())
- {
- OSErr err = Gestalt(gestaltThreadMgrAttr, &gThreadGestalt);
-
- if (err == noErr)
- {
- if (HasCFMSymbol(NewThread))
- {
- return true;
- }
- }
-
- gThreadGestalt = 0;
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------------------
-
- void ThreadManager::Initialize(void)
- {
- if (gThreadCount == 0)
- {
- InitializeAfter(Toolbox::GetToolbox());
-
- Inherited::Initialize();
-
- FailOSErr(GetThreadCurrentTaskRef(&gTaskRef));
-
- FailOSErr(SetDebuggerNotificationProcs(
- &ThreadCreatedProc,
- &ThreadDeletedProc,
- &ThreadScheduleProc));
-
- FailNIL(gThreadTable = (ThreadTableHdl) NewHandleClear(sizeofThreadTable(kThreadTableChunk)));
-
- ThreadTablePtr p = *gThreadTable;
-
- p->size = kThreadTableChunk;
- p->data[0].id = kApplicationThreadID;
-
- gThreadCount = 1;
- }
- }
-
- //--------------------------------------------------------------------------------
-
- ThreadID ThreadManager::NewThreadID(
- ThreadStyle threadStyle,
- ThreadEntryProcPtr threadEntry,
- void * threadParam,
- Size stackSize,
- ThreadOptions options,
- void ** threadResult)
- {
- ThreadID result;
-
- FailOSErr(::NewThread(threadStyle, threadEntry, threadParam, stackSize, options, threadResult, &result));
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
-
- void* ThreadManager::DisposeThreadID(ThreadID threadToDump)
- {
- void* result = nil;
-
- FailOSErr(::DisposeThread(threadToDump, &result, false));
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
-
- void* ThreadManager::RecycleThreadID(ThreadID threadToDump)
- {
- void* result = nil;
-
- FailOSErr(::DisposeThread(threadToDump, &result, true));
-
- return result;
- }
-
- //--------------------------------------------------------------------------------
-
- pascal void ThreadManager::ThreadCreatedProc(ThreadID threadCreated)
- {
- if (gThreadTable != nil)
- {
- ThreadTablePtr p = *gThreadTable;
-
- int count = p->size;
- int hole = hole;
- int index = -1;
-
- for (int i = 0; i < count; i++)
- {
- ThreadID id = p->data[i].id;
-
- if (id == kNoThreadID)
- {
- if (hole < 0)
- {
- hole = i;
- }
- }
- else if (id == threadCreated)
- {
- index = i;
- break;
- }
- }
-
- if (index < 0)
- {
- if (hole >= 0)
- {
- index = hole;
- }
- else
- {
- index = count;
- count += kThreadTableChunk;
-
- SetHandleSize((Handle) gThreadTable, sizeofThreadTable(count));
-
- FailMemError();
-
- p = *gThreadTable;
-
- BlockZero(&p->data[index], kThreadTableChunk*sizeof(ThreadTableEntry));
-
- p->size = count;
- }
-
- p->data[index].id = threadCreated;
- }
- }
-
- gThreadCount++;
- }
-
- //--------------------------------------------------------------------------------
-
- pascal void ThreadManager::ThreadDeletedProc(ThreadID threadDeleted)
- {
- if (gThreadTable != nil)
- {
- ThreadTablePtr p = *gThreadTable;
-
- int count = p->size;
-
- for (int i = 0; i < count; i++)
- {
- ThreadID id = p->data[i].id;
-
- if (id == threadDeleted)
- {
- p->data[i].id = kNoThreadID;
- p->data[i].obj = nil;
- break;
- }
- }
- }
-
- gThreadCount--;
- }
-
- //--------------------------------------------------------------------------------
-
- pascal ThreadID ThreadManager::ThreadScheduleProc(SchedulerInfoRecPtr schedulerInfo)
- {
- return schedulerInfo->SuggestedThreadID;
- }
-
- //--------------------------------------------------------------------------------
-
-