diff -r 0ff03867bdb6 -r 39b39e1a406e userlibandfileserver/fileserver/sfile/sf_thread.cpp --- a/userlibandfileserver/fileserver/sfile/sf_thread.cpp Wed Jul 21 14:46:58 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_thread.cpp Thu Jul 22 16:46:39 2010 +0100 @@ -834,10 +834,9 @@ // { __ASSERT_ALWAYS(FsThreadManager::IsDriveThread(iDriveNumber,EFalse),Fault(EDriveThreadNotifyUser1)); - // NB For read-ahead or a flush-dirty write request generated by the file cache, the session will be NULL: + // NB For read-ahead or a flush-dirty write request generated by the file cache, the request or the session may be NULL: // in this case assume that notify user is set (as it's the safest option) - CSessionFs* session = iRequest->Session(); - return session ? session->GetNotifyUser() : ETrue; + return iRequest && iRequest->Session() ? iRequest->Session()->GetNotifyUser() : ETrue; } void CDriveThread::StartFinalisationTimer() @@ -926,24 +925,34 @@ } -CPluginThread::CPluginThread(CFsPlugin& aPlugin) - : iPlugin(aPlugin) +CPluginThread::CPluginThread(CFsPlugin& aPlugin, RLibrary aLibrary) + : iPlugin(aPlugin), iLib(aLibrary) { /** @prototype */ iOperationLock.Close(); iPlugin.Open(); + + /* + Duplicate the handle to the DLL which created the plugin to prevent + TFsRemovePlugin::DoRequestL() from unmapping the DLL's code segment before + this thread's destructor has been called as the destructor closes the plugin + which results in a call to the plugin's derived destructor contained in the DLL (!) + */ + TInt r = iLib.Duplicate(iThread, EOwnerProcess); + __ASSERT_ALWAYS(r==KErrNone, Fault(EFsThreadConstructor)); } CPluginThread::~CPluginThread() { iPlugin.Close(); + iLib.Close(); } -CPluginThread* CPluginThread::NewL(CFsPlugin& aPlugin) +CPluginThread* CPluginThread::NewL(CFsPlugin& aPlugin, RLibrary aLibrary) { __PRINT(_L("CPluginThread::NewL()")); - CPluginThread* pT=new(ELeave) CPluginThread(aPlugin); + CPluginThread* pT=new(ELeave) CPluginThread(aPlugin, aLibrary); TInt r=pT->Initialise(); /** @prototype */