00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "server.h"
00018
00019 inline CShutdown::CShutdown()
00020 :CTimer(-1)
00021 {CActiveScheduler::Add(this);}
00022 inline void CShutdown::ConstructL()
00023 {CTimer::ConstructL();}
00024 inline void CShutdown::Start()
00025 {After(KMyShutdownDelay);}
00026
00027 inline CMyServer::CMyServer()
00028 :CServer2(0,ESharableSessions)
00029 {}
00030
00031 inline CMySession::CMySession()
00032 {}
00033 inline CMyServer& CMySession::Server()
00034 {return *static_cast<CMyServer*>(const_cast<CServer2*>(CSession2::Server()));}
00035 inline TBool CMySession::ReceivePending() const
00036 {return !iReceiveMsg.IsNull();}
00037
00038
00040
00041 void CMySession::CreateL()
00042
00043
00044
00045 {
00046 Server().AddSession();
00047 }
00048
00049 CMySession::~CMySession()
00050 {
00051 Server().DropSession();
00052 }
00053
00054 void CMySession::Send(const TDesC& aMessage)
00055
00056
00057
00058
00059 {
00060 if (ReceivePending())
00061 {
00062 TPtrC m(aMessage);
00063 if (iReceiveLen<aMessage.Length())
00064 m.Set(m.Left(iReceiveLen));
00065 TInt r=iReceiveMsg.Write(0,m);
00066 if (r==KErrNone)
00067 iReceiveMsg.Complete(KErrNone);
00068 else
00069 PanicClient(iReceiveMsg,EPanicBadDescriptor);
00070 }
00071 }
00072
00073 void CMySession::ServiceL(const RMessage2& aMessage)
00074
00075
00076
00077
00078
00079 {
00080 switch (aMessage.Function())
00081 {
00082 case ESend:
00083 {
00084 TBuf<KMaxMyMessage> message;
00085 aMessage.ReadL(0,message);
00086 Server().Send(message);
00087 aMessage.Complete(KErrNone);
00088 break;
00089 }
00090 case EReceive:
00091 if (ReceivePending())
00092 PanicClient(aMessage,EPanicAlreadyReceiving);
00093 else
00094 {
00095 iReceiveMsg=aMessage;
00096 iReceiveLen=aMessage.Int1();
00097 }
00098 break;
00099 case ECancelReceive:
00100 if (ReceivePending())
00101 iReceiveMsg.Complete(KErrCancel);
00102 aMessage.Complete(KErrNone);
00103 break;
00104 default:
00105 PanicClient(aMessage,EPanicIllegalFunction);
00106 break;
00107 }
00108 }
00109
00110 void CMySession::ServiceError(const RMessage2& aMessage,TInt aError)
00111
00112
00113
00114
00115
00116 {
00117 if (aError==KErrBadDescriptor)
00118 PanicClient(aMessage,EPanicBadDescriptor);
00119 CSession2::ServiceError(aMessage,aError);
00120 }
00121
00122 void CShutdown::RunL()
00123
00124
00125
00126 {
00127 CActiveScheduler::Stop();
00128 }
00129
00130 CServer2* CMyServer::NewLC()
00131 {
00132 CMyServer* self=new(ELeave) CMyServer;
00133 CleanupStack::PushL(self);
00134 self->ConstructL();
00135 return self;
00136 }
00137
00138 void CMyServer::ConstructL()
00139
00140
00141
00142 {
00143 StartL(KMyServerName);
00144 iShutdown.ConstructL();
00145
00146 iShutdown.Start();
00147 }
00148
00149
00150 CSession2* CMyServer::NewSessionL(const TVersion&,const RMessage2&) const
00151
00152
00153
00154 {
00155 return new(ELeave) CMySession();
00156 }
00157
00158 void CMyServer::AddSession()
00159
00160
00161
00162
00163 {
00164 ++iSessionCount;
00165 iShutdown.Cancel();
00166 }
00167
00168 void CMyServer::DropSession()
00169
00170
00171
00172
00173 {
00174 if (--iSessionCount==0)
00175 iShutdown.Start();
00176 }
00177
00178 void CMyServer::Send(const TDesC& aMessage)
00179
00180
00181
00182 {
00183 iSessionIter.SetToFirst();
00184 CSession2* s;
00185 while ((s=iSessionIter++)!=0)
00186 static_cast<CMySession*>(s)->Send(aMessage);
00187 }
00188
00189 void PanicClient(const RMessagePtr2& aMessage,TMyPanic aPanic)
00190
00191
00192
00193
00194
00195 {
00196 _LIT(KPanic,"MyServer");
00197 aMessage.Panic(KPanic,aPanic);
00198 }
00199
00200 static void RunServerL()
00201
00202
00203
00204
00205 {
00206
00207 User::LeaveIfError(RThread::RenameMe(KMyServerName));
00208
00209
00210 CActiveScheduler* s=new(ELeave) CActiveScheduler;
00211 CleanupStack::PushL(s);
00212 CActiveScheduler::Install(s);
00213
00214
00215 CMyServer::NewLC();
00216
00217
00218 RProcess::Rendezvous(KErrNone);
00219
00220
00221 CActiveScheduler::Start();
00222
00223
00224 CleanupStack::PopAndDestroy(2);
00225 }
00226
00227 TInt E32Main()
00228
00229
00230
00231 {
00232 __UHEAP_MARK;
00233
00234 CTrapCleanup* cleanup=CTrapCleanup::New();
00235 TInt r=KErrNoMemory;
00236 if (cleanup)
00237 {
00238 TRAP(r,RunServerL());
00239 delete cleanup;
00240 }
00241
00242 __UHEAP_MARKEND;
00243 return r;
00244 }