Wednesday, April 21, 2010

Singelton Design pattern

Singleton design pattern in used in cases where you want to have only one instance of the class.
Below is a sample code in c++ which shows how to achieve this
--------------------------------------------------------
//Header file : mySingleton.h file
class mySingleton
{

public:
static mySingleton* getInstance();
void releaseInstance();
void myFunction_1();
void myFunction_2();
private:
mySingleton();
~mySingleton();

private: //member varibles
static mySingleton* mStaticInstance;
static int mRefCount;
};
--------------------------------------------------------
//Source File : mySingleton.cpp


//Initilize the sttatic varibles to 0
mySingleton* mySingleton::mStaticInstance = 0;
int mySingleton::mRefCount = 0;

mySingleton* mySingleton::getInstance()
{
if(!mySingleton::mStaticInstance)
{
mySingleton::mStaticInstance = new mySingleton();
}
// Increment the reference count
mySingleton::mRefCount++;
return mySingleton::mStaticInstance;

}
void mySingleton::releaseInstance()
{
if(mySingleton::mRefCount > 0)
{
//Decrease the reference count
mySingleton::mRefCount--;
}
// delete if referece count is zero
if (mRefCount== 0)
{
delete mStaticInstance;
mStaticInstance = NULL;
}


}
mySingleton::mySingleton()
{
//Private constructor, so that it cannot be instantiated
//Inilitize data memebers,if any , for the class

}

mySingleton::~mySingleton()
{

//release resouces, if any

}

void mySingleton::myFunction_1()
{
//perform your operation

}


void mySingleton::myFunction_2()
{
//perform your operation

}


--------------------------------------------------------
//main function

main ()
{

//Get the singleton instance
mySingleton* sPtr = mySingleton::getInstance();

//Perfrom operaions
sPtr->myFunction_1();
sPtr->myFunction_2();

//Release the instance
sPtr->releaseInstance();
}

Tuesday, September 8, 2009

Server crash notification in Symbian

It is possible to get a notification when a server has crashed.
For example,
If you have process A which is a client of server B. Now if process B crashes, the session started by process A becomes invalid. You can check the return value of request made to server B and then you can decide to restart the server B.
Alternatively you can logon to server B. So when server B dies, it sends a notification when it panics or is terminated. You can you check the documentation for more details ( check either for RUndertaker ,RThread or Rprocess)
Below is an example implementation.
----------------------------------------------------------
This is the interface class that has the virtual method ProcessTerminatedL() to indicate the termination of server.

#ifndef MSERVERMONITOR_H_
#define MSERVERMONITOR_H_
#include <e32const.h>
class MServerMonitor
{
public:
virtual ~MServerMonitor() {}
public: // Interface
/**
* Callback indicating the termination the Process.
*
*/
virtual void ProcessTerminatedL(TExitType aExitType) = 0;

};
#endif /* MPBK2SERVERMONITOR_H_ */

-------------------- cmyservermonitor.h --------------------------------------
This is the actual server monitor class. It is a simple class with an instance of RUndertaker object, that does the monitoring.

#ifndef C_MYSERVER_MONITOR_H_
#define C_MYSERVER_MONITOR_H_
#include <e32std.h>
#include <e32base.h>


class CMyServerMonitor:public CActive

{
public:
static CMyServerMonitor* NewLC(MServerMonitor& aReporter);
static CMyServerMonitor* NewL(MServerMonitor& aReporter);
~CMyServerMonitor();
public://from CActive
void RunL();
void DoCancel();
TInt RunError(TInt aError);
public:
TBool Monitoring();
void StartMonitoringL(TInt aThreadNumber);
void StopMonitoringL();

private:
CMyServerMonitor(MServerMonitor& aReporter);
void ConstructL();

private:
RUndertaker iUnderTaker ;
TInt iThreadNumber ;
MServerMonitor& iReporter;

};

#endif /*C_MYSERVER_MONITOR_H_*/
---------------------cmyservermonitor.cpp-------------------------------------
The implementation for the server monitor class.


#include "cmyservermonitor.h"

CMyServerMonitor::CMyServerMonitor(MServerMonitor& aReporter)
: CActive(EPriorityStandard),iReporter(aReporter), iThreadNumber(0)
{
CActiveScheduler::Add(this);
}


CMyServerMonitor::~CMyServerMonitor()
{
Cancel();
iUnderTaker.Close();
}

CMyServerMonitor* CMyServerMonitor::NewLC(MServerMonitor& aReporter)
{
CMyServerMonitor* self = new (ELeave)CMyServerMonitor(aReporter);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}

CMyServerMonitor* CMyServerMonitor::NewL(MServerMonitor& aReporter)
{
CMyServerMonitor* self=CMyServerMonitor::NewLC(aReporter);
CleanupStack::Pop(); // self;
return self;
}

void CMyServerMonitor::ConstructL()
{
iUnderTaker.Create();
}

void CMyServerMonitor::RunL()
{
if(iStatus == KErrDied)
{
//report reason
RThread th;
th.SetHandle(iThreadNumber);
TFullName name = th.FullName();
TExitType type = th.ExitType();
iReporter.ProcessTerminatedL(type);
th.Close();
}
else
{
//
//
}
}

void CMyServerMonitor::DoCancel()
{
iUnderTaker.LogonCancel();
}


TInt CMyServerMonitor::RunError(TInt aError)
{
return KErrNone;
}


void CMyServerMonitor::StartMonitoringL(TInt aThreadNumber)
{
iThreadNumber = aThreadNumber;
iUnderTaker.Logon(iStatus,iThreadNumber);
SetActive();
}

void CMyServerMonitor::StopMonitoringL()
{
Cancel();

}

TBool CMyServerMonitor::Monitoring()
{
return IsActive();
}
------------------------------------------------------------------

The Process (for example, class X) which wants to monitor should inherit from MServerMonitor and it should implment the ProcessTerminatedL(TExitType aExitType) method. Also class X, should create instance of CMyServerMonitor and start the monitoring by calling the StartMonitoringL(TInt aThreadNumber) method.

Below is sample code for the same

void X::ConstructL()
{
iServerMonitor = CMyServerMonitor::NewLC(*this);
CleanupStack::Pop();
StartServerMonitoringL();
}

void X::StartServerMonitoringL()
{

_LIT(KMatchName,"MyServer.exe*");
TFindThread procName(KMatchName);
TFullName processName;
RThread PsprocHandle;
TInt threadId = KErrNotFound;
if ( procName.Next(processName) == KErrNone )
{
TInt rc = PsprocHandle.Open(procName);
if (rc == KErrNone)
{
threadId = PsprocHandle.Id();
}
}
if(threadId != KErrNotFound)
{
//Start the logging process
iServerMonitor->StartMonitoringL(threadId);
}
}

void X::ProcessTerminatedL(TExitType aExitType)
{
if(aExitType == EExitPanic)
{
//Thread paniced. Restart the server
// Add code to restart the server here
// --
// --
// --

//Start the monitoring again
StartServerMonitoringL();
}
else //Exit other than panic
{

// take necessary action
}

}
----------------------------------------------------------


I hope the above code helps. Do add your comments if you find this post useful.

Tuesday, October 14, 2008

Error Handling in Symbian

Why do we need Cleanup stack?
Cleanups stack is needed to store the pointers to the objects created, so that they could be deleted in case of a leave.
Consider the below pseudo code.
--------------------------8<---------------------------
void Function1L()
{
TRAPD(err,Function2L());
}
void Function2L()
{
CObject* myObj=new (ELeave) CObject; //Create some object
CleanupStack::PushL(myObj); //Push it on the cleanup stack
Function3L(); // Call some leaving function
CleanupStack::PopAndDestroy(); //Destroy the created object
}
void Function3L()
{
//Some code which leaves
}

--------------------------8<---------------------------

When the above code is executed, it leaves in Function3. What happens to the memory allocated to myObj? If we did not have the cleanupstack, then the pointer to the myObj object would not be available. So the memory pointed by myObj would be lost forever. So, for this very reason, the cleanup stack is used. The cleanup stack acts as a location for storing pointers, which can be deleted in case there is a leave.

The symbian provides two trap harnesses TRAP and TRAPD. Whenever a leave happens, the control goes back till the Trap. Now, in the above pesudo code, when Function3L() leaves, the control goes till the innermost Trap and the cleanupstack unwinds till that point. All the objects that were pushed on the stack the stack since the beginning of the Trap are poped and destroyed. So, in this case, myObj is popped from the stack and then destroyed.

Wednesday, October 8, 2008

New blog on symbian

Though there are a lot of technical site available on symbian, I decided to start another one. This is just to increase my knowledge of symbian.