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 |