20 #include "sf_memory_man.h" |
20 #include "sf_memory_man.h" |
21 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
21 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
22 #include "sf_notifier.h" |
22 #include "sf_notifier.h" |
23 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
23 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
24 |
24 |
|
25 TInt CancelAsyncRequests(CSessionFs* aSession); |
|
26 |
|
27 |
25 CSessionFs::CSessionFs() |
28 CSessionFs::CSessionFs() |
26 :iSessionFlags((TInt)EFsSessionFlagsAll), |
29 :iSessionFlags((TInt)EFsSessionFlagsAll), |
27 iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)), |
30 iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)), |
28 iId(0) |
31 iId(0), iAccessCount(1) |
29 { |
32 { |
30 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
33 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
31 __e32_atomic_add_ord32(&SessionCount, 1); |
34 __e32_atomic_add_ord32(&SessionCount, 1); |
32 #endif |
35 #endif |
33 } |
36 } |
39 |
42 |
40 CSessionFs::~CSessionFs() |
43 CSessionFs::~CSessionFs() |
41 { |
44 { |
42 __PRINT1(_L("CSessionFs::~CSessionFs() deleting... = 0x%x"),this); |
45 __PRINT1(_L("CSessionFs::~CSessionFs() deleting... = 0x%x"),this); |
43 |
46 |
|
47 FsNotify::CancelSession(this); |
|
48 |
|
49 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
|
50 FsNotificationManager::RemoveNotificationRequest(this); |
|
51 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
|
52 |
|
53 |
44 //take out all the reserved space set by this session |
54 //take out all the reserved space set by this session |
45 while(iReservedDriveAccess.Count()) |
55 while(iReservedDriveAccess.Count()) |
46 { |
56 { |
47 TReservedDriveAccess& reserved = iReservedDriveAccess[0]; |
57 TReservedDriveAccess& reserved = iReservedDriveAccess[0]; |
48 if(reserved.iReservedSpace) |
58 if(reserved.iReservedSpace) |
63 delete iHandles; |
73 delete iHandles; |
64 |
74 |
65 |
75 |
66 delete iPath; |
76 delete iPath; |
67 iSessionFlagsLock.Close(); |
77 iSessionFlagsLock.Close(); |
68 if(iDisconnectRequest) |
|
69 delete(iDisconnectRequest); |
|
70 |
78 |
71 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
79 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
72 __e32_atomic_add_ord32(&SessionCount, (TUint32) -1); |
80 __e32_atomic_add_ord32(&SessionCount, (TUint32) -1); |
73 #endif |
81 #endif |
74 } |
82 } |
75 |
83 |
|
84 void CSessionFs::Close() |
|
85 { |
|
86 TheFileServer->SessionQueueLockWait(); |
|
87 |
|
88 if (iAccessCount == 1) |
|
89 { |
|
90 // close the objects owned by this session |
|
91 // NB closing a CFileShare may allocate a request to flush dirty data which will |
|
92 // in turn increment iAccessCount on this session |
|
93 if (iHandles) |
|
94 { |
|
95 // Cancel any ASYNC requests belonging to this session BEFORE |
|
96 // CSessionFs is deleted to avoid a KERN-EXEC 44 (EBadMessageHandle) |
|
97 CancelAsyncRequests(this); |
|
98 delete iHandles; |
|
99 iHandles = NULL; |
|
100 } |
|
101 } |
|
102 |
|
103 if (__e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0) == 1) |
|
104 { |
|
105 RMessage2 message = iMessage; |
|
106 delete this; |
|
107 // NB Must complete the message AFTER the session has been deleted... |
|
108 message.Complete(KErrNone); |
|
109 } |
|
110 |
|
111 TheFileServer->SessionQueueLockSignal(); |
|
112 } |
|
113 |
76 void CSessionFs::CreateL() |
114 void CSessionFs::CreateL() |
77 // |
115 // |
78 // Create any additional resources. |
116 // Create any additional resources. |
79 // |
117 // |
80 { |
118 { |
81 __PRINT1(_L("CSessionFs::CreateL 0x%x"),this); |
119 __PRINT1(_L("CSessionFs::CreateL 0x%x"),this); |
82 |
120 |
83 iHandles=CFsObjectIx::NewL(); |
121 iHandles=CFsObjectIx::NewL(); |
84 TInt r = iSessionFlagsLock.CreateLocal(); |
122 TInt r = iSessionFlagsLock.CreateLocal(); |
85 User::LeaveIfError(r); |
123 User::LeaveIfError(r); |
86 RMessage2 m; |
|
87 |
|
88 iDisconnectRequest=new(ELeave) CFsDisconnectRequest; |
|
89 iDisconnectRequest->Set(m,SessionDisconnectOp,this); |
|
90 |
|
91 |
|
92 } |
124 } |
93 |
125 |
94 TInt CSessionFs::CurrentDrive() |
126 TInt CSessionFs::CurrentDrive() |
95 // |
127 // |
96 // Return the current drive. |
128 // Return the current drive. |
476 return retVal; |
509 return retVal; |
477 } |
510 } |
478 |
511 |
479 |
512 |
480 |
513 |
481 TInt TFsCancelSession::DoRequestL(CFsRequest* aRequest) |
|
482 { |
|
483 __CHECK_DRIVETHREAD(aRequest->DriveNumber()); |
|
484 |
|
485 // Cancel any outstanding requests |
|
486 CDriveThread* pT=NULL; |
|
487 TInt r=FsThreadManager::GetDriveThread(aRequest->DriveNumber(), &pT); |
|
488 if(r==KErrNone) |
|
489 pT->CompleteSessionRequests(aRequest->Session(),KErrCancel); |
|
490 // We must also cancel any ASYNC requests belonging to this session BEFORE |
|
491 // ~CSessionFs() is called to avoid a KERN-EXEC 44 (EBadMessageHandle) |
|
492 CancelAsyncRequests(aRequest->Session()); |
|
493 return(r); |
|
494 } |
|
495 |
|
496 TInt TFsCancelSession::Initialise(CFsRequest* /*aRequest*/) |
|
497 { |
|
498 return(KErrNone); |
|
499 } |
|
500 |
|
501 TInt TFsSessionDisconnect::DoRequestL(CFsRequest* aRequest) |
|
502 { |
|
503 __PRINT(_L("TFsSessionDisconnect::DoRequestL()")); |
|
504 __ASSERT_DEBUG(FsThreadManager::IsDisconnectThread(),Fault(ESessionDisconnectThread1)); |
|
505 CDisconnectThread* pT=FsThreadManager::GetDisconnectThread(); |
|
506 |
|
507 // Complete requests on all plugins |
|
508 CFsInternalRequest* pR=pT->GetRequest(); |
|
509 FsPluginManager::CompleteSessionRequests(aRequest->Session(), KErrCancel, pR); |
|
510 |
|
511 // ...and on all drives |
|
512 for(TInt i=0;i<KMaxDrives;++i) |
|
513 { |
|
514 FsThreadManager::LockDrive(i); |
|
515 if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse)) |
|
516 { |
|
517 FsThreadManager::UnlockDrive(i); |
|
518 continue; |
|
519 } |
|
520 pR->Set(CancelSessionOp,aRequest->Session()); |
|
521 pR->SetDriveNumber(i); |
|
522 pR->Status()=KRequestPending; |
|
523 pR->Dispatch(); |
|
524 FsThreadManager::UnlockDrive(i); |
|
525 User::WaitForRequest(pR->Status()); |
|
526 // check request completed or cancelled (by file system dismount which completes requests with KErrNotReady) |
|
527 __ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2)); |
|
528 __THRD_PRINT2(_L("cancel session requests on drive %d r=%d"),i,pR->Status().Int()); |
|
529 |
|
530 if (TFileCacheSettings::Flags(i) & (EFileCacheWriteEnabled | EFileCacheWriteOn)) |
|
531 { |
|
532 FsThreadManager::LockDrive(i); |
|
533 if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse)) |
|
534 { |
|
535 FsThreadManager::UnlockDrive(i); |
|
536 continue; |
|
537 } |
|
538 |
|
539 // Flush dirty data |
|
540 pR->Set(FlushDirtyDataOp,aRequest->Session()); |
|
541 pR->SetDriveNumber(i); |
|
542 pR->Status()=KRequestPending; |
|
543 pR->Dispatch(); |
|
544 FsThreadManager::UnlockDrive(i); |
|
545 User::WaitForRequest(pR->Status()); |
|
546 // check request completed or cancelled (by file system dismount which completes requests with KErrNotReady) |
|
547 __ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2)); |
|
548 __THRD_PRINT2(_L("Flush dirty data on drive %d r=%d"),i,pR->Status().Int()); |
|
549 } |
|
550 |
|
551 } |
|
552 FsNotify::CancelSession(aRequest->Session()); |
|
553 |
|
554 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
|
555 FsNotificationManager::RemoveNotificationRequest(aRequest->Session()); |
|
556 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION |
|
557 |
|
558 |
|
559 // don't delete session here, will be done in CFsDisconnectRequest::Complete() |
|
560 return(KErrNone); |
|
561 } |
|
562 |
|
563 TInt TFsSessionDisconnect::Initialise(CFsRequest* /*aRequest*/) |
|
564 { |
|
565 return(KErrNone); |
|
566 } |
|
567 |
|
568 TInt TFsCancelPlugin::DoRequestL(CFsRequest* aRequest) |
|
569 { |
|
570 //__ASSERT_DEBUG(FsPluginManager::IsPluginThread(),Fault(EFsPluginThreadError)); |
|
571 FsPluginManager::CancelPlugin(aRequest->iCurrentPlugin,aRequest->Session()); |
|
572 TInt err = aRequest->iCurrentPlugin->SessionDisconnect(aRequest->Session()); |
|
573 return(err); |
|
574 } |
|
575 |
|
576 TInt TFsCancelPlugin::Initialise(CFsRequest* /*aRequest*/) |
|
577 { |
|
578 // Notify plugin of session disconnect |
|
579 return(KErrNone); |
|
580 } |
|
581 |
|
582 TInt TFsSetSessionFlags::DoRequestL(CFsRequest* aRequest) |
514 TInt TFsSetSessionFlags::DoRequestL(CFsRequest* aRequest) |
583 { |
515 { |
584 aRequest->Session()->SetSessionFlags(aRequest->Message().Int0(), aRequest->Message().Int1()); |
516 aRequest->Session()->SetSessionFlags(aRequest->Message().Int0(), aRequest->Message().Int1()); |
585 return(KErrNone); |
517 return(KErrNone); |
586 } |
518 } |