--- 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 */