userlibandfileserver/fileserver/sfile/sf_notifier.cpp
changeset 31 56f325a607ea
parent 0 a41df078684a
child 299 b5a01337d018
equal deleted inserted replaced
15:4122176ea935 31:56f325a607ea
   748 	//Start Validation
   748 	//Start Validation
   749 	//
   749 	//
   750 	TBool overflow = EFalse;
   750 	TBool overflow = EFalse;
   751 	
   751 	
   752 	//Check that we have not filled the buffer
   752 	//Check that we have not filled the buffer
   753 	//Also if iClientMsg is present this is the first notification
   753     if (aServerTail == iClientHead)
   754 	if (aServerTail == iClientHead && ClientMsgHandle()==0)
   754         {
   755 		{
   755         // Buffer is empty when Client Tail = Client Head
   756 		//Overflow
   756         if (iClientHead != iClientTail)
   757 		overflow = ETrue;
   757         	{
   758 		return overflow;
   758 			overflow = ETrue;
   759 		}
   759             return overflow;            
       
   760 			}
       
   761         }
   760 
   762 
   761 	//Work out remaining size taking account of whether the end position is
   763 	//Work out remaining size taking account of whether the end position is
   762 	//before or after the overflow position.
   764 	//before or after the overflow position.
   763 	TInt remainingSize = (iClientHead > aServerTail)
   765 	TInt remainingSize = (iClientHead > aServerTail)
   764 			? iClientHead - aServerTail 
   766 			? iClientHead - aServerTail 
   765 			: iClientBufferSize - (aServerTail - iClientHead);
   767 			: iClientBufferSize - (aServerTail - iClientHead);
   766 	
   768 
   767 	//In order to ensure that we can always fit in an overflow notification,
   769     TInt reservedSize = aNotificationSize;
   768 	//Remove the size of an overflow notification from the total free space in the buffer
   770     // + Save additional space for OVERFLOW
   769 	remainingSize -= KNotificationHeaderSize;
   771     reservedSize += KNotificationHeaderSize;
   770 
   772 
   771 	//Check whether there is any chance of this notification fitting in the buffer
   773 	//
   772 	if (aNotificationSize > remainingSize)
   774     // Have we wrapped around already?
   773 		{
   775     //
   774 		//Overflow
   776     if (iClientHead > aServerTail)
   775 		overflow = ETrue;
   777         {
   776 		}
   778 		// Yes,
   777 	//Check that the notification fits in a contiguous chunk.
   779 		// Buffer looks something like this:
   778 	//If we've wrapped around already..
   780 		//
   779 	else if (iClientHead > aServerTail)
   781         //            |CH             
   780 		{
   782         // [5678------1234]
   781 		//Does it fit?
   783         //     |ST		
   782 		if ((iClientHead - aServerTail) < aNotificationSize)
   784 
   783 			{
   785 		//
   784 			//Overflow
   786 		//  Check if we can insert in the middle section:
       
   787 		//
       
   788 		if (remainingSize < reservedSize)
       
   789 			{
   785 			overflow = ETrue;
   790 			overflow = ETrue;
   786 			}
   791 			}	
   787 		}
   792 		//else:
   788 	//Else, We've not wrapped around yet.
   793 		// 	{
   789 	//Does it fit at the end?
   794 		// 	We add new notification to middle 
   790 	else if ((iClientBufferSize - aServerTail) < aNotificationSize)
   795         //	[5678***---1234]
   791 		{
   796         // 	}
   792 		//Notification won't fit in the space at the end of the buffer
   797 		//
   793 		//Fill end of buffer with KNotificationBufferFiller (if we're not at the very end already)
   798 		return overflow;
   794 		if(iServerTail != iClientBufferSize)
   799         }
   795 			{
   800 
   796 			//If there is any dead space it should always be at least 1 word big
   801 
   797 			TPtrC8 fillerDes((TText8*) &KNotificationBufferFiller, sizeof(TUint));
   802 	//
   798 			iBufferMsg.Write(KMsgPtr0, fillerDes, aServerTail);
   803     // We have not wrapped around yet..
   799 			}
   804     //
   800 
   805     // Buffer looks something like this:
   801 		//It doesn't fit at the end,
   806     //
   802 		//does it fit at the beginning?
   807     //    |CH      
   803 		if (iClientHead < aNotificationSize)
   808     // [--123456789--]
   804 			{
   809     //            |ST
   805 			//Overflow
   810     //
   806 			overflow = ETrue;
   811 
   807 			}
   812 
   808 		//Notification would fit at the beginning...		
   813 	//
   809 		else
   814     // Check up-front whether its possible for overflow to go at the beginning.
   810 			{
   815     // If there is not enough space at the start for overflow then we need to
   811 			//...however we need to ensure that there is
   816     // check that's there's space for overflow at the end and must not rollover.
   812 			//still space for overflow next time.
   817     //
   813 			if ((iClientHead - aNotificationSize) < KNotificationHeaderSize)
   818     TBool canRollOver = ETrue;
       
   819     
       
   820     if (iClientHead < KNotificationHeaderSize)
       
   821         {
       
   822 		//
       
   823         //  |CH      
       
   824         // [123456789----]
       
   825         //          |ST
       
   826         //
       
   827         // No space for overflow at the beginning of buffer.
       
   828         //
       
   829         canRollOver = EFalse; 
       
   830         }
       
   831 
       
   832 	//
       
   833     // IF: Cannot rollover
       
   834     //
       
   835     if (!canRollOver)
       
   836         {
       
   837         //IF (notification + overflow) does not fit at the end overflow now.
       
   838         if ((iClientBufferSize - aServerTail) < reservedSize)
       
   839             {
       
   840             overflow = ETrue;
       
   841             }        
       
   842         //Else
       
   843         //	{
       
   844 		//	Add notification (**) to end [---12345678**---]
       
   845 		//	}
       
   846 
       
   847         }
       
   848     else 
       
   849 	// Can rollover  
       
   850 	// - need to check that notification fits at the end
       
   851 	//   or that notification+overflow fits at the beginning.
       
   852         {
       
   853         // If not enough space at end, rollover
       
   854         if ((iClientBufferSize - aServerTail) < aNotificationSize)
       
   855             {
       
   856 			//
       
   857 			// Add notification to start and fill end with Filler char 
       
   858             // [----0123456789#]
       
   859             //
       
   860             
       
   861             // IF we are not at the very end of the buffer,
       
   862 			// insert a KNotificationBufferFiller at iServerTail.
       
   863 			// When the client reads this, it sets iHead to 0 and reads from there.
       
   864 			if(iServerTail != iClientBufferSize)
   814 				{
   865 				{
   815 				overflow = ETrue;
   866 				//If there is space it will always be at least 1 word big
       
   867 				TPtrC8 fillerDes((TText8*) &KNotificationBufferFiller, sizeof(TUint));
       
   868 				iBufferMsg.Write(KMsgPtr0, fillerDes, aServerTail);
   816 				}
   869 				}
   817 			else
   870 
   818 				{
   871             // Now that we have rolled over we need to check whether there is
   819 				//Everything was ok, update aServerTail
   872             // space at the beginning for notification + overflow
   820 				aServerTail = 0;
   873 			// We already know that overflow fits.
   821 				}
   874             if (reservedSize > iClientHead)
   822 			}
   875                 {
   823 		}	
   876                 //  [ov--0123456789-]
   824 
   877                 overflow = ETrue;
   825 	//
   878                 }
   826 	//End Validation
   879 			//
   827 	//
   880 			// Add notification/overflow to the beginning
   828 	return overflow;
   881 			//  	[**--0123456789(#)]
   829 	}
   882 			//
       
   883 			aServerTail = 0;
       
   884 			}
       
   885 		//
       
   886 		// else - notification fits at the end so there is nothing to do here.
       
   887 		//
       
   888 		//
       
   889         }
       
   890     //
       
   891     //End Validation
       
   892     //
       
   893     return overflow;
       
   894     }
   830 
   895 
   831 // Called from FsNotificationManager::HandleChange().
   896 // Called from FsNotificationManager::HandleChange().
   832 // Sends notifications into the client's buffer.
   897 // Sends notifications into the client's buffer.
   833 // If there is a iClientMsg then this is the first time this
   898 // If there is a iClientMsg then this is the first time this
   834 // has been called since the client called RequestNotifications.
   899 // has been called since the client called RequestNotifications.
   986 	//This signal moves when we have a cache system
  1051 	//This signal moves when we have a cache system
   987 	iClientSyncLock.Signal();
  1052 	iClientSyncLock.Signal();
   988 	
  1053 	
   989 	//We need to complete if this was the first 
  1054 	//We need to complete if this was the first 
   990 	//write to the client's buffer
  1055 	//write to the client's buffer
   991 	if(ClientMsgHandle()!=0 && r==KErrNone)
  1056     if (r == KErrNone)
   992 		{
  1057         {
   993 		__PRINT4(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
  1058 		//We need to complete if this was the first 
   994 		CompleteClientRequest(KErrNone);
  1059 		//write to the client's buffer
   995 		}
  1060         if(ClientMsgHandle()!=0)
   996 	else if(!overflow)
  1061             {
   997 		{
  1062 			//RDebug::Print(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
       
  1063             __PRINT4(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
       
  1064             CompleteClientRequest(KErrNone);
       
  1065             }
       
  1066         else if(!overflow)
       
  1067             {
   998 		SetActive(CFsNotifyRequest::EOutstanding);
  1068 		SetActive(CFsNotifyRequest::EOutstanding);
   999 		}
  1069             }
  1000 	else
  1070         else //Overflow
  1001 		{
  1071             {
  1002 		SetActive(CFsNotifyRequest::EOutstandingOverflow);
  1072 		SetActive(CFsNotifyRequest::EOutstandingOverflow);
  1003 		}
  1073             }
  1004 	
  1074         }
  1005 	if(r!= KErrNone)
  1075 	else // r!=KErrNone
  1006 		{
  1076 		{
  1007 		//RDebug::Print(_L("sf_notifier.cpp line %d function = %d, r = %d"),__LINE__, aRequest->FsFunction(),r);
  1077 		//RDebug::Print(_L("sf_notifier.cpp line %d function = %d, r = %d"),__LINE__, aRequest->FsFunction(),r);
  1008 		//RDebug::Print(_L("iServerTail=%d, tail=%d, iClientBufferSize=%d, overflow=%d"),iServerTail,tail,iClientBufferSize,overflow);
  1078 		//RDebug::Print(_L("iServerTail=%d, tail=%d, iClientBufferSize=%d, overflow=%d"),iServerTail,tail,iClientBufferSize,overflow);
  1009 		SetActive(CFsNotifyRequest::EInactive);
       
  1010 		}
  1079 		}
  1011 	return r;
  1080 	return r;
  1012 	}
  1081 	}
  1013 
  1082 
  1014 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
  1083 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION