|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Contains IPC Test 04 |
|
15 // |
|
16 // |
|
17 |
|
18 // EPOC includes |
|
19 #include <e32base.h> |
|
20 #include <ss_std.h> |
|
21 |
|
22 #include "Test04IPCMultithreadedDataTransfer.h" |
|
23 |
|
24 const TInt KInactivityTimeout = 1000000; // Use 1 second so that there can be many timeouts, but we'll beat the TEF's 100 second timeout |
|
25 |
|
26 const TDesC& CTest04IPCMultithreadedDataTransfer::GetTestName() |
|
27 { |
|
28 _LIT(ret,"IPCTest04"); |
|
29 return ret; |
|
30 } |
|
31 // constructor |
|
32 CTest04IPCMultithreadedDataTransfer::CTest04IPCMultithreadedDataTransfer() |
|
33 { |
|
34 iThreadStackSize = 1024; |
|
35 iSemName = _L("IPC sem"); |
|
36 iTestString = _L8("This is IPC test string"); |
|
37 } |
|
38 |
|
39 // destructor |
|
40 CTest04IPCMultithreadedDataTransfer::~CTest04IPCMultithreadedDataTransfer() |
|
41 { |
|
42 } |
|
43 |
|
44 // |
|
45 TInt CTest04IPCMultithreadedDataTransfer::fTransmitterThread(TAny* aInput) |
|
46 { |
|
47 TInt err; |
|
48 RSocketServ aSockServer; |
|
49 RSocket aClientSock; |
|
50 RSemaphore aSem; |
|
51 TSockAddr aAddr; |
|
52 CTest04IPCMultithreadedDataTransfer* pTestObject = |
|
53 (CTest04IPCMultithreadedDataTransfer*)aInput; |
|
54 |
|
55 //-------------------substep 01----------------------------- |
|
56 // Connect to Socket server, open semaphore and create client socket end point |
|
57 pTestObject->iTransmitThreadResult.Format(_L(" Step1...")); |
|
58 pTestObject->iTransmitThreadResult.Append(_L("Connect to Sock Server...")); |
|
59 if ( (err = OptimalConnect(aSockServer)) != KErrNone ) |
|
60 return err; |
|
61 pTestObject->iTransmitThreadResult.Append(_L("Open Semaphore...")); |
|
62 if ((err = aSem.OpenGlobal(pTestObject->iSemName)) != KErrNone) |
|
63 { |
|
64 aSockServer.Close(); |
|
65 return err; |
|
66 } |
|
67 pTestObject->iTransmitThreadResult.Append(_L("Open Client Socket...")); |
|
68 if ( (err=aClientSock.Open(aSockServer,pTestObject->iProt)) != KErrNone) |
|
69 { |
|
70 aSockServer.Close(); |
|
71 aSem.Close(); |
|
72 return err; |
|
73 } |
|
74 |
|
75 //-------------------substep 02----------------------------- |
|
76 // Wait the signal from receiver thread to continue |
|
77 pTestObject->iTransmitThreadResult.Append(_L("Wait...")); |
|
78 aSem.Wait(); |
|
79 |
|
80 //-------------------substep 03----------------------------- |
|
81 // Connect to the server socket and send test message |
|
82 aAddr.SetPort(1); |
|
83 pTestObject->iTransmitThreadResult.Append(_L("Connect...")); |
|
84 aClientSock.Connect(aAddr,pTestObject->iTrStatus); |
|
85 User::WaitForRequest(pTestObject->iTrStatus); |
|
86 if (pTestObject->iTrStatus != KErrNone) |
|
87 { |
|
88 aClientSock.Close(); |
|
89 aSockServer.Close(); |
|
90 aSem.Close(); |
|
91 return pTestObject->iTrStatus.Int(); |
|
92 } |
|
93 |
|
94 pTestObject->iTransmitThreadResult.Append(_L("Write...")); |
|
95 aClientSock.Write(pTestObject->iTestString,pTestObject->iTrStatus); |
|
96 User::WaitForRequest(pTestObject->iTrStatus); |
|
97 if(pTestObject->iTrStatus!=KErrNone) |
|
98 { |
|
99 aClientSock.Close(); |
|
100 aSockServer.Close(); |
|
101 aSem.Close(); |
|
102 return pTestObject->iTrStatus.Int(); |
|
103 } |
|
104 |
|
105 //-------------------substep 04----------------------------- |
|
106 // Wait the signal from receiver thread to continue |
|
107 pTestObject->iTransmitThreadResult.Append(_L("Wait...")); |
|
108 aSem.Wait(); |
|
109 |
|
110 //-------------------substep 05----------------------------- |
|
111 // Close the socket. Close connection to Socket server. |
|
112 pTestObject->iTransmitThreadResult.Append(_L("Exit OK...")); |
|
113 aClientSock.Close(); |
|
114 aSockServer.Close(); |
|
115 aSem.Close(); |
|
116 return KErrNone; |
|
117 } |
|
118 |
|
119 // |
|
120 TInt CTest04IPCMultithreadedDataTransfer::fReceiverThread(TAny* aInput) |
|
121 { |
|
122 TInt err; |
|
123 RSocketServ aSockServer; |
|
124 RSemaphore aSem; |
|
125 RSocket aNewConn, aServerSock; |
|
126 CTest04IPCMultithreadedDataTransfer* pTestObject = |
|
127 (CTest04IPCMultithreadedDataTransfer*)aInput; |
|
128 |
|
129 //-------------------substep 01----------------------------- |
|
130 // Connect to Socket setver, open semaphore and create server socket end point |
|
131 pTestObject->iReceiveThreadResult.Format(_L(" Step1...")); |
|
132 |
|
133 pTestObject->iReceiveThreadResult.Append(_L("Connect to SockServer...")); |
|
134 if ( (err = OptimalConnect(aSockServer)) != KErrNone ) |
|
135 return err; |
|
136 pTestObject->iReceiveThreadResult.Append(_L("Open semaphore...")); |
|
137 if ((err = aSem.OpenGlobal(pTestObject->iSemName)) != KErrNone) |
|
138 { |
|
139 aSockServer.Close(); |
|
140 return err; |
|
141 } |
|
142 pTestObject->iReceiveThreadResult.Append(_L("Open Server socket...")); |
|
143 if ( (err=aServerSock.Open(aSockServer,pTestObject->iProt)) != KErrNone) |
|
144 { |
|
145 aSockServer.Close(); |
|
146 aSem.Close(); |
|
147 return err; |
|
148 } |
|
149 if ( (err=aServerSock.SetLocalPort(1)) != KErrNone) |
|
150 { |
|
151 aServerSock.Close(); |
|
152 aSockServer.Close(); |
|
153 aSem.Close(); |
|
154 return err; |
|
155 } |
|
156 if ( (err=aServerSock.Listen(1)) != KErrNone) |
|
157 { |
|
158 aServerSock.Close(); |
|
159 aSockServer.Close(); |
|
160 aSem.Close(); |
|
161 return err; |
|
162 } |
|
163 pTestObject->iReceiveThreadResult.Append(_L("Open Blank Socket...")); |
|
164 if ( (err=aNewConn.Open(aSockServer)) != KErrNone) |
|
165 { |
|
166 aServerSock.Close(); |
|
167 aSockServer.Close(); |
|
168 aSem.Close(); |
|
169 return err; |
|
170 } |
|
171 |
|
172 //-------------------substep 02----------------------------- |
|
173 // Send the signal to transmit thread to continue |
|
174 pTestObject->iReceiveThreadResult.Append(_L("Signal...")); |
|
175 aSem.Signal(); |
|
176 |
|
177 //-------------------substep 03----------------------------- |
|
178 // Read the message from the socket |
|
179 pTestObject->iReceiveThreadResult.Append(_L("Accept...")); |
|
180 aServerSock.Accept(aNewConn,pTestObject->iRecStatus); |
|
181 User::WaitForRequest(pTestObject->iRecStatus); |
|
182 if (pTestObject->iRecStatus != KErrNone) |
|
183 { |
|
184 aNewConn.Close(); |
|
185 aServerSock.Close(); |
|
186 aSockServer.Close(); |
|
187 aSem.Close(); |
|
188 return pTestObject->iRecStatus.Int(); |
|
189 } |
|
190 int aLen = pTestObject->iTestString.Length(); |
|
191 TAny* aPtr = User::Alloc(aLen); |
|
192 if (aPtr == NULL) |
|
193 { |
|
194 aNewConn.Close(); |
|
195 aServerSock.Close(); |
|
196 aSockServer.Close(); |
|
197 aSem.Close(); |
|
198 return KErrNoMemory; |
|
199 } |
|
200 TPtr8 aIn((TUint8*)aPtr,aLen,aLen); |
|
201 aIn.SetLength(aLen); |
|
202 |
|
203 pTestObject->iReceiveThreadResult.Append(_L("Read...")); |
|
204 aNewConn.Read(aIn,pTestObject->iRecStatus); |
|
205 User::WaitForRequest(pTestObject->iRecStatus); |
|
206 if (pTestObject->iRecStatus != KErrNone) |
|
207 { |
|
208 User::Free(aPtr); |
|
209 aNewConn.Close(); |
|
210 aServerSock.Close(); |
|
211 aSockServer.Close(); |
|
212 aSem.Close(); |
|
213 return pTestObject->iRecStatus.Int(); |
|
214 } |
|
215 aNewConn.Close(); |
|
216 |
|
217 //-------------------substep 04----------------------------- |
|
218 // Send the signal to transmit thread to continue |
|
219 pTestObject->iReceiveThreadResult.Append(_L("Signal...")); |
|
220 aSem.Signal(); |
|
221 |
|
222 //-------------------substep 05----------------------------- |
|
223 // Check the data received against test message that is sent |
|
224 pTestObject->iReceiveThreadResult.Append(_L("Compare data...")); |
|
225 if (aIn.Compare(pTestObject->iTestString)) |
|
226 { |
|
227 User::Free(aPtr); |
|
228 aServerSock.Close(); |
|
229 aSockServer.Close(); |
|
230 aSem.Close(); |
|
231 return EFail; |
|
232 } |
|
233 |
|
234 //-------------------substep 02----------------------------- |
|
235 // Close the server socket. Close connection to Socket server. Free memory |
|
236 pTestObject->iReceiveThreadResult.Append(_L("Exit OK...")); |
|
237 aServerSock.Close(); |
|
238 aSockServer.Close(); |
|
239 User::Free(aPtr); |
|
240 aSem.Close(); |
|
241 return KErrNone; |
|
242 } |
|
243 |
|
244 |
|
245 // |
|
246 TInt CTest04IPCMultithreadedDataTransfer::fInactivityTimeoutThread(TAny* aSelf) |
|
247 { |
|
248 CTest04IPCMultithreadedDataTransfer* pTestObject = REINTERPRET_CAST(CTest04IPCMultithreadedDataTransfer*,aSelf); |
|
249 |
|
250 User::After(KInactivityTimeout); |
|
251 if (pTestObject->iRecStatus == KRequestPending) |
|
252 { |
|
253 pTestObject->iReceiveThreadResult.Append(_L("TIMEOUT...")); |
|
254 TRequestStatus* reqStat = &(pTestObject->iRecStatus); |
|
255 pTestObject->iThreadRec.RequestComplete(reqStat,KErrTimedOut); |
|
256 } |
|
257 |
|
258 if (pTestObject->iTrStatus == KRequestPending) |
|
259 { |
|
260 pTestObject->iTransmitThreadResult.Append(_L("TIMEOUT...")); |
|
261 TRequestStatus* reqStat = &(pTestObject->iTrStatus); |
|
262 pTestObject->iThreadTr.RequestComplete(reqStat,KErrTimedOut); |
|
263 } |
|
264 |
|
265 return KErrNone; |
|
266 } |
|
267 |
|
268 |
|
269 // |
|
270 enum TVerdict CTest04IPCMultithreadedDataTransfer::InternalDoTestStepL(void) |
|
271 { |
|
272 |
|
273 //-------------------substep 01----------------------------- |
|
274 _LIT(aLog01,"01 Create threads and semaphore:"); Logger().Write(aLog01); |
|
275 RThread aTimeoutThread; |
|
276 TRequestStatus aStatusRec,aStatusTr; |
|
277 |
|
278 TInt err=iThreadRec.Create(_L("testThreadRec"), |
|
279 fReceiverThread, |
|
280 KDefaultStackSize, |
|
281 KDefaultHeapSize, |
|
282 KDefaultHeapSize, |
|
283 (TAny*)this, |
|
284 EOwnerProcess); |
|
285 |
|
286 if (err != KErrNone) |
|
287 { |
|
288 _LIT(aLog,"Error:Could not create receiving thread. err = %d"); |
|
289 Logger().WriteFormat(aLog, err); |
|
290 return EFail; |
|
291 } |
|
292 |
|
293 err=iThreadTr.Create(_L("testThreadTr"), |
|
294 fTransmitterThread, |
|
295 KDefaultStackSize, |
|
296 KDefaultHeapSize, |
|
297 KDefaultHeapSize, |
|
298 (TAny*)this, |
|
299 EOwnerProcess); |
|
300 |
|
301 if (err != KErrNone) |
|
302 { |
|
303 _LIT(aLog,"Error:Could not create transmitting thread. err = %d"); |
|
304 Logger().WriteFormat(aLog, err); |
|
305 return EFail; |
|
306 } |
|
307 |
|
308 RSemaphore aSem; |
|
309 err = aSem.CreateGlobal(iSemName,0); |
|
310 if (err != KErrNone) |
|
311 { |
|
312 _LIT(aLog,"Error:Could not create semaphore. err = %d"); |
|
313 Logger().WriteFormat(aLog, err); |
|
314 return EFail; |
|
315 } |
|
316 |
|
317 err=aTimeoutThread.Create(_L("testThreadTimeout"), |
|
318 fInactivityTimeoutThread, |
|
319 KDefaultStackSize, |
|
320 KDefaultHeapSize, |
|
321 KDefaultHeapSize, |
|
322 (TAny*)this, |
|
323 EOwnerProcess); |
|
324 |
|
325 if (err != KErrNone) |
|
326 { |
|
327 _LIT(aLog,"Error:Could not create timeout thread. err = %d"); |
|
328 Logger().WriteFormat(aLog, err); |
|
329 return EFail; |
|
330 } |
|
331 |
|
332 //-------------------substep 02----------------------------- |
|
333 _LIT(aLog02,"02 Resume threads and wait them to end:"); Logger().Write(aLog02); |
|
334 iThreadRec.Logon(aStatusRec); |
|
335 iThreadRec.Resume(); |
|
336 iThreadTr.Logon(aStatusTr); |
|
337 iThreadTr.Resume(); |
|
338 User::WaitForRequest(aStatusRec,aStatusTr); |
|
339 if (aStatusRec!=KErrNone && aStatusTr==KRequestPending) |
|
340 { |
|
341 /* If the receiver completes prematurely with an error before the |
|
342 * transmitter, the transmitter will hang waiting to be signalled. |
|
343 * So we send 2 signals to ensure that the transmitter completes. */ |
|
344 aSem.Signal(); |
|
345 aSem.Signal(); |
|
346 } |
|
347 /* kick off a timeout thread that ensures that the test doesn't hang. |
|
348 * (This can happen when an OOM occurs at an unfavourable time.) */ |
|
349 aTimeoutThread.Resume(); |
|
350 User::WaitForRequest(aStatusRec,aStatusTr); |
|
351 // We've completed, so the timeout thread won't be needed any longer |
|
352 aTimeoutThread.Kill(KErrNone); |
|
353 aTimeoutThread.Close(); |
|
354 aSem.Close(); |
|
355 iThreadRec.Close(); |
|
356 iThreadTr.Close(); |
|
357 |
|
358 TVerdict verdict = EPass; |
|
359 Logger().Write(_L(" Info:Receiving thread log:")); |
|
360 Logger().Write(iReceiveThreadResult); |
|
361 err = aStatusRec.Int(); |
|
362 if (KErrNone != err) |
|
363 { |
|
364 _LIT(aLog,"Error:Receiving thread has returned error. err = %d"); |
|
365 Logger().WriteFormat(aLog, err); |
|
366 verdict = EFail; |
|
367 } |
|
368 |
|
369 Logger().Write(_L(" Info:Transmitting thread log:")); |
|
370 Logger().Write(iTransmitThreadResult); |
|
371 err = aStatusTr.Int(); |
|
372 if (KErrNone != err) |
|
373 { |
|
374 _LIT(aLog,"Error:Transmitting thread has returned error. err = %d"); |
|
375 Logger().WriteFormat(aLog, err); |
|
376 verdict = EFail; |
|
377 } |
|
378 return verdict; |
|
379 } |
|
380 |