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 { |
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 // |