userlibandfileserver/fileserver/sfile/sf_ses.cpp
changeset 273 6a75fa55495f
parent 90 947f0dc9f7a8
child 286 48e57fb1237e
equal deleted inserted replaced
271:dc268b18d709 273:6a75fa55495f
    20 #include "sf_memory_man.h"
    20 #include "sf_memory_man.h"
    21 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION	
    21 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION	
    22 #include "sf_notifier.h"
    22 #include "sf_notifier.h"
    23 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION	
    23 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION	
    24 
    24 
       
    25 TInt CancelAsyncRequests(CSessionFs* aSession);
       
    26 
       
    27 
    25 CSessionFs::CSessionFs()
    28 CSessionFs::CSessionFs()
    26 	       :iSessionFlags((TInt)EFsSessionFlagsAll), 
    29 	       :iSessionFlags((TInt)EFsSessionFlagsAll), 
    27           iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)),
    30           iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)),
    28 	       iId(0)
    31 	       iId(0), iAccessCount(1)
    29 	{
    32 	{
    30 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
    33 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
    31     __e32_atomic_add_ord32(&SessionCount, 1);
    34     __e32_atomic_add_ord32(&SessionCount, 1);
    32 #endif
    35 #endif
    33 	}
    36 	}
    39 
    42 
    40 CSessionFs::~CSessionFs()
    43 CSessionFs::~CSessionFs()
    41 	{
    44 	{
    42 	__PRINT1(_L("CSessionFs::~CSessionFs() deleting... = 0x%x"),this);
    45 	__PRINT1(_L("CSessionFs::~CSessionFs() deleting... = 0x%x"),this);
    43 		
    46 		
       
    47 	FsNotify::CancelSession(this);
       
    48 
       
    49 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
       
    50 	FsNotificationManager::RemoveNotificationRequest(this);
       
    51 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
       
    52 
       
    53 
    44 	//take out all the reserved space set by this session
    54 	//take out all the reserved space set by this session
    45 	while(iReservedDriveAccess.Count())
    55 	while(iReservedDriveAccess.Count())
    46 		{
    56 		{
    47 		TReservedDriveAccess& reserved = iReservedDriveAccess[0];
    57 		TReservedDriveAccess& reserved = iReservedDriveAccess[0];
    48 		if(reserved.iReservedSpace)
    58 		if(reserved.iReservedSpace)
    63 		delete iHandles;
    73 		delete iHandles;
    64 
    74 
    65 	
    75 	
    66 	delete iPath;
    76 	delete iPath;
    67 	iSessionFlagsLock.Close();
    77 	iSessionFlagsLock.Close();
    68 	if(iDisconnectRequest)
       
    69 		delete(iDisconnectRequest);
       
    70 
    78 
    71 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
    79 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
    72     __e32_atomic_add_ord32(&SessionCount, (TUint32) -1);
    80     __e32_atomic_add_ord32(&SessionCount, (TUint32) -1);
    73 #endif
    81 #endif
    74 	}
    82 	}
    75 
    83 
       
    84 void CSessionFs::Close()
       
    85 	{
       
    86 	TheFileServer->SessionQueueLockWait();
       
    87 
       
    88 	if (iAccessCount == 1)
       
    89 		{
       
    90 		// close the objects owned by this session 
       
    91 		// NB closing a CFileShare may allocate a request to flush dirty data which will
       
    92 		// in turn increment iAccessCount on this session
       
    93 		if (iHandles)
       
    94 			{
       
    95 			// Cancel any ASYNC requests belonging to this session BEFORE 
       
    96 			// CSessionFs is deleted to avoid a KERN-EXEC 44 (EBadMessageHandle)
       
    97 			CancelAsyncRequests(this);
       
    98 			delete iHandles;
       
    99 			iHandles = NULL;
       
   100 			}
       
   101 		}
       
   102 
       
   103 	if (__e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0) == 1)
       
   104 		{
       
   105 		RMessage2 message = iMessage;
       
   106 		delete this;
       
   107 		// NB Must complete the message AFTER the session has been deleted...
       
   108 		message.Complete(KErrNone);
       
   109 		}
       
   110 
       
   111 	TheFileServer->SessionQueueLockSignal();
       
   112 	}
       
   113 
    76 void CSessionFs::CreateL()
   114 void CSessionFs::CreateL()
    77 //
   115 //
    78 // Create any additional resources.
   116 // Create any additional resources.
    79 //
   117 //
    80 	{
   118 	{
    81 	__PRINT1(_L("CSessionFs::CreateL 0x%x"),this);
   119 	__PRINT1(_L("CSessionFs::CreateL 0x%x"),this);
    82 
   120 
    83 	iHandles=CFsObjectIx::NewL();
   121 	iHandles=CFsObjectIx::NewL();
    84 	TInt r = iSessionFlagsLock.CreateLocal();
   122 	TInt r = iSessionFlagsLock.CreateLocal();
    85 	User::LeaveIfError(r);
   123 	User::LeaveIfError(r);
    86 	RMessage2 m;
       
    87 
       
    88 	iDisconnectRequest=new(ELeave) CFsDisconnectRequest;
       
    89 	iDisconnectRequest->Set(m,SessionDisconnectOp,this);
       
    90 
       
    91 
       
    92 	}
   124 	}
    93 
   125 
    94 TInt CSessionFs::CurrentDrive()
   126 TInt CSessionFs::CurrentDrive()
    95 //
   127 //
    96 // Return the current drive.
   128 // Return the current drive.
   142 void CSessionFs::Disconnect(const RMessage2& aMessage)
   174 void CSessionFs::Disconnect(const RMessage2& aMessage)
   143 	{
   175 	{
   144 	__THRD_PRINT1(_L("CSessionFs::Disconnect() 0x%x"),this);
   176 	__THRD_PRINT1(_L("CSessionFs::Disconnect() 0x%x"),this);
   145 
   177 
   146 	iHandles->CloseMainThreadObjects();
   178 	iHandles->CloseMainThreadObjects();
   147 	iDisconnectRequest->SetMessage((RMessage2&)aMessage);
   179 	iMessage = aMessage;
   148 
   180 
   149 	iDisconnectRequest->Dispatch();
   181 	// close the session - if there are no requests using this session then the session will be freed
       
   182 	Close();
   150 	}
   183 	}
   151 
   184 
   152 
   185 
   153 TUint CSessionFs::Reserved(TInt aDriveNumber) const
   186 TUint CSessionFs::Reserved(TInt aDriveNumber) const
   154 	{
   187 	{
   476 	return retVal;
   509 	return retVal;
   477 	}
   510 	}
   478 
   511 
   479 
   512 
   480 
   513 
   481 TInt TFsCancelSession::DoRequestL(CFsRequest* aRequest)
       
   482 	{
       
   483 	__CHECK_DRIVETHREAD(aRequest->DriveNumber());
       
   484 
       
   485 	// Cancel any outstanding requests
       
   486 	CDriveThread* pT=NULL;
       
   487 	TInt r=FsThreadManager::GetDriveThread(aRequest->DriveNumber(), &pT);
       
   488 	if(r==KErrNone)
       
   489 		pT->CompleteSessionRequests(aRequest->Session(),KErrCancel);
       
   490 	// We must also cancel any ASYNC requests belonging to this session BEFORE 
       
   491 	// ~CSessionFs() is called to avoid a KERN-EXEC 44 (EBadMessageHandle)
       
   492 	CancelAsyncRequests(aRequest->Session());
       
   493 	return(r);
       
   494 	}
       
   495 
       
   496 TInt TFsCancelSession::Initialise(CFsRequest* /*aRequest*/)
       
   497 	{
       
   498 	return(KErrNone);
       
   499 	}
       
   500 
       
   501 TInt TFsSessionDisconnect::DoRequestL(CFsRequest* aRequest)
       
   502 	{
       
   503 	__PRINT(_L("TFsSessionDisconnect::DoRequestL()"));
       
   504 	__ASSERT_DEBUG(FsThreadManager::IsDisconnectThread(),Fault(ESessionDisconnectThread1));
       
   505 	CDisconnectThread* pT=FsThreadManager::GetDisconnectThread();
       
   506 	
       
   507 	// Complete requests on all plugins
       
   508 	CFsInternalRequest* pR=pT->GetRequest();
       
   509 	FsPluginManager::CompleteSessionRequests(aRequest->Session(), KErrCancel, pR);
       
   510 
       
   511 	// ...and on all drives
       
   512 	for(TInt i=0;i<KMaxDrives;++i)
       
   513 		{
       
   514 		FsThreadManager::LockDrive(i);
       
   515 		if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse))
       
   516 			{
       
   517 			FsThreadManager::UnlockDrive(i);
       
   518 			continue;
       
   519 			}
       
   520 		pR->Set(CancelSessionOp,aRequest->Session());
       
   521 		pR->SetDriveNumber(i);
       
   522 		pR->Status()=KRequestPending;
       
   523 		pR->Dispatch();
       
   524 		FsThreadManager::UnlockDrive(i);
       
   525 		User::WaitForRequest(pR->Status());
       
   526 		// check request completed or cancelled (by file system dismount which completes requests with KErrNotReady)
       
   527 		__ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2));
       
   528 		__THRD_PRINT2(_L("cancel session requests on drive %d r=%d"),i,pR->Status().Int());
       
   529 
       
   530 		if (TFileCacheSettings::Flags(i) & (EFileCacheWriteEnabled | EFileCacheWriteOn))
       
   531 			{
       
   532 			FsThreadManager::LockDrive(i);
       
   533 			if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse))
       
   534 				{
       
   535 				FsThreadManager::UnlockDrive(i);
       
   536 				continue;
       
   537 				}
       
   538 
       
   539 			// Flush dirty data
       
   540 			pR->Set(FlushDirtyDataOp,aRequest->Session());
       
   541 			pR->SetDriveNumber(i);
       
   542 			pR->Status()=KRequestPending;
       
   543 			pR->Dispatch();
       
   544 			FsThreadManager::UnlockDrive(i);
       
   545 			User::WaitForRequest(pR->Status());
       
   546 			// check request completed or cancelled (by file system dismount which completes requests with KErrNotReady)
       
   547 			__ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2));
       
   548 			__THRD_PRINT2(_L("Flush dirty data on drive %d r=%d"),i,pR->Status().Int());
       
   549 			}
       
   550 
       
   551 		}
       
   552 	FsNotify::CancelSession(aRequest->Session());
       
   553 	
       
   554 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
       
   555 	FsNotificationManager::RemoveNotificationRequest(aRequest->Session());
       
   556 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
       
   557 
       
   558 
       
   559 	// don't delete session here, will be done in CFsDisconnectRequest::Complete()
       
   560 	return(KErrNone);
       
   561 	}
       
   562 
       
   563 TInt TFsSessionDisconnect::Initialise(CFsRequest* /*aRequest*/)
       
   564 	{
       
   565 	return(KErrNone);
       
   566 	}
       
   567 
       
   568 TInt TFsCancelPlugin::DoRequestL(CFsRequest* aRequest)
       
   569 	{
       
   570 	//__ASSERT_DEBUG(FsPluginManager::IsPluginThread(),Fault(EFsPluginThreadError));
       
   571 	FsPluginManager::CancelPlugin(aRequest->iCurrentPlugin,aRequest->Session());
       
   572 	TInt err = aRequest->iCurrentPlugin->SessionDisconnect(aRequest->Session());
       
   573 	return(err);
       
   574 	}
       
   575 
       
   576 TInt TFsCancelPlugin::Initialise(CFsRequest* /*aRequest*/)
       
   577 	{
       
   578 	// Notify plugin of session disconnect
       
   579 	return(KErrNone);
       
   580 	}
       
   581 
       
   582 TInt TFsSetSessionFlags::DoRequestL(CFsRequest* aRequest)
   514 TInt TFsSetSessionFlags::DoRequestL(CFsRequest* aRequest)
   583 	{
   515 	{
   584 	aRequest->Session()->SetSessionFlags(aRequest->Message().Int0(), aRequest->Message().Int1());
   516 	aRequest->Session()->SetSessionFlags(aRequest->Message().Int0(), aRequest->Message().Int1());
   585 	return(KErrNone);
   517 	return(KErrNone);
   586 	}
   518 	}