r=mkaply, a=blizzard
Thread synchronization in dirpicker - prevents trap


git-svn-id: svn://10.0.0.236/trunk@83795 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mkaply%us.ibm.com
2000-12-18 20:33:29 +00:00
parent 85d269666a
commit a1fa286158
2 changed files with 28 additions and 12 deletions

View File

@@ -134,6 +134,7 @@ struct DirPicker : public FS::ICallbacks
// Create a new node
PTREENODE pRec = (PTREENODE) WinSendMsg( hwndCnr, CM_ALLOCRECORD,
MPFROMLONG(4), MPFROMLONG(1));
if( !pRec) return;
// find some strings; note that fstree owns them
pRec->m.pszIcon = (char*) aNewNode->GetFileInfo()->GetLeafName();
if( aNewNode->AsDrive())
@@ -395,13 +396,6 @@ MRESULT EXPENTRY fndpDirPicker( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
}
break;
case WM_DESTROY:
{
pData->fsTree->DeleteInstance();
delete pData;
break;
}
case WM_COMMAND:
switch( SHORT1FROMMP(mp1))
{
@@ -440,11 +434,11 @@ MRESULT EXPENTRY fndpDirPicker( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
}
}
}
// break out, defdlgproc will close the window.
break;
// fall out, defdlgproc will close the window.
}
}
pData->fsTree->DeleteInstance();
delete pData;
break;
case WM_CLOSE:

View File

@@ -399,7 +399,7 @@ BOOL fsTree::DeleteInstance()
fsTree::~fsTree()
{
// Execute synchronously to prevent leaky pain
mDestructing = TRUE;
mDestructing = TRUE;
if( mRoot)
DestroyNode( mRoot);
@@ -407,7 +407,11 @@ fsTree::~fsTree()
mCBQueue.Close();
if( mHEV)
{
if( mBuildMode != FS::Synchronous)
DosWaitEventSem( mHEV, SEM_INDEFINITE_WAIT); // Let async thread finish
DosCloseEventSem( mHEV);
}
if( mMutex)
DosCloseMutexSem( mMutex);
@@ -515,6 +519,12 @@ void fsTree::Scan()
// This lets the user thread go if we're synchronous.
SendCompleteMsg();
if( mDestructing)
{
DosPostEventSem( mHEV); // Just in case main thread is still waiting
return;
}
// Process commands
for(;;)
{
@@ -589,6 +599,8 @@ void fsTree::CreateDrives()
// go through the drives one by one
for( UINT i = 0; i < ulDrives; i++)
{
if( mDestructing) return;
APIRET rc;
FILESTATUS3 fs3 = { { 0, 0, 0 } };
FILEFINDBUF3 ffb3 = { 0 };
@@ -615,11 +627,13 @@ void fsTree::CreateDrives()
SendMsg( pDrive, CBPacket::CreateNode);
}
// now scan for children. Splitting the task up this way makes UIs more
// responsive, as they can wap up the roots first before going digging.
fsDir *pDir = mRoot->GetFirstChild();
while( pDir)
{
if( mDestructing) return;
ScanForChildren( pDir);
pDir = pDir->GetNextSibling();
}
@@ -652,6 +666,8 @@ void fsTree::ScanForChildren( fsDir *aParent)
while( !rc)
{
if( mDestructing) break;
if( strcmp( fb.achName, ".") && strcmp( fb.achName, ".."))
{
Lock();
@@ -755,6 +771,8 @@ void fsTree::Foliate( fsDir *aDir)
while( !rc)
{
if( mDestructing) break;
Lock();
fsFile *pFile = new fsFile( &fb, aDir);
if( !pLast) aDir->SetFiles( pFile);
@@ -793,6 +811,8 @@ void fsTree::Notify()
break;
}
if( mDestructing) break;
switch( pkt.mCmd)
{
case CBPacket::CreateRoot:
@@ -819,7 +839,7 @@ void fsTree::Notify()
case CBPacket::ScanComplete:
mCallbacks->InitialScanComplete();
if( mBuildMode == FS::Synchronous)
// if( mBuildMode == FS::Synchronous)
DosPostEventSem( mHEV);
break;
@@ -829,6 +849,8 @@ void fsTree::Notify()
}
}
DosPostEventSem( mHEV); // Just in case the main thread is still waiting
if( mNeedsPM)
{
WinDestroyMsgQueue( hmq);