userlibandfileserver/fileserver/sfile/sf_notify.cpp
changeset 286 48e57fb1237e
parent 273 6a75fa55495f
child 299 b5a01337d018
equal deleted inserted replaced
285:ff5437e4337c 286:48e57fb1237e
    38 CNotifyInfo::~CNotifyInfo()
    38 CNotifyInfo::~CNotifyInfo()
    39 //
    39 //
    40 //
    40 //
    41 //
    41 //
    42 	{
    42 	{
    43 	__ASSERT_DEBUG(!iLink.iNext,Fault(ENotifyInfoDestructor));
    43 	// message should have been completed already
       
    44 	__ASSERT_DEBUG(iMessage.IsNull(), Fault(ENotifyInfoDestructor));
       
    45 
       
    46 	__ASSERT_DEBUG(iLink.iNext,Fault(ENotifyInfoDestructor));	
       
    47 	iLink.Deque();
    44 	}
    48 	}
    45 
    49 
    46 void CNotifyInfo::Complete(TInt aError)
    50 void CNotifyInfo::Complete(TInt aError)
    47 //
    51 //
    48 //
    52 //
    49 //
    53 //
    50 	{
    54 	{
    51 	__PRINT2(_L("CNotifyInfo::Complete 0x%x error=%d"),this,aError);
    55 	__PRINT2(_L("CNotifyInfo::Complete 0x%x error=%d"),this,aError);
    52 	if (!iMessage.IsNull())				// Dismount notifiers may be completed but remain in the list
    56 	if (!iMessage.IsNull())						
    53 		{											// until handled by the client or the session is closed.
       
    54 		iMessage.Complete(aError);
    57 		iMessage.Complete(aError);
    55 		}
       
    56 	}
    58 	}
    57 
    59 
    58 
    60 
    59 void CStdChangeInfo::Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
    61 void CStdChangeInfo::Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
    60 //
    62 //
   257 		{
   259 		{
   258 		case EFsDismountNotifyClients:
   260 		case EFsDismountNotifyClients:
   259 			break;
   261 			break;
   260 		case EFsDismountRegisterClient:
   262 		case EFsDismountRegisterClient:
   261 			__ASSERT_ALWAYS(TheDrives[iDriveNumber].DismountUnlock() >= 0, Fault(ENotifyDismountCancel));
   263 			__ASSERT_ALWAYS(TheDrives[iDriveNumber].DismountUnlock() >= 0, Fault(ENotifyDismountCancel));
       
   264 			__ASSERT_ALWAYS(iMessage.IsNull(), Fault(ENotifyDismountCancel));
       
   265 			TheDrives[iDriveNumber].DismountClientRemoved();
   262 			break;
   266 			break;
   263 		default:
   267 		default:
   264 			break;
   268 			break;
   265 		}
   269 		}
   266 	}
   270 	}
       
   271 
       
   272 void CDismountNotifyInfo::Complete(TInt aError)
       
   273 	{
       
   274 	__PRINT2(_L("CDismountNotifyInfo::Complete 0x%x error=%d"),this,aError);
       
   275 	if (!iMessage.IsNull())						
       
   276 		{
       
   277 		iMessage.Complete(aError);
       
   278 		// inc count of messages completed by EFsDismountNotifyClients & waiting for an EFsAllowDismount request from client
       
   279 		if (iMode == EFsDismountRegisterClient)
       
   280 			TheDrives[iDriveNumber].DismountClientAdded();
       
   281 		}
       
   282 	}
       
   283 
   267 
   284 
   268 void CDismountNotifyInfo::Initialise(TNotifyDismountMode aMode, TInt aDriveNumber, TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
   285 void CDismountNotifyInfo::Initialise(TNotifyDismountMode aMode, TInt aDriveNumber, TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
   269 	{
   286 	{
   270 	iMode = aMode;
   287 	iMode = aMode;
   271 	iDriveNumber=aDriveNumber;
   288 	iDriveNumber=aDriveNumber;
   322 		{
   339 		{
   323 		if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
   340 		if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
   324 			{
   341 			{
   325 			isFound=ETrue;
   342 			isFound=ETrue;
   326 			info->Complete(aCompletionCode);
   343 			info->Complete(aCompletionCode);
   327 			info->iLink.Deque();
       
   328 			delete(info);
   344 			delete(info);
   329 			if(aStatus)
   345 			if(aStatus)
   330 				break;
   346 				break;
   331 			}
   347 			}
   332 		}
   348 		}
   333 	return(isFound);
   349 	return(isFound);
   334 	}
   350 	}
   335 
   351 
   336 CNotifyInfo* TBaseQue::DoFindEntry(CSessionFs* aSession, TRequestStatus* aStatus)
   352 void TBaseQue::DoCancelAll(TInt aCompletionCode)
       
   353 //
       
   354 // Cancel all notifications
       
   355 // Que should be locked by calling function
       
   356 //
   337 	{
   357 	{
   338 	TDblQueIter<CNotifyInfo> q(iHeader);
   358 	TDblQueIter<CNotifyInfo> q(iHeader);
   339 	CNotifyInfo* info;
   359 	CNotifyInfo* info;
   340 	while((info=q++)!=NULL)
   360 	while((info=q++)!=NULL)
   341 		{
   361 		{
   342 		if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
       
   343 			return info;
       
   344 		}
       
   345 	return NULL;
       
   346 	}
       
   347 
       
   348 void TBaseQue::DoCancelAll(TInt aCompletionCode)
       
   349 //
       
   350 // Cancel all notifications
       
   351 // Que should be locked by calling function
       
   352 //
       
   353 	{
       
   354 	TDblQueIter<CNotifyInfo> q(iHeader);
       
   355 	CNotifyInfo* info;
       
   356 	while((info=q++)!=NULL)
       
   357 		{
       
   358 		info->Complete(aCompletionCode);
   362 		info->Complete(aCompletionCode);
   359 		info->iLink.Deque();
       
   360 		delete(info);
   363 		delete(info);
   361 		}
   364 		}
   362 	__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
   365 	__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
   363 	}
   366 	}
   364 
   367 
   431 			isMatching=((CExtChangeInfo*)info)->IsMatching(aRequest);
   434 			isMatching=((CExtChangeInfo*)info)->IsMatching(aRequest);
   432 		if(isMatching)
   435 		if(isMatching)
   433 			{
   436 			{
   434 			__PRINT1(_L("TChangeQue::CheckChange()-Matching info=0x%x"),info);
   437 			__PRINT1(_L("TChangeQue::CheckChange()-Matching info=0x%x"),info);
   435 			info->Complete(KErrNone);
   438 			info->Complete(KErrNone);
   436 			info->iLink.Deque();
       
   437 			delete(info);
   439 			delete(info);
   438 			}
   440 			}
   439 		}
   441 		}
   440 	iQLock.Signal();
   442 	iQLock.Signal();
   441 	}
   443 	}
   528 
   530 
   529 			if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
   531 			if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
   530 				{
   532 				{
   531 				__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
   533 				__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
   532 				info->Complete(KErrNone);
   534 				info->Complete(KErrNone);
   533 				info->iLink.Deque();
       
   534 				delete(info);
   535 				delete(info);
   535 				}
   536 				}
   536 			}
   537 			}
   537 		iFreeDiskSpace=freeSpace;
   538 		iFreeDiskSpace=freeSpace;
   538 		iReservedDiskSpace=reservedSpace;
   539 		iReservedDiskSpace=reservedSpace;
   577 
   578 
   578 		if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
   579 		if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
   579 			{
   580 			{
   580 			__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
   581 			__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
   581 			info->Complete(KErrNone);
   582 			info->Complete(KErrNone);
   582 			info->iLink.Deque();
       
   583 			delete(info);
   583 			delete(info);
   584 			}
   584 			}
   585 		}
   585 		}
   586 	iFreeDiskSpace=aFreeDiskSpace;
   586 	iFreeDiskSpace=aFreeDiskSpace;
   587 	iReservedDiskSpace=reservedSpace;
   587 	iReservedDiskSpace=reservedSpace;
   644 		__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDebugChange,Fault(EDebugQueType));
   644 		__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDebugChange,Fault(EDebugQueType));
   645 		if(((CDebugChangeInfo*)info)->IsMatching(aDebugChange))
   645 		if(((CDebugChangeInfo*)info)->IsMatching(aDebugChange))
   646 			{
   646 			{
   647 			__PRINT1(_L("TDebugQue::CheckDebug()-Matching info=0x%x"),info);
   647 			__PRINT1(_L("TDebugQue::CheckDebug()-Matching info=0x%x"),info);
   648 			info->Complete(KErrNone);
   648 			info->Complete(KErrNone);
   649 			info->iLink.Deque();
       
   650 			delete(info);
   649 			delete(info);
   651 			}
   650 			}
   652 		}
   651 		}
   653 	iQLock.Signal();
   652 	iQLock.Signal();
   654 	}
   653 	}
   662 	TBaseQue::DoAddNotify(aInfo);
   661 	TBaseQue::DoAddNotify(aInfo);
   663 	iQLock.Signal();
   662 	iQLock.Signal();
   664 	return(KErrNone);
   663 	return(KErrNone);
   665 	}
   664 	}
   666 
   665 
   667 TInt TDismountNotifyQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
   666 void TDismountNotifyQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
   668 //
   667 //
   669 // Returns the drive number or KErrNotFound
   668 //
   670 //
   669 	{
   671 	{
   670 	iQLock.Wait();
   672 	iQLock.Wait();
   671 
   673 
   672 	TDblQueIter<CDismountNotifyInfo> q(iHeader);
   674 	// return the drive number
   673 	CDismountNotifyInfo* info;
   675 	CDismountNotifyInfo* info = (CDismountNotifyInfo*) DoFindEntry(aSession, aStatus);
   674 	while((info=q++)!=NULL)
   676 	TInt driveNumber = info ? info->DriveNumber() : KErrNotFound;
   675 		{
   677 
   676 		if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
   678 	TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
   677 			{
   679 
   678 			TInt driveNumber = info->DriveNumber();
   680 	iQLock.Signal();
   679 
   681 
   680 			info->Complete(aCompletionCode);
   682 	return(driveNumber);
   681 			TInt mode = info->Mode();
       
   682 
       
   683 			delete info;
       
   684 			info = NULL;
       
   685 
       
   686 			// if we're cancelling a dismount request (EFsDismountNotifyClients or EFsDismountForceDismount), 
       
   687 			// then we need to cancel the deferred dismount and issue a disk change notification as observers 
       
   688 			// may be expecting one...
       
   689 			if (mode == EFsDismountNotifyClients || mode == EFsDismountForceDismount)
       
   690 				{
       
   691 				TheDrives[driveNumber].SetDismountDeferred(EFalse);
       
   692 				FsNotify::DiskChange(driveNumber);
       
   693 				}
       
   694 
       
   695 			if(aStatus)
       
   696 				break;
       
   697 			}
       
   698 		}
       
   699 
       
   700 	iQLock.Signal();
   683 	}
   701 	}
   684 
   702 
   685 void TDismountNotifyQue::CancelAll(TInt aCompletionCode)
   703 void TDismountNotifyQue::CancelAll(TInt aCompletionCode)
   686 //
   704 //
   687 //
   705 //
   706 		if(((CDismountNotifyInfo*)info)->IsMatching(aMode, aDrive, NULL))
   724 		if(((CDismountNotifyInfo*)info)->IsMatching(aMode, aDrive, NULL))
   707 			{
   725 			{
   708 			__PRINT1(_L("TDismountNotifyQue::CheckDismount()-Matching info=0x%x"),info);
   726 			__PRINT1(_L("TDismountNotifyQue::CheckDismount()-Matching info=0x%x"),info);
   709 			info->Complete(aError);
   727 			info->Complete(aError);
   710 			if(aRemove)
   728 			if(aRemove)
   711 				{
   729 				delete info;
   712 				info->iLink.Deque();
   730 			}
   713 				delete(info);
   731 		}
   714 				}
   732 
   715 			}
   733 	__ASSERT_ALWAYS(!(aRemove && aMode == EFsDismountRegisterClient && TheDrives[aDrive].DismountLocked() > 0), Fault(EDismountLocked));
   716 		}
       
   717 
       
   718 	__ASSERT_ALWAYS(!aRemove || TheDrives[aDrive].DismountLocked() == 0, Fault(EDismountLocked));
       
   719 
   734 
   720 	iQLock.Signal();
   735 	iQLock.Signal();
   721 	}
   736 	}
   722 
   737 
   723 TBool TDismountNotifyQue::HandlePendingDismount(CSessionFs* aSession, TInt aDrive)
   738 TBool TDismountNotifyQue::HandlePendingDismount(CSessionFs* aSession, TInt aDrive)
   724 //
   739 //
   725 // Determine if the session has any outstanding dismount notifications on the specified drive.
   740 // Determine if the session has any outstanding *completed* dismount notifications on the specified drive 
   726 //
   741 // and delete them. Called from TFsAllowDismount::DoRequestL()
   727 	{
   742 //
   728 	iQLock.Wait();
   743 	{
   729 	TDblQueIter<CNotifyInfo> q(iHeader);
   744 	iQLock.Wait();
   730 	CNotifyInfo* info;
   745 	TDblQueIter<CDismountNotifyInfo> q(iHeader);
       
   746 	CDismountNotifyInfo* info;
       
   747 
       
   748 	TBool entryFound = EFalse;
       
   749 
   731 	while((info=q++)!=NULL)
   750 	while((info=q++)!=NULL)
   732 		{
   751 		{
   733 		__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDismount,Fault(EBadDismountNotifyType));
   752 		__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDismount,Fault(EBadDismountNotifyType));
   734 		if(((CDismountNotifyInfo*)info)->IsMatching(EFsDismountRegisterClient, aDrive, aSession))
   753 		if(((CDismountNotifyInfo*)info)->IsMatching(EFsDismountRegisterClient, aDrive, aSession))
   735 			{
   754 			{
   736 			__PRINT1(_L("TDismountNotifyQue::CheckDismount()-Pending info=0x%x"),info);
   755 			__PRINT1(_L("TDismountNotifyQue::HandlePendingDismount()-Pending info=0x%x"),info);
   737 			info->iLink.Deque();
   756 
   738 			delete(info);
   757 			if (info->Completed())
   739 			iQLock.Signal();
   758 				delete info;
   740 			return ETrue;
   759 
   741 			}
   760 			entryFound = ETrue;
   742 		}
   761 			}
   743 	iQLock.Signal();
   762 		}
   744 	return EFalse;
   763 	iQLock.Signal();
       
   764 
       
   765 	return entryFound;
   745 	}
   766 	}
   746 
   767 
   747 void FsNotify::Initialise()
   768 void FsNotify::Initialise()
   748 //
   769 //
   749 //
   770 //
   946 	{
   967 	{
   947 	__PRINT2(_L("FsNotify::CancelDebugSession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
   968 	__PRINT2(_L("FsNotify::CancelDebugSession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
   948 	iDebugQue.CancelSession(aSession,KErrCancel,aStatus);
   969 	iDebugQue.CancelSession(aSession,KErrCancel,aStatus);
   949 	}
   970 	}
   950 
   971 
   951 TInt FsNotify::CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus)
   972 void FsNotify::CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus)
   952 //
   973 //
   953 // Cancel all media removal notification(s) setup by aSession (if aStatus == NULL)
   974 // Cancel all media removal notification(s) setup by aSession (if aStatus == NULL)
   954 // else cancels all outstanding notifications(s) for the session
   975 // else cancels all outstanding notifications(s) for the session
   955 //
   976 //
   956 	{
   977 	{
   957 	__PRINT2(_L("FsNotify::CancelDismountNotifySession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
   978 	__PRINT2(_L("FsNotify::CancelDismountNotifySession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
   958 	TInt drive = iDismountNotifyQue.CancelSession(aSession,KErrCancel,aStatus);
   979 	iDismountNotifyQue.CancelSession(aSession,KErrCancel,aStatus);
   959 	return drive;
       
   960 	}
   980 	}
   961 
   981 
   962 void FsNotify::CancelSession(CSessionFs* aSession)
   982 void FsNotify::CancelSession(CSessionFs* aSession)
   963 //
   983 //
   964 //
   984 //