userlibandfileserver/fileserver/sfile/sf_notifier.cpp
changeset 31 56f325a607ea
parent 0 a41df078684a
child 299 b5a01337d018
--- a/userlibandfileserver/fileserver/sfile/sf_notifier.cpp	Mon Dec 21 16:14:42 2009 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_notifier.cpp	Wed Dec 23 11:43:31 2009 +0000
@@ -750,83 +750,148 @@
 	TBool overflow = EFalse;
 	
 	//Check that we have not filled the buffer
-	//Also if iClientMsg is present this is the first notification
-	if (aServerTail == iClientHead && ClientMsgHandle()==0)
-		{
-		//Overflow
-		overflow = ETrue;
-		return overflow;
-		}
+    if (aServerTail == iClientHead)
+        {
+        // Buffer is empty when Client Tail = Client Head
+        if (iClientHead != iClientTail)
+        	{
+			overflow = ETrue;
+            return overflow;            
+			}
+        }
 
 	//Work out remaining size taking account of whether the end position is
 	//before or after the overflow position.
 	TInt remainingSize = (iClientHead > aServerTail)
 			? iClientHead - aServerTail 
 			: iClientBufferSize - (aServerTail - iClientHead);
-	
-	//In order to ensure that we can always fit in an overflow notification,
-	//Remove the size of an overflow notification from the total free space in the buffer
-	remainingSize -= KNotificationHeaderSize;
+
+    TInt reservedSize = aNotificationSize;
+    // + Save additional space for OVERFLOW
+    reservedSize += KNotificationHeaderSize;
 
-	//Check whether there is any chance of this notification fitting in the buffer
-	if (aNotificationSize > remainingSize)
-		{
-		//Overflow
-		overflow = ETrue;
-		}
-	//Check that the notification fits in a contiguous chunk.
-	//If we've wrapped around already..
-	else if (iClientHead > aServerTail)
-		{
-		//Does it fit?
-		if ((iClientHead - aServerTail) < aNotificationSize)
+	//
+    // Have we wrapped around already?
+    //
+    if (iClientHead > aServerTail)
+        {
+		// Yes,
+		// Buffer looks something like this:
+		//
+        //            |CH             
+        // [5678------1234]
+        //     |ST		
+
+		//
+		//  Check if we can insert in the middle section:
+		//
+		if (remainingSize < reservedSize)
 			{
-			//Overflow
 			overflow = ETrue;
-			}
-		}
-	//Else, We've not wrapped around yet.
-	//Does it fit at the end?
-	else if ((iClientBufferSize - aServerTail) < aNotificationSize)
-		{
-		//Notification won't fit in the space at the end of the buffer
-		//Fill end of buffer with KNotificationBufferFiller (if we're not at the very end already)
-		if(iServerTail != iClientBufferSize)
-			{
-			//If there is any dead space it should always be at least 1 word big
-			TPtrC8 fillerDes((TText8*) &KNotificationBufferFiller, sizeof(TUint));
-			iBufferMsg.Write(KMsgPtr0, fillerDes, aServerTail);
-			}
+			}	
+		//else:
+		// 	{
+		// 	We add new notification to middle 
+        //	[5678***---1234]
+        // 	}
+		//
+		return overflow;
+        }
+
 
-		//It doesn't fit at the end,
-		//does it fit at the beginning?
-		if (iClientHead < aNotificationSize)
-			{
-			//Overflow
-			overflow = ETrue;
-			}
-		//Notification would fit at the beginning...		
-		else
-			{
-			//...however we need to ensure that there is
-			//still space for overflow next time.
-			if ((iClientHead - aNotificationSize) < KNotificationHeaderSize)
-				{
-				overflow = ETrue;
-				}
-			else
-				{
-				//Everything was ok, update aServerTail
-				aServerTail = 0;
-				}
-			}
-		}	
+	//
+    // We have not wrapped around yet..
+    //
+    // Buffer looks something like this:
+    //
+    //    |CH      
+    // [--123456789--]
+    //            |ST
+    //
+
 
 	//
