Server lifetime and resource clean-up
Sander van der Wal wrote:
>
>
> All server programmers must worry about all resource leaks (open files, open
> windows, etc). The uikon framework is special because it checks for resource
> leaks.
>
And it's a really good idea to do it yourself for your server. Something
like:
void CContextServer::ThreadFunctionL()
{
#if defined (__WINS__)
UserSvr::ServerStarted();
#endif
__UHEAP_MARK;
// Construct active scheduler
CActiveScheduler* activeScheduler = new (ELeave) CBaActiveScheduler;
CleanupStack::PushL(activeScheduler) ;
// Install active scheduler
// We don't need to check whether an active scheduler is already installed
// as this is a new thread, so there won't be one
CActiveScheduler::Install(activeScheduler);
// Construct our server
CContextServer::NewLC();
RSemaphore semaphore;
if (semaphore.CreateGlobal(KContextServerSemaphoreName, 0)!=KErrNone) {
User::LeaveIfError(semaphore.OpenGlobal(KContextServerSemaphoreName));
}
// Semaphore opened ok
semaphore.Signal();
semaphore.Close();
// Start handling requests
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(2,activeScheduler); // CServer
__UHEAP_MARKEND;
}
as your server startup function should do. The __UHEAP_MARK and
__UHEAP_MARKEND will check that the server doesn't lose any memory
while running.
Vlad wrote:
> Hi Mika,
>
I second Sander's recommendation to get Symbian OS C++ Programming for Mobile Phones.
>
> 1. What happens to the flow of execution after CActiveScheduler::Start() in
> your sample code (which is very similar to mine)? Does the thread block
> until the server somehow shuts itslef down or does it just continue
> afterwards and exit?
Unless you have some stringent time constraints I'd recommend stopping your server when the last session goes away (or you can do this for debug/wins and leave the server running in release/armi), like this:
void CContextServer::DecrementSessions()
{
iSessionCount--;
if (iSessionCount <= 0)
{
iSessionCount =0;
// stop your processing
iJabberClient->Disconnect(EFalse);
CActiveScheduler::Stop();
}
}
After CActiveScheduler::Stop() is called the CActiveScheduler::Start
returns and the code flow resumes in your ThreadFunctionL(). There
you delete the server object which should take care of releasing all
resources it has allocated. The sessions themselves should release
all resources _they_ have allocated in their destructors.
>
> I guess these questions stem from a fundamental lack of understanding of
> servers...
>
> 2. Is it true that after a server finishes its startup function akin to your
> ThreadFunctionL, the server is somehow registered with symbian OS and after
> that all resource cleanup is handled by the individual sessions?
No. The startup function is not finished until the server exits. Resource cleanup is not handled only by sessions, but the server must
handle it for per-server resources. The server is registered with a name
by calling CServer::StartL(name), but it has nothing to do with
resources.
When a client calls RSessionBase::CreateSession(name, version, slots)
the framework calls the server's NewSessionL which creates a new
server-side session object (as well as calling IncrementSessions).
When Close() is called on the client side session the server side
session object is deleted and CServer::DecrementSessions is called.
I'm not quite sure what happens if the client dies without calling
Close().
>
> 3. How can I make sure the individual sessions aren't leaking memory on the
> server side? Anything other than creating my own RChunk of memory
> explicitely for allocating memory for each session and then making sure that
> all memory is returned to the chunk?
If the server in total is not leaking (as checked by the __UHEAP*
macros) neither are the sessions, as the memory comes from the
same heap. I don't see any good reason for using RChunks.
>
> Thanks a lot,
>
> Vlad
Mika