examples/Base/IPC/AdvancedClientServerExample/ThreadServer/src/threadserver.cpp

00001 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 //
00015 
00016 #include "threadserver.h"
00017 #include "threadserverstart.h"
00018 #include "threadserversession.h"
00019 
00020 const TInt KThreadServerShutDownDelay = 50000000; //50 sec
00021 
00022 
00023 //******CThreadServer******//
00027 void CThreadServer::NewLC()
00028         {
00029         CThreadServer* s = new(ELeave) CThreadServer();
00030         CleanupStack::PushL(s);
00031         s->ConstructL();
00032         }
00036 CThreadServer::CThreadServer()
00037         :CServer2(EPriorityStandard, ESharableSessions),iDriverState(EStateUnknown)
00038         {
00039         }
00040 void CThreadServer::ConstructL()
00041         {
00042         // Call CServer2::StartL() before any other functions inside ConstructL
00043         // to avoid errors other than KErrAlreadyExists when the duplicate Server starts
00044         StartL(KThreadServerName);
00045         iDelayThreadServerShutDown = CDelayServerShutDown::NewL();
00046         }
00050 CThreadServer::~CThreadServer()
00051         {
00052         if (iDelayThreadServerShutDown)
00053                 {
00054                 iDelayThreadServerShutDown->Cancel();
00055                 delete iDelayThreadServerShutDown;
00056                 }
00057         // unload device driver when server terminated
00058         UnloadDevice();
00059         }
00066 CSession2* CThreadServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/) const
00067         {
00068         //check whether version is compatible
00069         TVersion v(KThreadServerVersion,KThreadServerMinorVersionNumber,KThreadServerBuildVersionNumber);
00070         if(!User::QueryVersionSupported(v, aVersion))
00071                 User::Leave(KErrNotSupported);
00072 
00073         // construct and return the server side client session object
00074         CThreadServer& ncThis = const_cast<CThreadServer&>(*this);
00075         CThreadServerSession* serverSession = CThreadServerSession::NewL(ncThis);
00076         return serverSession;
00077         }
00081 void CThreadServer::IncrementRefCount()
00082         {
00083         iRefCount++;
00084         iDelayThreadServerShutDown->Cancel(); // Cancel shutdown if it has started due to no clients being connected.
00085         }
00089 void CThreadServer::DecrementRefCount() 
00090         {
00091         iRefCount--;
00092         if ( iRefCount == 0 )
00093                 {
00094                 iDelayThreadServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KThreadServerShutDownDelay));
00095                 }
00096         }
00100 void CThreadServer::RenameServer()
00101         {
00102         //Rename thread server name in order to prevent same name creation
00103         RThread serverThread;
00104         TThreadId threadId;
00105         TName name;
00106         name.Append(KThreadServerName); 
00107         threadId = serverThread.Id();
00108         name.AppendNum(threadId.Id(),EHex);
00109         //We are ignoring the error code returned from User::RenameThread
00110         //as it is not important here, it may be used for profiling
00111         User::RenameThread(name);
00112         }
00117 TInt CThreadServer::LoadDevice()
00118         {
00119         if (iDriverState>=EDriverLoaded && iDriverState<EDriverUnloaded)
00120                 return KErrNone; //Device has been loaded, return immediately
00121                 
00122         TInt r=User::LoadPhysicalDevice(KThreadServerDriverPddFileName);
00123         if (r!=KErrNone && r!=KErrAlreadyExists)
00124                 return r; //some error occurred
00125         
00126         r = User::LoadLogicalDevice(KThreadServerDriverLddFileName);
00127         if (r!=KErrNone && r!=KErrAlreadyExists)
00128                 return r; //some error occurred 
00129         
00130         //both PDD and LDD have been loaded
00131         UpdateDriverState(EDriverLoaded);
00132         return KErrNone; 
00133         }
00138 TInt CThreadServer::UnloadDevice()
00139         {
00140         if (iDriverState==EDriverUnloaded || iDriverState == EStateUnknown)
00141                 return KErrNone; //no device is loaded, return immediately
00142                 
00143         // close device
00144         if (iDriver.Handle())
00145                 iDriver.Close();
00146         // Unload Logical Device
00147         TInt r = User::FreeLogicalDevice(RDriver1::Name());
00148         if (r!=KErrNone)
00149                 return r;
00150         // Unload Physical Device
00151         TName pddName(RDriver1::Name());
00152         _LIT(KVariantExtension,".template");
00153         pddName.Append(KVariantExtension);
00154         r=User::FreePhysicalDevice(pddName);
00155         
00156         if (KErrNone==r)
00157                 UpdateDriverState(EDriverUnloaded);     
00158         return r;
00159         }
00164 TInt CThreadServer::OpenLogicalChannel()
00165         {
00166         if (iDriverState>=ELogicalChannelOpened && iDriverState<ELogicalChannelClosed)
00167                 return KErrNone;
00168         
00169         TInt r = iDriver.Open();
00170         if (KErrNone==r)
00171                 UpdateDriverState(ELogicalChannelOpened);
00172         
00173         return r;
00174         }
00178 void CThreadServer::CloseLogicalChannel()
00179         {
00180         if (iDriver.Handle())
00181                 {
00182                 iDriver.Close();
00183                 UpdateDriverState(ELogicalChannelClosed);
00184                 }
00185         }
00192 TInt CThreadServer::SendDataToDevice(TRequestStatus& aStatus, const TDesC8& aData)
00193         {
00194         TInt r = KErrNone;
00195         if (iDriverState>=ELogicalChannelOpened && iDriverState<ELogicalChannelClosed)
00196                 {
00197                 iDriver.SendData(aStatus, aData);
00198                 UpdateDriverState(ESendingData);
00199                 }
00200         else
00201                 {
00202                 r = KErrArgument;
00203                 }
00204         return r;
00205         }
00209 void CThreadServer::CancelSendData()
00210         {
00211         iDriver.SendDataCancel();
00212         UpdateDriverState(ELogicalChannelOpened);
00213         }
00218 void CThreadServer::UpdateDriverState(TDriverState aState)
00219         {
00220         iDriverState = aState;
00221         }
00222 //EOF

Generated by  doxygen 1.6.2