diff --git a/mozilla/widget/src/os2/nsDirPicker.cpp b/mozilla/widget/src/os2/nsDirPicker.cpp index 6e37d29cd3f..97dcf8e2134 100644 --- a/mozilla/widget/src/os2/nsDirPicker.cpp +++ b/mozilla/widget/src/os2/nsDirPicker.cpp @@ -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: diff --git a/mozilla/widget/src/os2/nsFSTree.cpp b/mozilla/widget/src/os2/nsFSTree.cpp index aac4a844ca2..1b833fc95c7 100644 --- a/mozilla/widget/src/os2/nsFSTree.cpp +++ b/mozilla/widget/src/os2/nsFSTree.cpp @@ -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);