remotestoragefw/remotefileengine/src/rsfwlockmanager.cpp
branchRCL_3
changeset 15 88ee4cf65e19
parent 12 87c71b25c937
child 16 1aa8c82cb4cb
equal deleted inserted replaced
12:87c71b25c937 15:88ee4cf65e19
     1 /*
       
     2 * Copyright (c) 2004-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Lock manager for locked remote files
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "rsfwfileentry.h"
       
    20 #include "rsfwrfestatemachine.h"
       
    21 #include "rsfwlockmanager.h"
       
    22 #include "rsfwfileentry.h"
       
    23 #include "rsfwconfig.h"
       
    24 #include "mdebug.h"
       
    25 
       
    26 // ----------------------------------------------------------------------------
       
    27 
       
    28 // ============================ MEMBER FUNCTIONS ==============================
       
    29 
       
    30 // ----------------------------------------------------------------------------
       
    31 // CRsfwLockManager::NewL
       
    32 // ----------------------------------------------------------------------------
       
    33 //
       
    34 CRsfwLockManager* CRsfwLockManager::NewL(CRsfwRemoteAccess* aRemoteAccess)
       
    35     {
       
    36     CRsfwLockManager* self = CRsfwLockManager::NewLC(aRemoteAccess);
       
    37     CleanupStack::Pop(self);
       
    38     return self;
       
    39     }
       
    40 
       
    41 // ----------------------------------------------------------------------------
       
    42 // CRsfwLockManager::NewLC
       
    43 // ----------------------------------------------------------------------------
       
    44 //
       
    45 CRsfwLockManager* CRsfwLockManager::NewLC(CRsfwRemoteAccess* aRemoteAccess)
       
    46     {
       
    47     DEBUGSTRING(("CRsfwLockManager::NewLC"));
       
    48     CRsfwLockManager* self = new (ELeave) CRsfwLockManager();
       
    49     CleanupStack::PushL(self);
       
    50     self->ConstructL(aRemoteAccess);
       
    51     return self;
       
    52     }
       
    53 
       
    54 // ----------------------------------------------------------------------------
       
    55 // CRsfwLockManager::ConstructL
       
    56 // ----------------------------------------------------------------------------
       
    57 //
       
    58 void CRsfwLockManager::ConstructL(CRsfwRemoteAccess* aRemoteAccess)
       
    59     {
       
    60     iRemoteAccess = aRemoteAccess;
       
    61     }
       
    62 
       
    63 // ----------------------------------------------------------------------------
       
    64 // CRsfwLockManager::~CRsfwLockManager
       
    65 // ----------------------------------------------------------------------------
       
    66 //
       
    67 CRsfwLockManager::~CRsfwLockManager()
       
    68     {
       
    69     iLockRefreshContexts.Close();
       
    70 
       
    71     // set unlock flag for all the entries locked
       
    72     while (iLockedEntries.Count() > 0)
       
    73         {
       
    74         CRsfwFileEntry* entry = iLockedEntries[0];
       
    75         iLockedEntries.Remove(0);
       
    76         // note that RemoveLocked will call CRsfwLockManager::RemoveLockedEntry
       
    77         entry->RemoveLocked();
       
    78         }
       
    79     iLockedEntries.Close();    
       
    80     }
       
    81 
       
    82 
       
    83 // ----------------------------------------------------------------------------
       
    84 // CRsfwLockManager::HandleRemoteAccessResponse
       
    85 // For handling the response from RefreshLockL().
       
    86 // If the lock refresh is successful we restart the timer
       
    87 // as the server may have changed the timeout.
       
    88 // If the refresh request returns an error we remove the lock
       
    89 // We assume that server does not hold the lock anymore,
       
    90 // so we cannot re-acquire it simply by trying to refresh it again.
       
    91 // Instead, we should do a fresh lock operation
       
    92 // ----------------------------------------------------------------------------
       
    93 //
       
    94 void CRsfwLockManager::HandleRemoteAccessResponse(TUint aId,
       
    95                                               TInt aStatus)
       
    96     {
       
    97     DEBUGSTRING(("CRsfwLockManager::HandleRemoteAccessResponse id: %d, status: %d", aId, aStatus));
       
    98     TPendingLockRefreshContext lockRefresh;
       
    99     lockRefresh.iId = aId;
       
   100     TInt index = iLockRefreshContexts.Find(lockRefresh);
       
   101     if (index != KErrNotFound) 
       
   102         {
       
   103         lockRefresh = iLockRefreshContexts[index];
       
   104         if (aStatus == KErrNone) 
       
   105             {
       
   106             // Note that this can leave only when creating the timer
       
   107             // so it shouldn't really leave anymore at this point.
       
   108             // Also resetting the timer and calling Start() do not even
       
   109             // return an error, so there is no need to examine err or ret value
       
   110             TRAP_IGNORE(lockRefresh.iFileEntry->SetLockedL(this, NULL));
       
   111             }
       
   112         else 
       
   113             {
       
   114             lockRefresh.iFileEntry->RemoveLocked();
       
   115             }
       
   116         iLockRefreshContexts.Remove(index);
       
   117         }
       
   118     }
       
   119 
       
   120 // ----------------------------------------------------------------------------
       
   121 // CRsfwLockManager::ObtainLockL
       
   122 // ----------------------------------------------------------------------------
       
   123 //
       
   124 void CRsfwLockManager::ObtainLockL(CRsfwFileEntry *aFileEntry,
       
   125                                TUint aLockFlags,
       
   126                                TDesC8*& aLockToken,
       
   127                                CRsfwRfeStateMachine* aOperation)
       
   128     {
       
   129     DEBUGSTRING(("CRsfwLockManager::ObtainLockL"));
       
   130     if (aFileEntry->iLockTimeout == 0)
       
   131         {
       
   132         // No locking wanted,
       
   133         // we use notsupported as a return code in this case too....
       
   134         DEBUGSTRING(("lock timeout in CFileEntry is 0, no locking"));
       
   135         aOperation->HandleRemoteAccessResponse(0, KErrNotSupported); 
       
   136         }
       
   137     else 
       
   138         {
       
   139         HBufC* fullName = aFileEntry->FullNameLC();
       
   140          if (!iRemoteAccess) 
       
   141             {
       
   142             DEBUGSTRING(("iRemoteAccess NULL"));
       
   143             User::Leave(KErrNotReady);
       
   144             }
       
   145         else 
       
   146             {
       
   147             DEBUGSTRING(("calling iRemoteAccess::ObtainLockL()"));
       
   148             iRemoteAccess->ObtainLockL(*fullName,
       
   149                                    aLockFlags,
       
   150                                    aFileEntry->iLockTimeout,
       
   151                                    aLockToken,
       
   152                                    aOperation);
       
   153             }
       
   154 
       
   155         CleanupStack::PopAndDestroy(fullName); // fullname  
       
   156         }
       
   157     
       
   158     }
       
   159 
       
   160 // ----------------------------------------------------------------------------
       
   161 // CRsfwLockManager::ReleaseLockL
       
   162 // ----------------------------------------------------------------------------
       
   163 //
       
   164 void CRsfwLockManager::ReleaseLockL(CRsfwFileEntry* aFileEntry,
       
   165                                 CRsfwRfeStateMachine* aOperation)
       
   166     {
       
   167     DEBUGSTRING(("CRsfwLockManager::ReleaseLockL"));
       
   168     if (aFileEntry->iLockTimeout == 0)
       
   169         {
       
   170         // No locking
       
   171         User::Leave(KErrNotFound);
       
   172         }
       
   173     
       
   174 
       
   175     if (!iRemoteAccess) 
       
   176         {
       
   177         User::Leave(KErrNotReady);
       
   178         }
       
   179     else 
       
   180         {
       
   181         HBufC* fullName = aFileEntry->FullNameLC();
       
   182 #ifdef _DEBUG
       
   183         TInt err;
       
   184         err = iRemoteAccess->ReleaseLockL(*fullName, aOperation);
       
   185         TPtrC p = fullName->Des();
       
   186         DEBUGSTRING16(("ReleaseLockL(): returned %d for file '%S'", err, &p));     
       
   187 
       
   188 
       
   189 
       
   190 #else        
       
   191         iRemoteAccess->ReleaseLockL(*fullName, aOperation);
       
   192 #endif
       
   193         CleanupStack::PopAndDestroy(fullName); // fullname
       
   194         }
       
   195     
       
   196     }
       
   197 
       
   198 // ----------------------------------------------------------------------------
       
   199 // CRsfwLockManager::RefreshLockL
       
   200 // ----------------------------------------------------------------------------
       
   201 //
       
   202 void CRsfwLockManager::RefreshLockL(CRsfwFileEntry* aFileEntry)
       
   203     {
       
   204    DEBUGSTRING(("CRsfwLockManager::RefreshLockL"));
       
   205     TInt id = 0;
       
   206     if (aFileEntry->iLockTimeout > 0) // timeout = 0 indicates no locking
       
   207         {
       
   208         aFileEntry->iLockTimer->Cancel(); // cancel the old timer
       
   209         HBufC* fullName = aFileEntry->FullNameLC();
       
   210         TRAPD(err, id = iRemoteAccess->RefreshLockL(*fullName,
       
   211                                                     aFileEntry->iLockTimeout,
       
   212                                                     this)); 
       
   213         if (err == KErrNone) 
       
   214             {
       
   215             TPendingLockRefreshContext lockRefresh;
       
   216             lockRefresh.iId = id;
       
   217             lockRefresh.iFileEntry = aFileEntry;
       
   218             iLockRefreshContexts.AppendL(lockRefresh);
       
   219             } 
       
   220         else 
       
   221             {
       
   222             // This error would come from the lower layers of the communication
       
   223             // stack, not from the server.
       
   224             // We use the timer mechanism to try again
       
   225             // but set the timeout to smaller.
       
   226             // Note that we don't touch aFileEntry->iLockTimer, 
       
   227             // which will be used to set the timeout requested from the server
       
   228             TInt lockTimeout =
       
   229                 Min((aFileEntry->iLockTimeout / KLockRefreshAdjustment) / 2,
       
   230                     KMinLockRefreshAttempt);
       
   231             TCallBack callBack(CRsfwFileEntry::LockTimerExpiredL, this);
       
   232             aFileEntry->iLockTimer->Start(1000000 * lockTimeout,
       
   233                                           1000000 * lockTimeout,
       
   234                                           callBack);
       
   235             }
       
   236         CleanupStack::PopAndDestroy(fullName); // fullname
       
   237         }
       
   238     }
       
   239   
       
   240 // ----------------------------------------------------------------------------
       
   241 // CRsfwLockManager::LockedCount
       
   242 // ----------------------------------------------------------------------------
       
   243 //  
       
   244 TInt CRsfwLockManager::LockedCount()
       
   245     {
       
   246     return iLockedEntries.Count();
       
   247     }
       
   248 
       
   249 // ----------------------------------------------------------------------------
       
   250 // CRsfwLockManager::AddLockedEntryL
       
   251 // ----------------------------------------------------------------------------
       
   252 //
       
   253 void CRsfwLockManager::AddLockedEntryL(CRsfwFileEntry* aEntry)
       
   254     {
       
   255     // prevent from adding the same item twice
       
   256     if (iLockedEntries.Find(aEntry) != KErrNotFound)
       
   257         {
       
   258         return;
       
   259         }
       
   260     
       
   261     iLockedEntries.AppendL(aEntry);
       
   262     DEBUGSTRING(("Update locked count %d -> %d",
       
   263                  iLockedEntries.Count() - 1,
       
   264                  iLockedEntries.Count()));
       
   265     }
       
   266 
       
   267 // ----------------------------------------------------------------------------
       
   268 // CRsfwLockManager::RemoveLockedEntry
       
   269 // ----------------------------------------------------------------------------
       
   270 //
       
   271 void CRsfwLockManager::RemoveLockedEntry(CRsfwFileEntry* aEntry)
       
   272     {
       
   273     TInt index = iLockedEntries.Find(aEntry);
       
   274     if (index != KErrNotFound)
       
   275         {
       
   276         iLockedEntries.Remove(index);        
       
   277         DEBUGSTRING(("Update locked count %d -> %d",
       
   278                  iLockedEntries.Count() + 1,
       
   279                  iLockedEntries.Count()));
       
   280 
       
   281         }
       
   282     }
       
   283 
       
   284 // ----------------------------------------------------------------------------
       
   285 // CRsfwLockManager::PopulateExternalLockTokenCacheL
       
   286 // ----------------------------------------------------------------------------
       
   287 //
       
   288 void CRsfwLockManager::PopulateExternalLockTokenCacheL(CRsfwFileEntry* aRoot)
       
   289     {
       
   290     if (aRoot)
       
   291         {
       
   292         const TDesC8* lockToken = aRoot->LockToken();
       
   293         if (lockToken)
       
   294             {
       
   295             HBufC* path = aRoot->FullNameLC();
       
   296             TPtr pathPtr = path->Des();
       
   297             if (aRoot->Type() == KNodeTypeDir)
       
   298                 {
       
   299                 // the MaxLength() of path is KMaxPath, so we can append
       
   300             if (pathPtr.Length() && (pathPtr[pathPtr.Length() - 1] != '/'))
       
   301                 {
       
   302                 pathPtr.Append('/');
       
   303                 }
       
   304                 }
       
   305             iRemoteAccess->SetLockToken(pathPtr, *lockToken);
       
   306             CleanupStack::PopAndDestroy(path);
       
   307             }
       
   308         
       
   309         RPointerArray<CRsfwFileEntry>* kids = aRoot->Kids();
       
   310         TInt i;
       
   311         for (i = 0; i < kids->Count(); i++)
       
   312             {
       
   313             PopulateExternalLockTokenCacheL((*kids)[i]);
       
   314             }
       
   315         }
       
   316     }
       
   317 
       
   318 //  End of File