--- 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;
}