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