userlibandfileserver/fileserver/sfile/sf_request.cpp
branchRCL_3
changeset 21 e7d2d738d3c2
parent 2 4122176ea935
child 42 a179b74831c9
equal deleted inserted replaced
20:597aaf25e343 21:e7d2d738d3c2
    25 TParse dummyP;
    25 TParse dummyP;
    26 RMessage2 dummyM;
    26 RMessage2 dummyM;
    27 
    27 
    28 CFsClientMessageRequest* RequestAllocator::iFreeHead;				
    28 CFsClientMessageRequest* RequestAllocator::iFreeHead;				
    29 CFsClientMessageRequest* RequestAllocator::iCloseHead;
    29 CFsClientMessageRequest* RequestAllocator::iCloseHead;
    30 TInt RequestAllocator::iAllocNum;
    30 TInt RequestAllocator::iRequestCount;
    31 TInt RequestAllocator::iAllocNumOperation;
    31 TInt RequestAllocator::iFreeCount;
    32 TMsgOperation* RequestAllocator::iFreeHeadSupOp;
    32 TInt RequestAllocator::iRequestCountPeak;
    33 
       
    34 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
    35 TInt RequestAllocator::iAllocated;
       
    36 #endif
       
    37 RFastLock RequestAllocator::iCacheLock;
    33 RFastLock RequestAllocator::iCacheLock;
    38 
    34 
    39 void RequestAllocator::Initialise()
    35 TMsgOperation* OperationAllocator::iFreeHead;				
       
    36 TInt OperationAllocator::iRequestCount;
       
    37 TInt OperationAllocator::iFreeCount;
       
    38 TInt OperationAllocator::iRequestCountPeak;
       
    39 RFastLock OperationAllocator::iCacheLock;
       
    40 
       
    41 TInt RequestAllocator::Initialise()
    40 	{	
    42 	{	
    41 	iFreeHead=NULL;  
    43 	iFreeHead = NULL;  
    42 	iCloseHead=NULL; 
    44 	iCloseHead = NULL; 
    43 	iAllocNum=0; 
    45 	iRequestCount = 0; 
    44 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
    46 	iFreeCount = 0;
    45 	iAllocated=0;
    47 	iRequestCountPeak = 0;
    46 #endif
    48 	return iCacheLock.CreateLocal();
    47 	iAllocNumOperation=0;
    49 	}
    48 	iFreeHeadSupOp=NULL;
    50 
    49 	}
    51 void RequestAllocator::FreeRequest(CFsClientMessageRequest* aRequest)
    50 
    52 //
    51 TInt RequestAllocator::AllocRequest(TInt aNum)
    53 //free request 
    52 //
    54 //
    53 //	Allocates a group of request objects
    55 	{
    54 //
    56 	__CACHE_PRINT1(_L("RequestAllocator::FreeRequest for %x"), aRequest);
    55 	{
    57 	ASSERT(aRequest != NULL);
    56     TInt i;
    58 	iCacheLock.Wait();
    57 	if(iAllocNum < KMaxRequestAllocated)
    59 	if (iFreeCount >= KFreeCountMax)
    58 		{
    60 		{
    59 		__CACHE_PRINT(_L("RequestAllocator::AllocRequest() Not reached the limit"));
    61 		delete aRequest;
    60 		CFsClientMessageRequest* list;
    62 		ASSERT(iRequestCount > 0);
    61 		CFsClientMessageRequest* start;
    63 		iRequestCount--;
    62 		list = new CFsClientMessageRequest[KAllocReqBlock];
       
    63 		start = list;
       
    64 		if(!list)
       
    65 			return KErrNoMemory;
       
    66 		
       
    67 		// Make sure the constructors are called for every element in the array
       
    68 		// - some compilers don't do this
       
    69 		for(TInt j=0; j<KAllocReqBlock; j++)
       
    70 			{
       
    71 			CFsClientMessageRequest* request = &list[j];
       
    72 			new(request) CFsClientMessageRequest();
       
    73 			}
       
    74 
       
    75 		iAllocNum += KAllocReqBlock;
       
    76 		CFsClientMessageRequest* last;
       
    77 		for(i=1;i<KAllocReqBlock;i++)
       
    78 			{
       
    79 			last = list;
       
    80 			list++;
       
    81 			last->iNext = list;
       
    82 			}
       
    83 		list->iNext = iFreeHead;
       
    84 		iFreeHead = start;
       
    85 		return KErrNone;
       
    86 		}
    64 		}
    87 	else
    65 	else
    88 		{
    66 		{
    89 		__CACHE_PRINT1(_L("RequestAllocator::AllocRequest() Limit exceeded Count = %d"),aNum);
    67 		aRequest->SetSubstedDrive(NULL);
    90 		CFsClientMessageRequest* request;
    68 		aRequest->iNext = iFreeHead;
    91 		for(i=0;i<aNum;i++)
    69 		iFreeHead=aRequest;
    92 			{
    70 		iFreeCount++;
    93 			request=new CFsClientMessageRequest;
    71 		}
    94 			if(!request)
       
    95 				return KErrNoMemory;
       
    96 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
    97 			iAllocated++;
       
    98 #endif
       
    99 			request->SetAllocated();
       
   100 			request->iNext=iFreeHead;
       
   101 			iFreeHead=request;
       
   102 			}
       
   103 		return KErrNone;
       
   104 		}
       
   105 	}
       
   106 
       
   107 void RequestAllocator::FreeRequest(CFsClientMessageRequest* aRequest)
       
   108 //
       
   109 //free request 
       
   110 //
       
   111 	{
       
   112 	__CACHE_PRINT1(_L("PLUGIN: RequestAllocator::FreeRequest for %x"), aRequest);
       
   113 	if(aRequest->IsAllocated())
       
   114 		{
       
   115 		__CACHE_PRINT(_L("RequestAllocator::FreeRequest() Allocated request"));
       
   116 		delete(aRequest);
       
   117 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   118 		iAllocated--;
       
   119 #endif
       
   120 		return;
       
   121 		}
       
   122 	
       
   123 	__CACHE_PRINT(_L("RequestAllocator::FreeRequest() returning to free list"));
       
   124 	iCacheLock.Wait();
       
   125 	aRequest->iNext = iFreeHead;
       
   126 	iFreeHead=aRequest;
       
   127 	aRequest->SetSubstedDrive(NULL);
       
   128 	iCacheLock.Signal();
    72 	iCacheLock.Signal();
   129 	}
    73 	}
   130 
    74 
   131 void RequestAllocator::OpenSubFailed(CSessionFs* aSession)
    75 void RequestAllocator::OpenSubFailed(CSessionFs* aSession)
   132 //
    76 //
   133 //	Move requst from closed list to free list
    77 //	Move request from closed list to free list
   134 //
    78 //
   135 	{
    79 	{
   136 	__ASSERT_DEBUG(iCloseHead!=NULL,Fault(ERequestAllocatorOpenSubFailed)); // On arriving here Close Queue is supposed to be empty
    80 	__ASSERT_DEBUG(iCloseHead!=NULL,Fault(ERequestAllocatorOpenSubFailed)); // On arriving here Close Queue is supposed to be empty
   137 	__ASSERT_ALWAYS(aSession!=NULL,Fault(ERequestAllocatorOpenSubFailed));
    81 	__ASSERT_ALWAYS(aSession!=NULL,Fault(ERequestAllocatorOpenSubFailed));
   138 	if (iCloseHead==NULL)
    82 	if (iCloseHead==NULL)
   140 		return;
    84 		return;
   141 		}
    85 		}
   142 	iCacheLock.Wait();
    86 	iCacheLock.Wait();
   143 	CFsClientMessageRequest* rp = iCloseHead;
    87 	CFsClientMessageRequest* rp = iCloseHead;
   144 	iCloseHead = rp->iNext;
    88 	iCloseHead = rp->iNext;
       
    89 	iCacheLock.Signal();
   145 	
    90 	
   146 	// dec the number of closed requests owned by this session
    91 	// dec the number of closed requests owned by this session
   147 	aSession->CloseRequestCountDec();
    92 	aSession->CloseRequestCountDec();
   148 
    93 
   149 	rp->iNext = NULL;
    94 	__CACHE_PRINT1(_L("RequestAllocator::OpenSubFailed() IsAllocated %d"), rp->IsAllocated());
   150 	if(rp->IsAllocated())
    95 	FreeRequest(rp);
   151 		{
    96 	}
   152 		__CACHE_PRINT(_L("RequestAllocator::OpenSubFailed() Allocated request"));
    97 
   153 		delete(rp);
    98 CFsClientMessageRequest* RequestAllocator::GetRequest()
   154 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
    99 //
   155 		iAllocated--;
   100 // Get request from the free queue
   156 #endif
   101 //
       
   102 	{
       
   103 	CFsClientMessageRequest* request;
       
   104 	if (iFreeHead == NULL)
       
   105 		{
       
   106 		request = new CFsClientMessageRequest;
       
   107 		if (request)
       
   108 			{
       
   109 			iRequestCount++;
       
   110 			iRequestCountPeak = Max(iRequestCountPeak, iRequestCount);
       
   111 			}
   157 		}
   112 		}
   158 	else
   113 	else
   159 		{
   114 		{
   160 		__CACHE_PRINT(_L("RequestAllocator::OpenSubFailed()"));
   115 		request = iFreeHead;
   161 		if(iFreeHead)
   116 		iFreeHead = iFreeHead->iNext;
   162 			{
   117 		request->iNext = NULL;
   163 			rp->iNext = iFreeHead;
   118 		iFreeCount--;
   164 			}
   119 		ASSERT(iFreeCount >= 0);
   165 		else
   120 		}
   166 			{
   121 	return request;
   167 			rp->iNext = NULL;
       
   168 			}
       
   169 
       
   170 		iFreeHead = rp;		
       
   171 		}
       
   172 	iCacheLock.Signal();
       
   173 	}
   122 	}
   174 
   123 
   175 TInt RequestAllocator::GetMessageRequest(const TOperation& aOperation,const RMessage2& aMessage,CFsClientMessageRequest* &aRequest)
   124 TInt RequestAllocator::GetMessageRequest(const TOperation& aOperation,const RMessage2& aMessage,CFsClientMessageRequest* &aRequest)
   176 //
   125 //
   177 //	tries to get a pre allocated message from the cache. Failing that allocates one indivisualy 
   126 //	tries to get a pre allocated message from the cache. Failing that allocates one indivisualy 
   179 	{
   128 	{
   180 	if(aOperation.IsOpenSubSess())
   129 	if(aOperation.IsOpenSubSess())
   181 		{
   130 		{
   182 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() Open sub-sess"));
   131 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() Open sub-sess"));
   183 		iCacheLock.Wait();
   132 		iCacheLock.Wait();
   184 		if(iFreeHead == NULL || iFreeHead->iNext == NULL)
   133 
   185 			{
   134 		aRequest = GetRequest();
   186 			if(AllocRequest(2)!= KErrNone)
   135 		CFsClientMessageRequest* closeRequest = GetRequest();
   187 				{
   136 		
   188 				iCacheLock.Signal();
   137 		if (aRequest == NULL || closeRequest == NULL)
   189 				return KErrNoMemory;
   138 			{
   190 				}
   139 			delete aRequest;
   191 			}
   140 			delete closeRequest;
   192 		aRequest= iFreeHead;						//get our request from free head
   141 			iCacheLock.Signal();
   193 		iFreeHead = iFreeHead->iNext->iNext;	//set next but one as new free head read for next
   142 			return KErrNoMemory;
   194 
   143 			}
   195 		aRequest->iNext->iNext = NULL;				//seperate our request and close from free list
   144 
   196 		CFsClientMessageRequest* CRp = aRequest->iNext;
   145 		closeRequest->iNext = iCloseHead;		//set second one as a reserved (tail) close request
   197 		aRequest->iNext = NULL;
   146 		iCloseHead = closeRequest;
   198 		if(iCloseHead)
       
   199 			{
       
   200 			CRp->iNext = iCloseHead;		//set second one as a reserved (tail) close request
       
   201 			iCloseHead = CRp;
       
   202 			}
       
   203 		else
       
   204 			iCloseHead = CRp;
       
   205 		
   147 		
   206 		((CSessionFs*) aMessage.Session())->CloseRequestCountInc();
   148 		((CSessionFs*) aMessage.Session())->CloseRequestCountInc();
   207 		}
   149 		}
   208 	else if(aOperation.IsCloseSubSess())
   150 	else if(aOperation.IsCloseSubSess())
   209 		{
   151 		{
   270 			default:
   212 			default:
   271 				Fault(ECloseSubBadMessage);
   213 				Fault(ECloseSubBadMessage);
   272 			}
   214 			}
   273 
   215 
   274 		iCacheLock.Wait();
   216 		iCacheLock.Wait();
       
   217 		ASSERT(iCloseHead);
   275 		aRequest = iCloseHead;
   218 		aRequest = iCloseHead;
   276 		iCloseHead = aRequest->iNext;
   219 		iCloseHead = aRequest->iNext;
   277 		((CSessionFs*) aMessage.Session())->CloseRequestCountDec();
   220 		((CSessionFs*) aMessage.Session())->CloseRequestCountDec();
   278 		aRequest->iNext = NULL;
   221 		aRequest->iNext = NULL;
   279 
   222 
   287 		}
   230 		}
   288 	else
   231 	else
   289 		{
   232 		{
   290 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() "));
   233 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() "));
   291 		iCacheLock.Wait();
   234 		iCacheLock.Wait();
   292 		if(!iFreeHead)
   235 		aRequest = GetRequest();
   293 			{
   236 		if (aRequest == NULL)
   294 			if(AllocRequest(1) != KErrNone)
   237 			{
   295 				{
   238 			iCacheLock.Signal();
   296 				iCacheLock.Signal();
   239 			return KErrNoMemory; 
   297 				return KErrNoMemory; 
   240 			}
   298 				}
       
   299 			}
       
   300 		aRequest = iFreeHead;						
       
   301 		iFreeHead = aRequest->iNext;
       
   302 		aRequest->iNext= NULL;
       
   303 		}
   241 		}
   304 
   242 
   305 	aRequest->Init();
   243 	aRequest->Init();
   306 
   244 
   307 	iCacheLock.Signal();
   245 	iCacheLock.Signal();
   320 
   258 
   321 
   259 
   322 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
   260 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
   323 TInt RequestAllocator::CloseCount()
   261 TInt RequestAllocator::CloseCount()
   324 	{TInt count=0;
   262 	{TInt count=0;
       
   263 	iCacheLock.Wait();
       
   264 
   325 	CFsClientMessageRequest* list=iCloseHead;
   265 	CFsClientMessageRequest* list=iCloseHead;
   326 	while(list!=NULL)
   266 	while(list!=NULL)
   327 		{
   267 		{
   328 		count++;
   268 		count++;
   329 		list=list->iNext;
   269 		list=list->iNext;
   330 		}
   270 		}
       
   271 
       
   272 	iCacheLock.Signal();
   331 	return(count);
   273 	return(count);
   332 	} 
   274 	} 
   333 TInt RequestAllocator::FreeCount()
   275 TInt RequestAllocator::FreeCount()
   334 	{
   276 	{
   335 	TInt count=0;
   277 	TInt count=0;
       
   278 	iCacheLock.Wait();
   336 	CFsClientMessageRequest* list=iFreeHead;
   279 	CFsClientMessageRequest* list=iFreeHead;
   337 	while(list!=NULL)
   280 	while(list!=NULL)
   338 		{
   281 		{
   339 		count++;
   282 		count++;
   340 		list=list->iNext;
   283 		list=list->iNext;
   341 		}
   284 		}
   342 	return(count);}
   285 	ASSERT(count == iFreeCount);
       
   286 	iCacheLock.Signal();
       
   287 	return(count);
       
   288 	}
   343 #endif
   289 #endif
   344 
   290 
   345 TInt RequestAllocator::AllocOperation()
   291 TInt OperationAllocator::Initialise()
   346 //
   292 	{	
   347 //	Allocates a group of TMsgOperation objects
   293 	iFreeHead = NULL;  
   348 //
   294 	iRequestCount = 0; 
   349 // Must be called with iCacheLock held
   295 	iFreeCount = 0;
   350 	{
   296 	return iCacheLock.CreateLocal();
   351     TInt i;
   297 	}
   352 	if(iAllocNumOperation < KMaxOperationAllocated)
   298 
   353 		{
   299 void OperationAllocator::FreeOperation(TMsgOperation* aOperation)
   354 		__CACHE_PRINT(_L("RequestAllocator::AllocOperation() Not reached the limit"));
   300 //
   355 		TMsgOperation* list;
   301 // free Operation
   356 		TMsgOperation* start;
   302 //
   357 		list = new TMsgOperation[KAllocReqBlock];
   303 	{
   358 		start = list;
   304 	__CACHE_PRINT1(_L("RequestAllocator::FreeOperation() returning %x to free list"), aOperation);
   359 		if(!list)
   305 	ASSERT(aOperation != NULL);
   360 			return KErrNoMemory;
   306 	iCacheLock.Wait();
   361 		
   307 	if (iFreeCount >= KFreeCountMax)
   362 		for(TInt j=0; j<KAllocReqBlock; j++)
   308 		{
   363 			{
   309 		delete aOperation;
   364 			TMsgOperation* request = &list[j];
   310 		ASSERT(iRequestCount > 0);
   365 			request->iIsAllocated = EFalse;
   311 		iRequestCount--;
   366 			}
       
   367 
       
   368 		iAllocNumOperation += KAllocReqBlock;
       
   369 		TMsgOperation* last;
       
   370 		for(i=1;i<KAllocReqBlock;i++)
       
   371 			{
       
   372 			last = list;
       
   373 			list++;
       
   374 			last->iNext = list;
       
   375 			}
       
   376 		list->iNext = iFreeHeadSupOp;
       
   377 		iFreeHeadSupOp = start;
       
   378 		return KErrNone;
       
   379 		}
   312 		}
   380 	else
   313 	else
   381 		{
   314 		{
   382 		__CACHE_PRINT(_L("RequestAllocator::AllocOperation() Limit exceeded"));
   315 		aOperation->iNext = iFreeHead;
   383 		TMsgOperation* request;
   316 		iFreeHead = aOperation;
   384 
   317 		iFreeCount++;
   385 		request=new TMsgOperation;
   318 		}
   386 		if(!request)
   319 
   387 			return KErrNoMemory;
   320 	iCacheLock.Signal();
   388 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
   321 	}
   389 		iAllocated++;
   322 
   390 #endif
   323 TInt OperationAllocator::GetOperation(TMsgOperation* &aOperation)
   391 		request->iIsAllocated = ETrue;
       
   392 		request->iNext=iFreeHeadSupOp;
       
   393 		iFreeHeadSupOp=request;
       
   394 
       
   395 		return KErrNone;
       
   396 		}
       
   397 	}
       
   398 TInt RequestAllocator::GetOperation(TMsgOperation* &aOperation)
       
   399 //
   324 //
   400 //	tries to get a pre allocated subop from the cache. Failing that allocates one individualy 
   325 //	tries to get a pre allocated subop from the cache. Failing that allocates one individualy 
   401 //	
   326 //	
   402 	{
   327 	{
   403 
   328 
   404 	__CACHE_PRINT(_L("RequestAllocator::GetOperation() "));
   329 	__CACHE_PRINT(_L("RequestAllocator::GetOperation() "));
       
   330 
   405 	iCacheLock.Wait();
   331 	iCacheLock.Wait();
   406 	if(!iFreeHeadSupOp)
   332 
   407 		{
   333 	TInt r = KErrNone;
   408 		if(AllocOperation() != KErrNone)
   334 	if (iFreeHead == NULL)
   409 			{
   335 		{
   410 			iCacheLock.Signal();
   336 		aOperation = new TMsgOperation;
   411 			return KErrNoMemory; 
   337 		if (aOperation == NULL)
   412 			}
   338 			r = KErrNoMemory; 
   413 		}
   339 		else
   414 	aOperation = iFreeHeadSupOp;						
   340 			{
   415 	iFreeHeadSupOp = aOperation->iNext;
   341 			iRequestCount++;
   416 	aOperation->iNext = aOperation->iPrev = NULL;
   342 			iRequestCountPeak = Max(iRequestCountPeak, iRequestCount);
       
   343 			}
       
   344 		}
       
   345 	else
       
   346 		{
       
   347 		aOperation = iFreeHead;
       
   348 		iFreeHead = iFreeHead->iNext;
       
   349 		iFreeCount--;
       
   350 		ASSERT(iFreeCount >= 0);
       
   351 		}
       
   352 
       
   353 	if (aOperation)
       
   354 		aOperation->iNext = aOperation->iPrev = NULL;
   417 
   355 
   418 	iCacheLock.Signal();
   356 	iCacheLock.Signal();
   419 	return KErrNone;
   357 	return r;
   420 	}	
   358 	}	
   421 
       
   422 void RequestAllocator::FreeOperation(TMsgOperation* aOperation)
       
   423 //
       
   424 // free Operation
       
   425 //
       
   426 	{
       
   427 	if(aOperation->iIsAllocated)
       
   428 		{
       
   429 		__CACHE_PRINT(_L("RequestAllocator::FreeOperation() Allocated subop"));
       
   430 		delete(aOperation);
       
   431 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   432 		iAllocated--;
       
   433 #endif
       
   434 		return;
       
   435 		}
       
   436 	
       
   437 	__CACHE_PRINT(_L("RequestAllocator::FreeOperation() returning to free list"));
       
   438 	iCacheLock.Wait();
       
   439 	aOperation->iNext = iFreeHeadSupOp;	// NB backward link only used when request in in use
       
   440 	iFreeHeadSupOp = aOperation;
       
   441 
       
   442 	iCacheLock.Signal();
       
   443 	}
       
   444 
   359 
   445 
   360 
   446 CFsRequest::CFsRequest()
   361 CFsRequest::CFsRequest()
   447 //
   362 //
   448 //
   363 //
  1819 	}
  1734 	}
  1820 
  1735 
  1821 TInt CFsMessageRequest::PushOperation(TFsRequestFunc aCallback, TInt aNextState, TInt aFunction)
  1736 TInt CFsMessageRequest::PushOperation(TFsRequestFunc aCallback, TInt aNextState, TInt aFunction)
  1822 	{
  1737 	{
  1823 	TMsgOperation* nextOperation;
  1738 	TMsgOperation* nextOperation;
  1824 	TInt r = RequestAllocator::GetOperation(nextOperation);
  1739 	TInt r = OperationAllocator::GetOperation(nextOperation);
  1825 	if (r != KErrNone)
  1740 	if (r != KErrNone)
  1826 		return r;
  1741 		return r;
  1827 
  1742 
  1828 	
  1743 	
  1829 	// Store the caller's state etc in the CURRENT TMsgOperation (if there is one)
  1744 	// Store the caller's state etc in the CURRENT TMsgOperation (if there is one)
  1947 		
  1862 		
  1948 		if (iCurrentOperation->iFunction != iOperation->Function())
  1863 		if (iCurrentOperation->iFunction != iOperation->Function())
  1949 			SetOperationFunc(iCurrentOperation->iFunction);
  1864 			SetOperationFunc(iCurrentOperation->iFunction);
  1950 		}
  1865 		}
  1951 
  1866 
  1952 	RequestAllocator::FreeOperation(currentOperation);
  1867 	OperationAllocator::FreeOperation(currentOperation);
  1953 	}
  1868 	}
  1954 
  1869 
  1955 TMsgOperation& CFsMessageRequest::CurrentOperation()
  1870 TMsgOperation& CFsMessageRequest::CurrentOperation()
  1956 	{
  1871 	{
  1957 	__ASSERT_ALWAYS(iCurrentOperation != NULL, Fault(EInvalidOperationIndex));
  1872 	__ASSERT_ALWAYS(iCurrentOperation != NULL, Fault(EInvalidOperationIndex));