1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/lowlevellibsandfws/apputils/src/Baksrv.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1453 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <baksrv.h>
1.20 +#include "Baksrvs.h"
1.21 +#include <babackup.h>
1.22 +#include <bafl/backup_std.h>
1.23 +#include <basched.h>
1.24 +#include <bsul/clientmessage.h>
1.25 +#include "patchdata.h"
1.26 +
1.27 +extern const BSUL::TClientMessageServerData KServerData;
1.28 +
1.29 +const TInt KBakServMaxOperationTimerLoops = 3; // Number of iterations for base operation timer
1.30 +
1.31 +_LIT(KPanic,"BackupServer");
1.32 +//
1.33 +// RMessage::Panic() also completes the message. This is:
1.34 +// (a) important for efficient cleanup within the kernel
1.35 +// (b) a problem if the message is completed a second time
1.36 +//
1.37 +void PanicClient(const RMessagePtr2& aMessage, TInt aPanic)
1.38 + {
1.39 + aMessage.Panic(KPanic,aPanic);
1.40 + }
1.41 +
1.42 +
1.43 +//
1.44 +// class CShutdownServer
1.45 +//
1.46 +
1.47 +NONSHARABLE_CLASS(CShutdownServer) : public CTimer
1.48 + {
1.49 + enum {KMyShutdownDelay=0x2000000}; // approx 2s
1.50 +public:
1.51 + inline CShutdownServer();
1.52 + inline void ConstructL();
1.53 + inline void Start();
1.54 +private:
1.55 + void RunL();
1.56 + };
1.57 +
1.58 +inline CShutdownServer::CShutdownServer()
1.59 + :CTimer(-1)
1.60 + {
1.61 + CActiveScheduler::Add(this);
1.62 + }
1.63 +
1.64 +inline void CShutdownServer::ConstructL()
1.65 + {
1.66 + CTimer::ConstructL();
1.67 + }
1.68 +inline void CShutdownServer::Start()
1.69 + {
1.70 + After(KMyShutdownDelay);
1.71 + }
1.72 +
1.73 +//
1.74 +// Initiate server exit when the timer expires
1.75 +//
1.76 +void CShutdownServer::RunL()
1.77 + {
1.78 + CActiveScheduler::Stop();
1.79 + }
1.80 +
1.81 +
1.82 +//
1.83 +// class CBaServBackupScheduler
1.84 +//
1.85 +
1.86 +EXPORT_C CBaServBackupScheduler::CBaServBackupScheduler()
1.87 +{
1.88 +}
1.89 +
1.90 +EXPORT_C CBaServBackupScheduler::~CBaServBackupScheduler()
1.91 +{
1.92 +}
1.93 +
1.94 +/**
1.95 + *
1.96 + * Set the error handler to aErrorHandler to the current scheduler.
1.97 + *
1.98 + * @param "CBaServBackupSession* aErrorHandler"
1.99 + * The handler session.
1.100 + */
1.101 +EXPORT_C void CBaServBackupScheduler::SetErrorHandler(CBaServBackupSession* aErrorHandler)
1.102 + {
1.103 + iErrorHandler=aErrorHandler;
1.104 + }
1.105 +
1.106 +/**
1.107 + *
1.108 + * Handles the error aError.
1.109 + *
1.110 + * @param "TInt aError"
1.111 + * The error.
1.112 + */
1.113 +EXPORT_C void CBaServBackupScheduler::Error(TInt aError) const
1.114 + {
1.115 + if (iErrorHandler)
1.116 + {
1.117 + iErrorHandler->HandleError(aError);
1.118 + }
1.119 + else if (aError!=KLeaveWithoutAlert)
1.120 + {
1.121 + // Handling the in this way implies that ServiceL should not leave.
1.122 + CActiveScheduler::Error(aError);
1.123 + }
1.124 + }
1.125 +
1.126 +/**
1.127 +Class CBaServBackupSession::CReRegistrationTimer
1.128 +*/
1.129 +NONSHARABLE_CLASS(CBaServBackupSession::CReRegistrationTimer) : public CPeriodic
1.130 +{
1.131 + public:
1.132 + static CReRegistrationTimer* NewL(TInt aPriority);
1.133 + static TInt ReRegistrationTimerCallBack(TAny* aPtr);
1.134 +
1.135 + protected:
1.136 + TInt RunError(TInt aError);
1.137 +
1.138 + private:
1.139 + CReRegistrationTimer(TInt aPriority);
1.140 + void HandleReRegistrationTimerCallBack();
1.141 +
1.142 + public:
1.143 + CBaBackupServer* iBackupServer;
1.144 +};
1.145 +
1.146 +/**
1.147 +Class CBaBackupServer::CBaServCloseAllOperationTimer
1.148 +*/
1.149 +
1.150 +NONSHARABLE_CLASS(CBaBackupServer::CBaServCloseAllOperationTimer): public CPeriodic
1.151 +{
1.152 + public:
1.153 + static CBaServCloseAllOperationTimer* NewL(CBaBackupServer* aBackupServer);
1.154 + void ConstructL(CBaBackupServer* aBackupServer);
1.155 + ~CBaServCloseAllOperationTimer();
1.156 + void SetMessage(const RMessagePtr2& aPtr);
1.157 + RMessagePtr2 Message();
1.158 + TInt GetOperationCount();
1.159 + void SetOperationCount(TInt aCount);
1.160 + static TInt OperationTimerCallBack(TAny* aPtr);
1.161 + protected:
1.162 + TInt RunError(TInt aError);
1.163 + private:
1.164 + void HandleOperationTimerCallBack();
1.165 + CBaServCloseAllOperationTimer();
1.166 + private:
1.167 + RMessagePtr2 iCloseAllFilesMessage;
1.168 + TInt16 iOperationCount;
1.169 + CBaBackupServer* iBackupServer;
1.170 +};
1.171 +
1.172 +//
1.173 +// class CBaBackupServer
1.174 +//
1.175 +
1.176 +/**
1.177 + *
1.178 + * Returns a pointer to <code>CBaBackupServer</code> object.
1.179 + *
1.180 + * @return "CBaBackupServer"
1.181 + * A newly-constructed backup server object.
1.182 + */
1.183 +EXPORT_C CBaBackupServer* CBaBackupServer::NewL()
1.184 + { // static
1.185 + CBaBackupServer* self=new(ELeave) CBaBackupServer(CActive::EPriorityStandard);
1.186 + return self;
1.187 + }
1.188 +
1.189 +/**
1.190 + *
1.191 + * Constructor.
1.192 + *
1.193 + * @param "TInt aPriority"
1.194 + * The active object priority.
1.195 + */
1.196 +EXPORT_C CBaBackupServer::CBaBackupServer(TInt aPriority)
1.197 + : CServer2(aPriority)
1.198 + {}
1.199 +/**
1.200 + *
1.201 + * Destructor.
1.202 + *
1.203 + */
1.204 +EXPORT_C CBaBackupServer::~CBaBackupServer()
1.205 + {
1.206 + TDblQueIter<CSession2> iter(iSessionIter);
1.207 + iter.SetToFirst();
1.208 +
1.209 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.210 + {
1.211 + delete session;
1.212 + }
1.213 + delete iShutdown;
1.214 + delete iExtension;
1.215 + delete iCloseAllFilesOperationTimer;
1.216 + }
1.217 +
1.218 +/**
1.219 + *
1.220 + * Completes the server construction by adding the server to the active scheduler and creating
1.221 + * a <code>CShutdownServer</code> object.
1.222 + *
1.223 + */
1.224 +EXPORT_C void CBaBackupServer::ConstructL()
1.225 + {
1.226 + StartL(__BACKUP_SERVER_NAME_V2);
1.227 + iExtension = new(ELeave) CBaBackupServerExt();
1.228 + iShutdown = new (ELeave) CShutdownServer;
1.229 + iShutdown->ConstructL();
1.230 + // ensure that the server still exits even if the 1st client fails to connect
1.231 + iShutdown->Start();
1.232 + iRegisteredFilesCount = 0;
1.233 + iCloseAllFilesOperationTimer = CBaBackupServer::CBaServCloseAllOperationTimer::NewL(this);
1.234 + iCloseAllOperationRunning = EFalse;
1.235 +
1.236 + //initialise the client message framework
1.237 + BSUL::CClientMessage::InitialiseFrameworkL(KServerData);
1.238 + }
1.239 +
1.240 +/**
1.241 + *
1.242 + * Sets the server to be busy with the aUniqueClientId client.
1.243 + *
1.244 + * @param "TUint32 aUniqueClientId"
1.245 + * A unique client identifier.
1.246 + */
1.247 +EXPORT_C void CBaBackupServer::SetBusy(TUint32 aUniqueClientId)
1.248 + {
1.249 + iExtension->iUniqueBusyClientId=aUniqueClientId;
1.250 + }
1.251 +
1.252 +/**
1.253 + *
1.254 + * Returns <code>ETrue</code> if the client using the server is not the one identified by aUniqueClientId
1.255 + * oterwise <code>EFalse</code>
1.256 + *
1.257 + * @param "TUint32 aUniqueClientId"
1.258 + * A unique client identifier.
1.259 + */
1.260 +EXPORT_C TBool CBaBackupServer::IsOtherClientBusy(TUint32 aUniqueClientId) const
1.261 + {
1.262 + return (iExtension->iUniqueBusyClientId!=0 && iExtension->iUniqueBusyClientId!=aUniqueClientId);
1.263 + }
1.264 +
1.265 +/**
1.266 + *
1.267 + * Returns <code>ETrue</code> if the client using the server corresponds has aUniqueClientId as unique id
1.268 + * oterwise <code>EFalse</code>
1.269 + *
1.270 + * @param "TUint32 aUniqueClientId"
1.271 + * A unique client identifier id.
1.272 + */
1.273 +EXPORT_C TBool CBaBackupServer::IsClientBusy(TUint32 aUniqueClientId) const
1.274 + {
1.275 + return ((iExtension->iUniqueBusyClientId==aUniqueClientId) ||
1.276 + ((iExtension->iCachedBusyClientId != 0) && (iExtension->iCachedBusyClientId == aUniqueClientId)));
1.277 + }
1.278 +
1.279 +/**
1.280 + *
1.281 + * Handles the closing of all files by signaling the new file lock flag, aFlag, to all client.
1.282 + *
1.283 + * @param "MBackupObserver::TFileLockFlags aFlag"
1.284 + * A file lock flag.
1.285 + */
1.286 +EXPORT_C void CBaBackupServer::CloseAllFilesL(MBackupObserver::TFileLockFlags aFlag)
1.287 + {
1.288 + // Set the close all operation flag and the reregistration counter to zero
1.289 + iCloseAllOperationRunning = ETrue;
1.290 + iSessionLockReRegistrationCount = 0;
1.291 +
1.292 + // cleanup that calls RestartAll if required
1.293 + TDblQueIter<CSession2> iter(iSessionIter);
1.294 + iter.SetToFirst();
1.295 +
1.296 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.297 + {
1.298 + static_cast<CBaServBackupSession*>(session)->SignalReleaseAllFileLocksL(aFlag);
1.299 + }
1.300 + }
1.301 +
1.302 +/**
1.303 + *
1.304 + * Signals to all clients of getting the lock of their respective files.
1.305 + *
1.306 + */
1.307 +EXPORT_C void CBaBackupServer::RestartAll()
1.308 + {
1.309 + TDblQueIter<CSession2> iter(iSessionIter);
1.310 + iter.SetToFirst();
1.311 +
1.312 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.313 + {
1.314 + static_cast<CBaServBackupSession*>(session)->SignalRetakeAllFileLocks();
1.315 + }
1.316 + }
1.317 +
1.318 +/**
1.319 + *
1.320 + * Allows any subclass of <code>CBaBackupServer</code> of completing the closing of files.
1.321 + * The server will lose the ownership of aClosedFiles object, which implies it is up to this virtual
1.322 + * function to deal with it in order to avoid a memory leak.
1.323 + *
1.324 + * @param "CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles"
1.325 + * An array of closed files.
1.326 + */
1.327 +EXPORT_C void CBaBackupServer::CompleteClosingFiles(CArrayFix<CBaServBackupSession::TClosedFile>* aClosedFiles)
1.328 + {
1.329 + delete aClosedFiles;
1.330 + }
1.331 +
1.332 +/**
1.333 + *
1.334 + * Allows application framework backup code to check if all registerd files have beem updated
1.335 + *
1.336 + */
1.337 +EXPORT_C TBool CBaBackupServer::HaveAllCloseAllFilesClientsReRegistered()
1.338 + {
1.339 + return((iRegisteredFilesCount == iSessionLockReRegistrationCount) ? ETrue : EFalse);
1.340 + }
1.341 +
1.342 +void CBaBackupServer::CloseFileL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
1.343 + {
1.344 + TDblQueIter<CSession2> iter(iSessionIter);
1.345 + iter.SetToFirst();
1.346 +
1.347 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.348 + {
1.349 + static_cast<CBaServBackupSession*>(session)->SignalReleaseFileLockL(aFlag,aFileName);
1.350 + }
1.351 + }
1.352 +
1.353 +void CBaBackupServer::RestartFile(const TDesC& aFileName)
1.354 + {
1.355 + TDblQueIter<CSession2> iter(iSessionIter);
1.356 + iter.SetToFirst();
1.357 +
1.358 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.359 + {
1.360 + static_cast<CBaServBackupSession*>(session)->SignalRetakeFileLocks(aFileName);
1.361 + }
1.362 + }
1.363 +
1.364 +/**
1.365 + *
1.366 + * Creates a server-side client <code>CBaServBackupSession</code> session object by checking first if
1.367 + * the version of the server is compatible with the client.
1.368 + *
1.369 + * @param "const TVersion &aVersion"
1.370 + * Version information supplied by the client.
1.371 + */
1.372 +EXPORT_C CSession2* CBaBackupServer::NewSessionL(const TVersion &aVersion, const RMessage2& /*aMessage*/) const
1.373 + {
1.374 + TVersion ver(KBakServMajorVN,KBakServMinorVN,KBakServBuildVN);
1.375 + if (!User::QueryVersionSupported(ver,aVersion))
1.376 + User::Leave(KErrNotSupported);
1.377 +//
1.378 + return CBaServBackupSession::NewL();
1.379 + }
1.380 +
1.381 +/**
1.382 + *
1.383 + * Signals to all clients the aBackupOperationAttributes.
1.384 + *
1.385 + * @param "const TBackupOperationAttributes& aBackupOperationAttributes"
1.386 + * Backup operation attributes.
1.387 + */
1.388 +EXPORT_C void CBaBackupServer::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
1.389 + {
1.390 + TDblQueIter<CSession2> iter(iSessionIter);
1.391 + iter.SetToFirst();
1.392 +
1.393 + for (CSession2* session=iter++; session!=NULL; session=iter++)
1.394 + {
1.395 + static_cast<CBaServBackupSession*>(session)->SignalBackupOperation(aBackupOperationAttributes);
1.396 + }
1.397 + // Cache session id if starting backup
1.398 + if (aBackupOperationAttributes.iOperation == MBackupOperationObserver::EStart)
1.399 + iExtension->iCachedBusyClientId = iExtension->iUniqueBusyClientId;
1.400 + }
1.401 +
1.402 +void CBaBackupServer::AddSession()
1.403 + {
1.404 + iShutdown->Cancel();
1.405 + ++iSessionCount;
1.406 + }
1.407 +
1.408 +void CBaBackupServer::DropSession()
1.409 + {
1.410 + if (--iSessionCount==0)
1.411 + {
1.412 + iShutdown->Start();
1.413 + }
1.414 + }
1.415 +
1.416 +/*
1.417 + * Check to see if a CloseAll opertation is in progress
1.418 + *
1.419 + */
1.420 +TBool CBaBackupServer::IsCloseAllOperationRunning()
1.421 + {
1.422 + return iCloseAllOperationRunning;
1.423 + }
1.424 +
1.425 +/*
1.426 + * Set value of IsCloseAllOperationRunning
1.427 + *
1.428 + */
1.429 +EXPORT_C void CBaBackupServer::SetCloseAllOperationRunningState(TBool aRunning)
1.430 + {
1.431 + iCloseAllOperationRunning = aRunning;
1.432 + }
1.433 +
1.434 +/**
1.435 + *
1.436 + * This timer will only be created in cases of no derived backup server
1.437 + *
1.438 + */
1.439 +void CBaBackupServer::StartCloseAllFilesOperationTimer(const RMessagePtr2& aPtr)
1.440 + {
1.441 + // Store the CloseAll message in case we need to Complete on a timeout
1.442 + iCloseAllFilesOperationTimer->SetMessage(aPtr);
1.443 +
1.444 + // If hardware use patchable constant if not default to 3 seconds
1.445 + iCloseAllFilesOperationTimer->Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack, iCloseAllFilesOperationTimer));
1.446 + }
1.447 +
1.448 +/**
1.449 + * Handle an error from CBaServBackupSession::ServiceL()
1.450 + * A bad descriptor error implies a badly programmed client, so panic it;
1.451 + * otherwise report the error to the client
1.452 + *
1.453 + * @param "TInt aError"
1.454 + * The error.
1.455 + */
1.456 +EXPORT_C TInt CBaBackupServer::RunError(TInt aError)
1.457 + {
1.458 + if (aError==KErrBadDescriptor)
1.459 + {
1.460 + PanicClient(Message(), EBufferOverflow);
1.461 + }
1.462 + else
1.463 + {
1.464 + Message().Complete(aError);
1.465 + }
1.466 + //
1.467 + // The leave will result in an early return from CServer::RunL(), skipping
1.468 + // the call to request another message. So do that now in order to keep the
1.469 + // server running.
1.470 + ReStart();
1.471 + return KErrNone; // handled the error fully
1.472 + }
1.473 +
1.474 +//
1.475 +// class CBaBackupServer::CBaServCloseAllOperationTimer
1.476 +//
1.477 +
1.478 +/**
1.479 +@internalComponent
1.480 +*/
1.481 +CBaBackupServer::CBaServCloseAllOperationTimer* CBaBackupServer::CBaServCloseAllOperationTimer::NewL(CBaBackupServer* aBackupServer)
1.482 + { // static
1.483 + CBaBackupServer::CBaServCloseAllOperationTimer* self=new(ELeave) CBaBackupServer::CBaServCloseAllOperationTimer();
1.484 + CleanupStack::PushL(self);
1.485 + self->ConstructL(aBackupServer);
1.486 + CleanupStack::Pop(); // self
1.487 + CActiveScheduler::Add(self);
1.488 + return self;
1.489 + }
1.490 +
1.491 +/**
1.492 +@internalComponent
1.493 +*/
1.494 +
1.495 +void CBaBackupServer::CBaServCloseAllOperationTimer::ConstructL(CBaBackupServer* aBackupServer)
1.496 + {
1.497 + CTimer::ConstructL();
1.498 + iBackupServer = aBackupServer;
1.499 + iOperationCount = 0;
1.500 + }
1.501 +/**
1.502 +@internalComponent
1.503 +*/
1.504 +
1.505 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::GetOperationCount()
1.506 +{
1.507 + return iOperationCount;
1.508 +}
1.509 +
1.510 +/**
1.511 +@internalComponent
1.512 +*/
1.513 +
1.514 +void CBaBackupServer::CBaServCloseAllOperationTimer::SetOperationCount(TInt aCount)
1.515 +{
1.516 + iOperationCount = aCount;
1.517 +}
1.518 +
1.519 +/**
1.520 +@internalComponent
1.521 +*/
1.522 +
1.523 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::RunError(TInt aError)
1.524 + {
1.525 + if (aError==KLeaveWithoutAlert)
1.526 + {
1.527 + return KErrNone;
1.528 + }
1.529 + return aError;
1.530 + }
1.531 +
1.532 +/**
1.533 +@internalComponent
1.534 +*/
1.535 +CBaBackupServer::CBaServCloseAllOperationTimer::CBaServCloseAllOperationTimer()
1.536 + : CPeriodic(CActive::EPriorityStandard)
1.537 + { ; }
1.538 +
1.539 +/**
1.540 +@internalComponent
1.541 +*/
1.542 +CBaBackupServer::CBaServCloseAllOperationTimer::~CBaServCloseAllOperationTimer()
1.543 + {
1.544 + if (IsActive())
1.545 + Cancel();
1.546 + }
1.547 +
1.548 +/**
1.549 +@internalComponent
1.550 +*/
1.551 +void CBaBackupServer::CBaServCloseAllOperationTimer::SetMessage(const RMessagePtr2& aPtr)
1.552 + {
1.553 + iCloseAllFilesMessage = aPtr;
1.554 + }
1.555 +
1.556 +/**
1.557 +@internalComponent
1.558 +*/
1.559 +RMessagePtr2 CBaBackupServer::CBaServCloseAllOperationTimer::Message()
1.560 + {
1.561 + return iCloseAllFilesMessage;
1.562 + }
1.563 +
1.564 +/**
1.565 +@internalComponent
1.566 +*/
1.567 +TInt CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack(TAny* aPtr)
1.568 + { // static
1.569 + TRAP_IGNORE(REINTERPRET_CAST(CBaBackupServer::CBaServCloseAllOperationTimer*,aPtr)->HandleOperationTimerCallBack());
1.570 + return 0;
1.571 + }
1.572 +
1.573 +/**
1.574 +@internalComponent
1.575 +*/
1.576 +void CBaBackupServer::CBaServCloseAllOperationTimer::HandleOperationTimerCallBack()
1.577 + {
1.578 + TBool finished = iBackupServer->HaveAllCloseAllFilesClientsReRegistered();
1.579 + TInt retCode;
1.580 + if (finished || (iOperationCount == KBakServMaxOperationTimerLoops))
1.581 + {
1.582 + if (finished)
1.583 + {
1.584 + retCode = KErrNone;
1.585 + }
1.586 + else
1.587 + {
1.588 + retCode = KErrLocked;
1.589 + }
1.590 +
1.591 + // One way or another CloseAll is finished at this point
1.592 + iBackupServer->SetCloseAllOperationRunningState(EFalse);
1.593 +
1.594 + iCloseAllFilesMessage.Complete(retCode);
1.595 + Cancel();
1.596 + }
1.597 + else
1.598 + {
1.599 + iOperationCount++;
1.600 + if (IsActive())
1.601 + {
1.602 + Cancel();
1.603 +
1.604 + // If hardware use patchable constant if not default to 3 seconds
1.605 + Start(KBaBackupCloseallFilesTimeout, KBaBackupCloseallFilesTimeout, TCallBack(CBaBackupServer::CBaServCloseAllOperationTimer::OperationTimerCallBack,this));
1.606 + }
1.607 + }
1.608 + }
1.609 +
1.610 +//
1.611 +// class CBaServBackupMessageQueue
1.612 +//
1.613 +
1.614 +inline CBaServBackupMessageQueue::TQueueItem::TQueueItem(HBufC* aFileName,TInt aOperation)
1.615 + : iFileName(aFileName), iOperation(aOperation)
1.616 + {}
1.617 +
1.618 +CBaServBackupMessageQueue* CBaServBackupMessageQueue::NewL()
1.619 + { // static
1.620 + CBaServBackupMessageQueue* self=new(ELeave) CBaServBackupMessageQueue();
1.621 + return self;
1.622 + }
1.623 +
1.624 +CBaServBackupMessageQueue::~CBaServBackupMessageQueue()
1.625 + {
1.626 + const TInt count=iQueue.Count();
1.627 + for (TInt ii=0;ii<count;ii++)
1.628 + {
1.629 + delete iQueue[ii].iFileName;
1.630 + }
1.631 + iQueue.Reset();
1.632 + iQueue.Close();
1.633 + }
1.634 +
1.635 +void CBaServBackupMessageQueue::AddItemL(const TDesC& aFileName,MBackupObserver::TFileLockFlags aFlag)
1.636 + {
1.637 + const TInt count=iQueue.Count();
1.638 + for (TInt ii=0;ii<count;ii++)
1.639 + {
1.640 + TQueueItem& item=iQueue[ii];
1.641 + if(aFileName.MatchF(*item.iFileName) == KErrNone)
1.642 + {
1.643 + if (item.iOperation==MBackupObserver::EReleaseLockReadOnly && aFlag==MBackupObserver::EReleaseLockNoAccess)
1.644 + {
1.645 + item.iOperation=MBackupObserver::EReleaseLockNoAccess;
1.646 + }
1.647 + else if (item.iOperation!=MBackupObserver::EReleaseLockNoAccess)
1.648 + {
1.649 + HBufC* file=aFileName.AllocLC();
1.650 + TQueueItem item(file,aFlag);
1.651 + User::LeaveIfError(iQueue.Insert(item,ii));
1.652 + CleanupStack::Pop(); // file
1.653 + }
1.654 + return;
1.655 + }
1.656 + }
1.657 + HBufC* file=aFileName.AllocLC();
1.658 + HBufC* copy=aFileName.AllocLC();
1.659 + TQueueItem item(file,aFlag);
1.660 + User::LeaveIfError(iQueue.Append(item));
1.661 + item=TQueueItem(copy,-1);
1.662 + const TInt err=iQueue.Append(item);
1.663 + if (err!=KErrNone)
1.664 + {
1.665 + iQueue.Remove(iQueue.Count()-1);
1.666 + User::Leave(err);
1.667 + }
1.668 + CleanupStack::Pop(2); // copy, file
1.669 + }
1.670 +
1.671 +void CBaServBackupMessageQueue::AddItem(const TDesC& aFileName)
1.672 + {
1.673 + const TInt count=iQueue.Count();
1.674 + for (TInt ii=0;ii<count;ii++)
1.675 + {
1.676 + TQueueItem& item=iQueue[ii];
1.677 + if (aFileName.MatchF(*item.iFileName) == KErrNone && item.iOperation==-1)
1.678 + {
1.679 + item.iOperation=0;
1.680 + break;
1.681 + }
1.682 + }
1.683 + }
1.684 +
1.685 +TBool CBaServBackupMessageQueue::IsEmpty() const
1.686 + {
1.687 + return HeadIndex()==KErrNotFound;
1.688 + }
1.689 +
1.690 +void CBaServBackupMessageQueue::RemoveHead()
1.691 + {
1.692 + const TInt index=HeadIndex();
1.693 + if (index!=KErrNotFound)
1.694 + {
1.695 + delete iQueue[index].iFileName;
1.696 + iQueue.Remove(index);
1.697 + iQueue.Compress();
1.698 + }
1.699 + }
1.700 +
1.701 +void CBaServBackupMessageQueue::RemoveItem(const TDesC& aFileName)
1.702 + {
1.703 + const TInt count=iQueue.Count();
1.704 + for (TInt ii=count-1;ii>=0;ii--)
1.705 + {
1.706 + const TQueueItem& item=iQueue[ii];
1.707 + if (aFileName.MatchF(*item.iFileName) == KErrNone)
1.708 + {
1.709 + delete item.iFileName;
1.710 + iQueue.Remove(ii);
1.711 + iQueue.Compress();
1.712 + }
1.713 + }
1.714 + }
1.715 +
1.716 +void CBaServBackupMessageQueue::GetHead(TDes& aFileName,MBackupObserver::TFileLockFlags& aFlag) const
1.717 + {
1.718 + aFileName.Zero();
1.719 + const TInt index=HeadIndex();
1.720 + if (index!=KErrNotFound)
1.721 + {
1.722 + const TQueueItem& item=iQueue[index];
1.723 + aFileName=item.iFileName->Des();
1.724 + aFlag=(MBackupObserver::TFileLockFlags)item.iOperation;
1.725 + }
1.726 + }
1.727 +
1.728 +TInt CBaServBackupMessageQueue::HeadIndex() const
1.729 + {
1.730 + TInt index=KErrNotFound;
1.731 + const TInt count=iQueue.Count();
1.732 + for (TInt ii=0;ii<count;ii++)
1.733 + {
1.734 + const TQueueItem& item=iQueue[ii];
1.735 + if (item.iOperation!=ENoOp)
1.736 + {
1.737 + index=ii;
1.738 + break;
1.739 + }
1.740 + }
1.741 + return index;
1.742 + }
1.743 +
1.744 +//
1.745 +// class CBaServBackupSession
1.746 +//
1.747 +
1.748 +CBaServBackupSession* CBaServBackupSession::NewL()
1.749 + { // static
1.750 + CBaServBackupSession* self=new(ELeave) CBaServBackupSession();
1.751 + CleanupStack::PushL(self);
1.752 + self->ConstructL();
1.753 + CleanupStack::Pop(); // self
1.754 + return self;
1.755 + }
1.756 +
1.757 +/**
1.758 + *
1.759 + * Constructor.
1.760 + *
1.761 + * @param "RThread aClient"
1.762 + * The client thread for which this server-side client session is being constructed.
1.763 + */
1.764 +EXPORT_C CBaServBackupSession::CBaServBackupSession()
1.765 + : CSession2()
1.766 + {
1.767 + iUniqueClientId = (TUint32)this;
1.768 + }
1.769 +
1.770 +/**
1.771 + *
1.772 + * Destructor.
1.773 + *
1.774 + */
1.775 +EXPORT_C CBaServBackupSession::~CBaServBackupSession()
1.776 + {
1.777 + CBaBackupServer* server=BackupServer();
1.778 + if (server->IsClientBusy(iUniqueClientId))
1.779 + {
1.780 + RestartAll();
1.781 + if (server->IsBackupOperationRunning())
1.782 + {
1.783 + TBackupOperationAttributes backupOpAtt(MBackupObserver::ETakeLock, MBackupOperationObserver::EAbort);
1.784 + server->SignalBackupOperation(backupOpAtt);
1.785 + server->SetBackupOperationRunning(EFalse);
1.786 + }
1.787 + server->SetBusy(0);
1.788 + }
1.789 +
1.790 + if (iFileLockObservers)
1.791 + {
1.792 + server->DecrementRegisteredFilesCount(iFileLockObservers->Count());
1.793 + }
1.794 +
1.795 + delete iClosedFiles;
1.796 + delete iFileLockObservers;
1.797 + delete iReleasedFiles;
1.798 + delete iMessageQueue;
1.799 + delete iReRegistrationTimer;
1.800 + iReRegistrationTimer = 0;
1.801 + server->DropSession();
1.802 + }
1.803 +
1.804 +/**
1.805 + *
1.806 + * Completes the session construction by creating a <code>CBaServBackupMessageQueue</code> object.
1.807 + *
1.808 + */
1.809 +EXPORT_C void CBaServBackupSession::ConstructL()
1.810 + {
1.811 + iMessageQueue=CBaServBackupMessageQueue::NewL();
1.812 +
1.813 + // Cannot set iBackupServer in CReRegistrationTimer at this point but must be done before call to Start
1.814 + iReRegistrationTimer=CBaServBackupSession::CReRegistrationTimer::NewL(CActive::EPriorityStandard);
1.815 + }
1.816 +
1.817 +/**
1.818 + *
1.819 + * Completes the construction of this <code>CBaServBackupSession</code> session by just doing a base call class.
1.820 + * It also notify the server that a new session has been created.
1.821 + *
1.822 + * @param "const CServer& aServer"
1.823 + * The server active object which is responsible for this session
1.824 + */
1.825 +EXPORT_C void CBaServBackupSession::CreateL()
1.826 + {
1.827 + BackupServer()->AddSession();
1.828 + }
1.829 +
1.830 +void CBaServBackupSession::SignalReleaseAllFileLocksL(MBackupObserver::TFileLockFlags aFlag)
1.831 + {
1.832 + CBaBackupServer* server=BackupServer();
1.833 + if (iFileLockObservers)
1.834 + {
1.835 + const TInt count=iFileLockObservers->Count();
1.836 + for (TInt ii=0;ii<count;ii++)
1.837 + {
1.838 + TFileName name=(*iFileLockObservers)[ii];
1.839 + server->CloseFileL(aFlag,name);
1.840 + }
1.841 + }
1.842 + }
1.843 +
1.844 +void CBaServBackupSession::SignalRetakeAllFileLocks()
1.845 + {
1.846 +// CBaBackupServer* server=BackupServer();
1.847 + if (iReleasedFiles)
1.848 + {
1.849 + const TInt count=iReleasedFiles->Count();
1.850 + for (TInt ii=count-1;ii>=0;ii--)
1.851 + {
1.852 + TFileName name=(*iReleasedFiles)[ii];
1.853 +// server->RestartFile(name);
1.854 + SignalRetakeFileLocks(name);
1.855 + }
1.856 + }
1.857 + }
1.858 +
1.859 +LOCAL_C void CleanupCloseFail(TAny* aPtr)
1.860 + {
1.861 + CDesCArray* array=REINTERPRET_CAST(CDesCArray*,aPtr);
1.862 + array->Delete(array->Count()-1);
1.863 + }
1.864 +
1.865 +void CBaServBackupSession::SignalReleaseFileLockL(MBackupObserver::TFileLockFlags aFlag,const TDesC& aFileName)
1.866 + {
1.867 + TInt pos;
1.868 + if (iFileLockObservers && iFileLockObservers->Find(aFileName,pos)==KErrNone)
1.869 + {
1.870 + if (iReleasedFiles==NULL)
1.871 + {
1.872 + iReleasedFiles=new(ELeave) CDesCArraySeg(1);
1.873 + }
1.874 + const TBool addedReleasedFile=iReleasedFiles->Find(aFileName,pos)!=KErrNone;
1.875 + if (addedReleasedFile)
1.876 + {
1.877 + iReleasedFiles->AppendL(aFileName);
1.878 + CleanupStack::PushL(TCleanupItem(CleanupCloseFail,iReleasedFiles));
1.879 + }
1.880 + iMessageQueue->AddItemL(aFileName,aFlag);
1.881 + if (!iNotificationPullMsg.IsNull())
1.882 + {
1.883 + iNotificationPullMsg.Complete(KErrNone);
1.884 +
1.885 + // Okay - if this is part of a CloseAll operation we need to kick off a ReRegistration timer
1.886 + if (BackupServer()->IsCloseAllOperationRunning())
1.887 + {
1.888 + // Set backup server for the timer
1.889 + iReRegistrationTimer->iBackupServer = BackupServer();
1.890 +
1.891 + // If hardware use patchable constant if not default to 3 seconds
1.892 + iReRegistrationTimer->Start(KBaBackupFileLockReRegistrationTimeout, KBaBackupFileLockReRegistrationTimeout, TCallBack(CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack, iReRegistrationTimer));
1.893 + }
1.894 +
1.895 + }
1.896 + if (addedReleasedFile)
1.897 + {
1.898 + CleanupStack::Pop(); // CleanupCloseFail
1.899 + }
1.900 + }
1.901 + }
1.902 +
1.903 +void CBaServBackupSession::SignalRetakeFileLocks(const TDesC& aFileName)
1.904 + {
1.905 + if (iReleasedFiles)
1.906 + {
1.907 + const TInt count=iReleasedFiles->Count();
1.908 + for (TInt ii=count-1;ii>=0;ii--)
1.909 + {
1.910 + TFileName name=(*iReleasedFiles)[ii];
1.911 + if (name.MatchF(aFileName)==0)
1.912 + {
1.913 + iMessageQueue->AddItem(aFileName);
1.914 + if (!iNotificationPullMsg.IsNull())
1.915 + {
1.916 + iNotificationPullMsg.Complete(KErrNone);
1.917 + }
1.918 + iReleasedFiles->Delete(ii);
1.919 + }
1.920 + }
1.921 + if (iReleasedFiles->Count()==0)
1.922 + {
1.923 + delete iReleasedFiles;
1.924 + iReleasedFiles=NULL;
1.925 + if (iClosedFiles==NULL && BackupServer()->IsClientBusy(iUniqueClientId))
1.926 + {
1.927 + BackupServer()->SetBusy(0);
1.928 + }
1.929 + }
1.930 + }
1.931 + }
1.932 +
1.933 +/**
1.934 + *
1.935 + * Allows the session to handle the error.
1.936 + *
1.937 + * @param "TInt aError"
1.938 + * The error.
1.939 + */
1.940 +EXPORT_C void CBaServBackupSession::HandleError(TInt aError)
1.941 + {
1.942 + if (aError==KLeaveWithoutAlert)
1.943 + {
1.944 + CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
1.945 + }
1.946 + }
1.947 +
1.948 +void CBaServBackupSession::DoServiceL(TCompletionType& aCompleteType)
1.949 + {
1.950 + switch (iClientMessage->Function())
1.951 + {
1.952 + case EBakOpCodeEventReady:
1.953 + {
1.954 + HandleEventReadyL();
1.955 + aCompleteType = ECompleteAsync;
1.956 + }
1.957 + break;
1.958 + case EBakOpCodeStopNotifications:
1.959 + {
1.960 + StopNotifications();
1.961 + }
1.962 + break;
1.963 + case EBakOpCodeGetEvent:
1.964 + GetEventL();
1.965 + break;
1.966 + case EBakOpCodeCloseAllFiles:
1.967 + {
1.968 + aCompleteType = CloseAllFilesL(iClientMessage->Message());
1.969 + }
1.970 + break;
1.971 + case EBakOpCodeRestartAll:
1.972 + RestartAll();
1.973 + break;
1.974 + case EBakOpCodeCloseFile:
1.975 + CloseFileL();
1.976 + break;
1.977 + case EBakOpCodeRestartFile:
1.978 + RestartFileL();
1.979 + break;
1.980 + case EBakOpCodeNotifyLockChange:
1.981 + NotifyLockChangeL();
1.982 + break;
1.983 + case EBakOpCodeNotifyLockChangeCancel:
1.984 + NotifyLockChangeCancelL();
1.985 + break;
1.986 + case EBakOpCodeNotifyBackupOperation:
1.987 + NotifyBackupOperationL();
1.988 + break;
1.989 + case EBakOpCodeCancelOutstandingBackupOperationEvent:
1.990 + {
1.991 + iBackupOperationObserverPresent = EFalse;
1.992 + if (!iBackupOperationMessagePtr.IsNull())
1.993 + {
1.994 + GetBackupOperationEventL(iBackupOperationMessagePtr);
1.995 + iBackupOperationMessagePtr.Complete(KErrCancel);
1.996 + }
1.997 + }
1.998 + break;
1.999 + case EBakOpCodeGetBackupOperationState:
1.1000 + GetBackupOperationStateL();
1.1001 + break;
1.1002 + case EBakOpCodeBackupOperationEventReady:
1.1003 + BackupOperationEventReadyL();
1.1004 + aCompleteType = ECompleteAsync;
1.1005 + break;
1.1006 + case EBakOpCodeGetBackupOperationEvent:
1.1007 + GetBackupOperationEventL(iClientMessage->Message());
1.1008 + break;
1.1009 + case EBakOpCodeSetBackupOperationObserverIsPresent:
1.1010 + {
1.1011 + iBackupOperationObserverPresent = iClientMessage->GetIntL(0);
1.1012 + }
1.1013 + break;
1.1014 + default:
1.1015 + User::Leave(KErrNotSupported);
1.1016 + break;
1.1017 + }
1.1018 + }
1.1019 +
1.1020 +
1.1021 +/**
1.1022 + *
1.1023 + * Handles the servicing of client requests passed to the backup server.
1.1024 + *
1.1025 + * @param "const RMessage& aMessage"
1.1026 + * The message containing the client request.
1.1027 + */
1.1028 +EXPORT_C void CBaServBackupSession::ServiceL(const RMessage2& aMessage)
1.1029 + {
1.1030 +
1.1031 + TCompletionType completionType = ECompleteSync;
1.1032 +
1.1033 + BSUL::CClientMessage* clientMessage = 0;
1.1034 + clientMessage = BSUL::CClientMessage::NewL(aMessage);
1.1035 +
1.1036 + //Push iClientMessage onto the cleanupstack. Although an instance variable,
1.1037 + //the lifetime of the object is contained to this function so it needs to
1.1038 + //be pushed and popped here as it is not deleted in the destructor
1.1039 + CleanupStack::PushL(clientMessage);
1.1040 +
1.1041 + //Validate the message
1.1042 + TRAPD(error, clientMessage->ValidateL());
1.1043 +
1.1044 + iClientMessage = clientMessage;
1.1045 +
1.1046 + if(error == KErrNone)
1.1047 + {
1.1048 + TRAP(error, DoServiceL(completionType));
1.1049 + }
1.1050 +
1.1051 + if(completionType == ECompleteSync)
1.1052 + {
1.1053 + if (error==KLeaveWithoutAlert)
1.1054 + {
1.1055 + CBaServBackupScheduler::Current()->SetErrorHandler(NULL);
1.1056 + }
1.1057 + else
1.1058 + {
1.1059 + iClientMessage->CompleteRequestL(error);
1.1060 + }
1.1061 + }
1.1062 +
1.1063 + //Pop and destroy message
1.1064 + CleanupStack::PopAndDestroy(clientMessage);
1.1065 + clientMessage = NULL;
1.1066 + iClientMessage = NULL;
1.1067 + }
1.1068 +
1.1069 +void CBaServBackupSession::HandleEventReadyL()
1.1070 + {
1.1071 + if (iReRegistrationTimer->IsActive())
1.1072 + { // If timer is still active (ie not timed out) we need to increment the counter and cancel the timer
1.1073 + BackupServer()->IncrementFilesReRegistrationCount();
1.1074 + iReRegistrationTimer->Cancel();
1.1075 + }
1.1076 + // else timer is already inactive because it's expired
1.1077 +
1.1078 + if (iMessageQueue->IsEmpty())
1.1079 + {
1.1080 + iNotificationPullMsg = iClientMessage->Message();
1.1081 + }
1.1082 + else
1.1083 + {
1.1084 + iClientMessage->CompleteRequestL(KErrNone);
1.1085 + }
1.1086 + }
1.1087 +
1.1088 +const TInt KEventFileNameOffset=1;
1.1089 +
1.1090 +void CBaServBackupSession::GetEventL()
1.1091 + {
1.1092 + TFileName fileName;
1.1093 + MBackupObserver::TFileLockFlags fileFlag;
1.1094 + if(!iMessageQueue->IsEmpty())
1.1095 + {
1.1096 + iMessageQueue->GetHead(fileName,fileFlag);
1.1097 + TBuf<KEventFileNameOffset> num;
1.1098 + num.Num((TInt)fileFlag);
1.1099 +
1.1100 + iClientMessage->WriteL(0,num,0);
1.1101 +
1.1102 + iClientMessage->WriteL(0,fileName,KEventFileNameOffset);
1.1103 +
1.1104 + iMessageQueue->RemoveHead();
1.1105 + }
1.1106 + else
1.1107 + {
1.1108 + iClientMessage->PanicClient(KPanic,ENoEventToFetch);
1.1109 + User::Leave(KLeaveWithoutAlert);
1.1110 + }
1.1111 + }
1.1112 +
1.1113 +void CBaServBackupSession::CleanupCloseAllFiles(TAny* aPtr)
1.1114 + { // static
1.1115 + CBaServBackupSession* self=REINTERPRET_CAST(CBaServBackupSession*,aPtr);
1.1116 + delete self->iClosedFiles;
1.1117 + self->iClosedFiles=NULL;
1.1118 + self->BackupServer()->RestartAll();
1.1119 + }
1.1120 +
1.1121 +/**
1.1122 + Asks the server to close all files. This function may leave in case the server is busy.
1.1123 + If the requesting client is the current busy client and it has already requested CloseAll,
1.1124 + this request will be ignored.
1.1125 +
1.1126 + @param aMessage The reference to the message containing the client request: file lock.
1.1127 + @leave KErrServerBusy if the requesting client is not the busy client. Plus other system-wide
1.1128 + errors.
1.1129 + */
1.1130 +EXPORT_C TCompletionType CBaServBackupSession::CloseAllFilesL(const RMessage2& aMessage)
1.1131 + {
1.1132 + // Raise file lock notifications
1.1133 + TRAPD(err,DoCloseAllFilesL(aMessage));
1.1134 +
1.1135 + if (err == KErrNone)
1.1136 + {
1.1137 + // Start timer to check all file locks re-registered before completing message
1.1138 + BackupServer()->StartCloseAllFilesOperationTimer(aMessage);
1.1139 + }
1.1140 + else
1.1141 + {
1.1142 + // If the error is that the same client has already requested CloseAll, ignore this request
1.1143 + // If not this error, recover the CloseAllOperationRunningState flag and leave with the error.
1.1144 + if (err != KErrAlreadyExists)
1.1145 + {
1.1146 + BackupServer()->SetCloseAllOperationRunningState(EFalse);
1.1147 + User::Leave(err);
1.1148 + }
1.1149 + }
1.1150 +
1.1151 + return ECompleteAsync;
1.1152 + }
1.1153 +
1.1154 +void CBaBackupServer::IncrementRegisteredFilesCount()
1.1155 + {
1.1156 + iRegisteredFilesCount++;
1.1157 + }
1.1158 +
1.1159 +void CBaBackupServer::DecrementRegisteredFilesCount(TInt aNumberFiles)
1.1160 + {
1.1161 + iRegisteredFilesCount = iRegisteredFilesCount - aNumberFiles;
1.1162 + }
1.1163 +
1.1164 +void CBaBackupServer::IncrementFilesReRegistrationCount()
1.1165 + {
1.1166 + iSessionLockReRegistrationCount++;
1.1167 + }
1.1168 +
1.1169 +/**
1.1170 + Function called by both base and derived backup sessions in order to start asynchronous
1.1171 + file lock notifications.
1.1172 + The requesting client is set to the current busy client.
1.1173 +
1.1174 + @leave KErrServerBusy if the requesting client is not the current busy client or the server
1.1175 + is under CloseAll operation. KErrAlreadyExists if the same client has sent CloseAll request.
1.1176 + Plus other system-wide errors.
1.1177 + */
1.1178 +
1.1179 +EXPORT_C TCompletionType CBaServBackupSession::DoCloseAllFilesL(const RMessage2& /*aMessage*/)
1.1180 + {
1.1181 + CBaBackupServer* server=BackupServer();
1.1182 + if (server->IsOtherClientBusy(iUniqueClientId))
1.1183 + {
1.1184 + User::Leave(KErrServerBusy);
1.1185 + }
1.1186 +
1.1187 + if (BackupServer()->IsCloseAllOperationRunning())
1.1188 + {
1.1189 + User::Leave(KErrAlreadyExists);
1.1190 + }
1.1191 +
1.1192 + CleanupStack::PushL(TCleanupItem(CleanupCloseAllFiles,this));
1.1193 + if (iClosedFiles)
1.1194 + {
1.1195 + delete iClosedFiles;
1.1196 + iClosedFiles=NULL;
1.1197 + }
1.1198 + server->SetBusy(iUniqueClientId);
1.1199 +
1.1200 + MBackupObserver::TFileLockFlags fileFlag=
1.1201 + (MBackupObserver::TFileLockFlags)iClientMessage->GetIntL(0);
1.1202 + server->CloseAllFilesL(fileFlag);
1.1203 +
1.1204 + iClosedFiles=new(ELeave) CArrayFixSeg<CBaServBackupSession::TClosedFile>(1);
1.1205 + CBaServBackupScheduler::Current()->SetErrorHandler(this);
1.1206 + CleanupStack::Pop(); // CleanupCloseAllFiles
1.1207 + return ECompleteAsync;
1.1208 + }
1.1209 +
1.1210 +/**
1.1211 + *
1.1212 + * Asks the server to signal all clients of getting the lock of their respective files.
1.1213 + *
1.1214 + */
1.1215 +EXPORT_C void CBaServBackupSession::RestartAll()
1.1216 + {
1.1217 + CBaBackupServer* server=BackupServer();
1.1218 + if (server->IsClientBusy(iUniqueClientId))
1.1219 + {
1.1220 + DoRestartAll();
1.1221 + }
1.1222 + }
1.1223 +
1.1224 +void CBaServBackupSession::DoRestartAll()
1.1225 + {
1.1226 + CBaBackupServer* server=BackupServer();
1.1227 + server->RestartAll();
1.1228 + delete iReleasedFiles;
1.1229 + iReleasedFiles=NULL;
1.1230 + if (iClosedFiles)
1.1231 + {
1.1232 + CArrayFix<CBaServBackupSession::TClosedFile>* closedFiles=iClosedFiles;
1.1233 + iClosedFiles=NULL;
1.1234 + server->CompleteClosingFiles(closedFiles); // takes ownership of closedFiles immediately
1.1235 + }
1.1236 + }
1.1237 +
1.1238 +/**
1.1239 +Handle the client's request to close a file.
1.1240 +The request will be ignored if the requesting client the current busy client and the server is
1.1241 +under CloseAll operation.
1.1242 +
1.1243 +@leave KErrServerBusy if the server is busy with the other client, plus other system-wide errors.
1.1244 +*/
1.1245 +void CBaServBackupSession::CloseFileL()
1.1246 + {
1.1247 + CBaBackupServer* server=BackupServer();
1.1248 + if (server->IsOtherClientBusy(iUniqueClientId))
1.1249 + {
1.1250 + User::Leave(KErrServerBusy);
1.1251 + }
1.1252 +
1.1253 + if (! server->IsCloseAllOperationRunning())
1.1254 + {
1.1255 + MBackupObserver::TFileLockFlags flag=
1.1256 + static_cast<MBackupObserver::TFileLockFlags>(iClientMessage->GetIntL(2));
1.1257 + TFileName fileName;
1.1258 + GetFileNameL(fileName);
1.1259 + server->SetBusy(iUniqueClientId);
1.1260 + server->CloseFileL(flag,fileName);
1.1261 + }
1.1262 + }
1.1263 +
1.1264 +void CBaServBackupSession::RestartFileL()
1.1265 + {
1.1266 + TFileName fileName;
1.1267 + GetFileNameL(fileName);
1.1268 + BackupServer()->RestartFile(fileName);
1.1269 + }
1.1270 +
1.1271 +/**
1.1272 +Handles the client's request of notification of a file lock change.
1.1273 +
1.1274 +@leave KErrServerBusy if the server is under CloseAll operation, KLeaveWithoutAlert if the requested
1.1275 + file has been registered. Plus other system-wide errors.
1.1276 +*/
1.1277 +void CBaServBackupSession::NotifyLockChangeL()
1.1278 + {
1.1279 + if(BackupServer()->IsCloseAllOperationRunning())
1.1280 + {
1.1281 + User::Leave(KErrServerBusy);
1.1282 + }
1.1283 +
1.1284 + TFileName fileName;
1.1285 + GetFileNameL(fileName);
1.1286 + if (iFileLockObservers==NULL)
1.1287 + {
1.1288 + iFileLockObservers=new(ELeave) CDesCArraySeg(1);
1.1289 + }
1.1290 + else
1.1291 + {
1.1292 + TInt pos;
1.1293 + if(iFileLockObservers->Find(fileName,pos)== KErrNone)
1.1294 + {
1.1295 + iClientMessage->PanicClient(KPanic,EReqAlreadyOutstanding);
1.1296 + User::Leave(KLeaveWithoutAlert);
1.1297 + }
1.1298 + }
1.1299 + iFileLockObservers->AppendL(fileName);
1.1300 + BackupServer()->IncrementRegisteredFilesCount();
1.1301 + }
1.1302 +
1.1303 +LOCAL_C void RemoveFileName(CDesCArray& aArray,const TDesC& aFileName)
1.1304 + {
1.1305 + TInt pos;
1.1306 + if (aArray.Find(aFileName,pos)==KErrNone)
1.1307 + {
1.1308 + aArray.Delete(pos);
1.1309 + }
1.1310 + }
1.1311 +
1.1312 +void CBaServBackupSession::NotifyLockChangeCancelL()
1.1313 + {
1.1314 + TFileName fileName;
1.1315 + GetFileNameL(fileName);
1.1316 + if (iFileLockObservers)
1.1317 + {
1.1318 + RemoveFileName(*iFileLockObservers,fileName);
1.1319 + BackupServer()->DecrementRegisteredFilesCount();
1.1320 + }
1.1321 + if (iReleasedFiles)
1.1322 + {
1.1323 + RemoveFileName(*iReleasedFiles,fileName);
1.1324 + }
1.1325 + iMessageQueue->RemoveItem(fileName);
1.1326 + }
1.1327 +
1.1328 +void CBaServBackupSession::GetFileNameL(TDes& aFileName)
1.1329 + {
1.1330 + //The verification of this parameter has already been handled
1.1331 + //by the CClientMessage class so we can safely read the value
1.1332 + iClientMessage->ReadL(1,aFileName);
1.1333 + }
1.1334 +
1.1335 +
1.1336 +void CBaServBackupSession::GetBackupOperationEventL(const RMessagePtr2& aPtr)
1.1337 + {
1.1338 + TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
1.1339 +
1.1340 + aPtr.WriteL(0, backupOpAttPkg);
1.1341 + }
1.1342 +
1.1343 +void CBaServBackupSession::BackupOperationEventReadyL()
1.1344 + {
1.1345 + if (iBackupOperationObserverPresent)
1.1346 + {
1.1347 + iBackupOperationMessagePtr = iClientMessage->Message();
1.1348 + }
1.1349 + else
1.1350 + {
1.1351 + iClientMessage->CompleteRequestL(KErrNone);
1.1352 + }
1.1353 + }
1.1354 +
1.1355 +void CBaServBackupSession::NotifyBackupOperationL()
1.1356 + {
1.1357 + CBaBackupServer* server=BackupServer();
1.1358 + if (server->CBaBackupServer::IsOtherClientBusy(iUniqueClientId))
1.1359 + {
1.1360 + User::Leave(KErrServerBusy);
1.1361 + }
1.1362 + TPckg<TBackupOperationAttributes> backupOpAttPkg(iBackupOperationAttributes);
1.1363 +
1.1364 + iClientMessage->ReadL(0,backupOpAttPkg);
1.1365 +
1.1366 + const TBool backupOperationRunning = ((iBackupOperationAttributes.iOperation==MBackupOperationObserver::EStart) ? ETrue : EFalse);
1.1367 + server->SetBackupOperationRunning(backupOperationRunning);
1.1368 + server->SetBusy(backupOperationRunning ? iUniqueClientId : 0);
1.1369 + server->SignalBackupOperation(iBackupOperationAttributes);
1.1370 + if (!iBackupOperationMessagePtr.IsNull())
1.1371 + {
1.1372 + GetBackupOperationEventL(iBackupOperationMessagePtr);
1.1373 + iBackupOperationMessagePtr.Complete(KErrCancel);
1.1374 + }
1.1375 + }
1.1376 +
1.1377 +void CBaServBackupSession::GetBackupOperationStateL()
1.1378 + {
1.1379 + const TBool isRunning = BackupServer()->IsBackupOperationRunning();
1.1380 + TPckgC<TBool> pkgObs(isRunning);
1.1381 +
1.1382 + iClientMessage->WriteL(0, pkgObs);
1.1383 + }
1.1384 +
1.1385 +void CBaServBackupSession::SignalBackupOperation(const TBackupOperationAttributes& aBackupOperationAttributes)
1.1386 + {
1.1387 + iBackupOperationAttributes = aBackupOperationAttributes;
1.1388 + if (!iBackupOperationMessagePtr.IsNull())
1.1389 + {
1.1390 + TRAPD(err,GetBackupOperationEventL(iBackupOperationMessagePtr));
1.1391 + iBackupOperationMessagePtr.Complete(err);
1.1392 + }
1.1393 + }
1.1394 +
1.1395 +void CBaServBackupSession::StopNotifications()
1.1396 + {
1.1397 + if(!iNotificationPullMsg.IsNull())
1.1398 + {// complete the registration message
1.1399 + iNotificationPullMsg.Complete(KErrNone);
1.1400 + }
1.1401 + }
1.1402 +
1.1403 +/**
1.1404 +@internalComponent
1.1405 +*/
1.1406 +CBaServBackupSession::CReRegistrationTimer* CBaServBackupSession::CReRegistrationTimer::NewL(TInt aPriority)
1.1407 + { // static
1.1408 + CBaServBackupSession::CReRegistrationTimer* self=new(ELeave) CBaServBackupSession::CReRegistrationTimer(aPriority);
1.1409 + CleanupStack::PushL(self);
1.1410 + self->ConstructL();
1.1411 + CleanupStack::Pop(); // self
1.1412 + CActiveScheduler::Add(self);
1.1413 + return self;
1.1414 + }
1.1415 +
1.1416 +/**
1.1417 +@internalComponent
1.1418 +*/
1.1419 +TInt CBaServBackupSession::CReRegistrationTimer::RunError(TInt aError)
1.1420 + {
1.1421 + if (aError==KLeaveWithoutAlert)
1.1422 + {
1.1423 + return KErrNone;
1.1424 + }
1.1425 + return aError;
1.1426 + }
1.1427 +
1.1428 +/**
1.1429 +@internalComponent
1.1430 +*/
1.1431 +CBaServBackupSession::CReRegistrationTimer::CReRegistrationTimer(TInt aPriority)
1.1432 + : CPeriodic(aPriority)
1.1433 + { }
1.1434 +
1.1435 +/**
1.1436 +@internalComponent
1.1437 +*/
1.1438 +TInt CBaServBackupSession::CReRegistrationTimer::ReRegistrationTimerCallBack(TAny* aPtr)
1.1439 + { // static
1.1440 + TRAP_IGNORE(REINTERPRET_CAST(CBaServBackupSession::CReRegistrationTimer*,aPtr)->HandleReRegistrationTimerCallBack());
1.1441 + return 0;
1.1442 + }
1.1443 +
1.1444 +/**
1.1445 +@internalComponent
1.1446 +*/
1.1447 +void CBaServBackupSession::CReRegistrationTimer::HandleReRegistrationTimerCallBack()
1.1448 + {
1.1449 + iBackupServer->IncrementFilesReRegistrationCount();
1.1450 +
1.1451 + if (IsActive())
1.1452 + {
1.1453 + Cancel();
1.1454 + }
1.1455 + }
1.1456 +