-	//End Validation
+    // Check up-front whether its possible for overflow to go at the beginning.
+    // If there is not enough space at the start for overflow then we need to
+    // check that's there's space for overflow at the end and must not rollover.
+    //
+    TBool canRollOver = ETrue;
+    
+    if (iClientHead < KNotificationHeaderSize)
+        {
+		//
+        //  |CH      
+        // [123456789----]
+        //          |ST
+        //
+        // No space for overflow at the beginning of buffer.
+        //
+        canRollOver = EFalse; 
+        }
+
 	//
-	return overflow;
-	}
+    // IF: Cannot rollover
+    //
+    if (!canRollOver)
+        {
+        //IF (notification + overflow) does not fit at the end overflow now.
+        if ((iClientBufferSize - aServerTail) < reservedSize)
+            {
+            overflow = ETrue;
+            }        
+        //Else
+        //	{
+		//	Add notification (**) to end [---12345678**---]
+		//	}
+
+        }
+    else 
+	// Can rollover  
+	// - need to check that notification fits at the end
+	//   or that notification+overflow fits at the beginning.
+        {
+        // If not enough space at end, rollover
+        if ((iClientBufferSize - aServerTail) < aNotificationSize)
+            {
+			//
+			// Add notification to start and fill end with Filler char 
+            // [----0123456789#]
+            //
+            
+            // IF we are not at the very end of the buffer,
+			// insert a KNotificationBufferFiller at iServerTail.
+			// When the client reads this, it sets iHead to 0 and reads from there.
+			if(iServerTail != iClientBufferSize)
+				{
+				//If there is space it will always be at least 1 word big
+				TPtrC8 fillerDes((TText8*) &KNotificationBufferFiller, sizeof(TUint));
+				iBufferMsg.Write(KMsgPtr0, fillerDes, aServerTail);
+				}
+
+            // Now that we have rolled over we need to check whether there is
+            // space at the beginning for notification + overflow
+			// We already know that overflow fits.
+            if (reservedSize > iClientHead)
+                {
+                //  [ov--0123456789-]
+                overflow = ETrue;
+                }
+			//
+			// Add notification/overflow to the beginning
+			//  	[**--0123456789(#)]
+			//
+			aServerTail = 0;
+			}
+		//
+		// else - notification fits at the end so there is nothing to do here.
+		//
+		//
+        }
+    //
+    //End Validation
+    //
+    return overflow;
+    }
 
 // Called from FsNotificationManager::HandleChange().
 // Sends notifications into the client's buffer.
@@ -988,25 +1053,29 @@
 	
 	//We need to complete if this was the first 
 	//write to the client's buffer
-	if(ClientMsgHandle()!=0 && r==KErrNone)
-		{
-		__PRINT4(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
-		CompleteClientRequest(KErrNone);
-		}
-	else if(!overflow)
-		{
+    if (r == KErrNone)
+        {
+		//We need to complete if this was the first 
+		//write to the client's buffer
+        if(ClientMsgHandle()!=0)
+            {
+			//RDebug::Print(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
+            __PRINT4(_L("CFsNotifyRequest::NotifyChange iClientHead(%d) iClientTail(%d) iServerTail(%d) iClientBufferSize(%d)"),iClientHead,iClientTail,iServerTail,iClientBufferSize);
+            CompleteClientRequest(KErrNone);
+            }
+        else if(!overflow)
+            {
 		SetActive(CFsNotifyRequest::EOutstanding);
-		}
-	else
-		{
+            }
+        else //Overflow
+            {
 		SetActive(CFsNotifyRequest::EOutstandingOverflow);
-		}
-	
-	if(r!= KErrNone)
+            }
+        }
+	else // r!=KErrNone
 		{
 		//RDebug::Print(_L("sf_notifier.cpp line %d function = %d, r = %d"),__LINE__, aRequest->FsFunction(),r);
 		//RDebug::Print(_L("iServerTail=%d, tail=%d, iClientBufferSize=%d, overflow=%d"),iServerTail,tail,iClientBufferSize,overflow);
-		SetActive(CFsNotifyRequest::EInactive);
 		}
 	return r;
 	}