|
1 // Copyright (c) 2006-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 // Name : tlibcbackendblocks.cpp |
|
15 // |
|
16 |
|
17 |
|
18 |
|
19 /* |
|
20 * ============================================================================== |
|
21 * Name : tlibcbackendblocks.cpp |
|
22 * Part of : backend / testlibcbackend |
|
23 * |
|
24 * Description : ?Description |
|
25 * Version: 0.5 |
|
26 * |
|
27 * Copyright (C) 2002 Nokia Corporation. |
|
28 * This material, including documentation and any related |
|
29 * computer programs, is protected by copyright controlled by |
|
30 * Nokia Corporation. All rights are reserved. Copying, |
|
31 * including reproducing, storing, adapting or translating, any |
|
32 * or all of this material requires the prior written consent of |
|
33 * Nokia Corporation. This material also contains confidential |
|
34 * information which may not be disclosed to others without the |
|
35 * prior written consent of Nokia Corporation. |
|
36 * |
|
37 * ============================================================================ |
|
38 */ |
|
39 |
|
40 // INCLUDE FILES |
|
41 #include <e32svr.h> |
|
42 #include "tlibcbackend.h" |
|
43 #include <pthread.h> |
|
44 #include <errno.h> |
|
45 #include <unistd.h> |
|
46 #include <fcntl.h> |
|
47 #include <sys/stat.h> |
|
48 #include <sys/types.h> |
|
49 #include <sys/socket.h> |
|
50 #include <sys/ioctl.h> |
|
51 #include <stdapis/netinet/in.h> |
|
52 #include <stdapis/arpa/inet.h> |
|
53 #include <netdb.h> |
|
54 |
|
55 #include <stdio.h> |
|
56 #include <semaphore.h> |
|
57 |
|
58 |
|
59 #define IN_SET_LOOPBACK_ADDR(a) \ |
|
60 { (a)->sin_addr.s_addr = 0x0100007F; (a)->sin_family = AF_INET; } |
|
61 |
|
62 |
|
63 const char* const KThreadOneLogFile = "C:\\ThreadOneLog.txt"; |
|
64 const char* const KThreadTwoLogFile = "C:\\ThreadTwoLog.txt"; |
|
65 |
|
66 const TInt KPortNum = 2222; |
|
67 const TInt KCount = 10; |
|
68 const char KFileName[50] = "C:\\File.txt"; |
|
69 |
|
70 #ifdef __ARMCC__ |
|
71 const char* const KReadProcess = "C:\\Sys\\Bin\\TPopenReadChild.exe"; |
|
72 const char* const KWriteProcess = "C:\\Sys\\Bin\\TPopenWriteChild.exe"; |
|
73 #endif //__ARMCC__ |
|
74 |
|
75 const short MODE_READ = 1; |
|
76 const short MODE_WRITE = 2; |
|
77 const short MODE_READWRITE = 4; |
|
78 |
|
79 void* SocketReadThreadEntryPoint( void* aParam ); |
|
80 void* SocketWriteThreadEntryPoint( void* aParam ); |
|
81 void* FileReadThreadEntryPoint( void* aParam ); |
|
82 void* FileWriteThreadEntryPoint( void* aParam ); |
|
83 void* ServerLockThreadEntryPoint( void* aParam ); |
|
84 |
|
85 struct TThreadParam |
|
86 { |
|
87 TInt iDataCount; |
|
88 sem_t iSemaphore; |
|
89 FILE* iFp; |
|
90 }; |
|
91 |
|
92 |
|
93 //Utility functions |
|
94 void CTestLibcbackend::ReadIntParam(TInt &aInt) |
|
95 { |
|
96 _LIT( Kparam, "Param%d" ); |
|
97 TBuf<8> pNameBuf; |
|
98 TPtrC string; |
|
99 pNameBuf.Format(Kparam,++iParamCnt); |
|
100 TBool res = GetIntFromConfig(ConfigSection(), pNameBuf, aInt); |
|
101 if(!res) |
|
102 { |
|
103 _LIT(Kerr , "Unable to retrieve integer parameter") ; |
|
104 INFO_PRINTF1(Kerr); |
|
105 } |
|
106 return; |
|
107 } |
|
108 |
|
109 // ============================ MEMBER FUNCTIONS =============================== |
|
110 // ----------------------------------------------------------------------------- |
|
111 // CTestLibcbackend::SocketIOTest |
|
112 // Testing new backend with a scenario like this: |
|
113 // create two thread which sends/receive data to each other |
|
114 // This test case can be invoked with below syntax: |
|
115 // SocketIO <NoOfMsgs:Integer> |
|
116 // Example: SocketIO 100 |
|
117 // ----------------------------------------------------------------------------- |
|
118 // |
|
119 TInt CTestLibcbackend::SocketIOTest() |
|
120 { |
|
121 TInt dataCount = KCount; |
|
122 ReadIntParam( dataCount ); |
|
123 int retVal = 0; |
|
124 pthread_t threadID1 = 0; |
|
125 pthread_t threadID2 = 0; |
|
126 pthread_attr_t threadAttr; |
|
127 pthread_attr_init( &threadAttr ); |
|
128 pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE ); |
|
129 |
|
130 //Create a Read thread now |
|
131 retVal = pthread_create( &threadID1, &threadAttr, SocketReadThreadEntryPoint, |
|
132 (void*)dataCount ); |
|
133 INFO_PRINTF2(_L("ReadThread Creation returned with %d"), retVal); |
|
134 if( retVal == 0) |
|
135 { |
|
136 //Create Write thread |
|
137 retVal = pthread_create( &threadID2, &threadAttr, |
|
138 SocketWriteThreadEntryPoint, (void*)dataCount ); |
|
139 INFO_PRINTF2(_L("WriteThread Creation returned with %d"), retVal); |
|
140 //If its joinable thread and waitFlag id set |
|
141 if( KErrNone == retVal ) |
|
142 { |
|
143 TInt exitReason = 0; |
|
144 retVal = pthread_join(threadID1, (void**)&exitReason ); |
|
145 INFO_PRINTF3(_L("ReadThread join returned with %d and the exit reason is %d"), retVal, exitReason ); |
|
146 retVal = pthread_join(threadID2, (void**)&exitReason ); |
|
147 if (retVal != 0) |
|
148 { |
|
149 //If the thread fails , kill the first thread |
|
150 pthread_join(threadID1, NULL); |
|
151 return KErrGeneral; |
|
152 } |
|
153 else |
|
154 { |
|
155 INFO_PRINTF3(_L("WriteThread join returned with %d and the exit reason is %d"), retVal, exitReason ); |
|
156 } |
|
157 } |
|
158 } |
|
159 return retVal; |
|
160 } |
|
161 |
|
162 // ----------------------------------------------------------------------------- |
|
163 // CTestLibcbackend::FileIOTest |
|
164 // Testing new backend with a scenario like this: |
|
165 // create two thread which read/write data to same file |
|
166 // This test case can be invoked with below syntax: |
|
167 // FileIO <NoOfFileIO:Integer> |
|
168 // Example: FileIO 100 |
|
169 // ----------------------------------------------------------------------------- |
|
170 // |
|
171 TInt CTestLibcbackend::FileIOTest() |
|
172 { |
|
173 int retVal = 0; |
|
174 TInt dataCount = KCount; |
|
175 ReadIntParam( dataCount ); |
|
176 TThreadParam threadParam; |
|
177 threadParam.iDataCount = dataCount; |
|
178 |
|
179 if( sem_init( &threadParam.iSemaphore, 0, 0 ) != KErrNone ) |
|
180 { |
|
181 INFO_PRINTF2(_L("Semaphore creation Failed with %d"), errno ); |
|
182 return KErrGeneral; |
|
183 } |
|
184 |
|
185 FILE* fp = fopen( KFileName, "w+"); |
|
186 if (fp == NULL) |
|
187 { |
|
188 INFO_PRINTF1(_L("File open error!")); |
|
189 return KErrGeneral; |
|
190 } |
|
191 threadParam.iFp = fp; |
|
192 if(!fp) |
|
193 { |
|
194 return KErrGeneral; |
|
195 } |
|
196 |
|
197 pthread_t threadID1 = 0; |
|
198 pthread_t threadID2 = 0; |
|
199 pthread_attr_t threadAttr; |
|
200 pthread_attr_init( &threadAttr ); |
|
201 pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE ); |
|
202 |
|
203 //Create a Read thread now |
|
204 retVal = pthread_create( &threadID1, &threadAttr, FileReadThreadEntryPoint, |
|
205 (void*)&threadParam ); |
|
206 INFO_PRINTF2(_L("ReadThread Creation returned with %d"), retVal); |
|
207 if( retVal == 0) |
|
208 { |
|
209 //Create Write thread |
|
210 retVal = pthread_create( &threadID2, &threadAttr, |
|
211 FileWriteThreadEntryPoint, (void*)&threadParam ); |
|
212 INFO_PRINTF2(_L("WriteThread Creation returned with %d"), retVal); |
|
213 //If its joinable thread and waitFlag id set |
|
214 if( KErrNone == retVal ) |
|
215 { |
|
216 TInt exitReason = 0; |
|
217 retVal = pthread_join(threadID1, (void**)&exitReason ); |
|
218 INFO_PRINTF3(_L("ReadThread join returned with %d and the exit reason is %d"), retVal, exitReason ); |
|
219 retVal = pthread_join(threadID2, (void**)&exitReason ); |
|
220 if (retVal != 0) |
|
221 { |
|
222 //If the thread fails , kill the first thread |
|
223 pthread_join(threadID1, NULL); |
|
224 return KErrGeneral; |
|
225 } |
|
226 else |
|
227 { |
|
228 INFO_PRINTF3(_L("WriteThread join returned with %d and the exit reason is %d"), retVal, exitReason ); |
|
229 } |
|
230 } |
|
231 } |
|
232 |
|
233 if( sem_destroy( &threadParam.iSemaphore ) != KErrNone ) |
|
234 { |
|
235 INFO_PRINTF2(_L("sem_destroy Failed with %d"), errno ); |
|
236 retVal = KErrGeneral; |
|
237 } |
|
238 |
|
239 fclose(fp); |
|
240 return retVal; |
|
241 } |
|
242 |
|
243 // ----------------------------------------------------------------------------- |
|
244 // CTestLibcbackend::ServerLockTest |
|
245 // Testing new backend's Server Session locks with multiple threads |
|
246 // This test case can be invoked with below syntax: |
|
247 // ServerLock <NoOfThreads:Integer> |
|
248 // Example: ServerLock 10 |
|
249 // ----------------------------------------------------------------------------- |
|
250 // |
|
251 TInt CTestLibcbackend::ServerLockTest() |
|
252 { |
|
253 TInt retVal = KErrNone; |
|
254 TInt threadCount = KCount; |
|
255 ReadIntParam( threadCount ); |
|
256 pthread_t threadID = 0; |
|
257 pthread_attr_t threadAttr; |
|
258 pthread_attr_init( &threadAttr ); |
|
259 pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE ); |
|
260 |
|
261 for(int index = 0; index<threadCount && KErrNone == retVal; index++) |
|
262 { |
|
263 //Create a Read thread now |
|
264 retVal = pthread_create( &threadID, &threadAttr, ServerLockThreadEntryPoint, |
|
265 (void*)threadCount ); |
|
266 INFO_PRINTF2(_L("ServerLockThreadEntryPoint Creation returned with %d"), retVal); |
|
267 } |
|
268 TInt exitReason = 0; |
|
269 retVal = pthread_join(threadID, (void**)&exitReason ); |
|
270 INFO_PRINTF3(_L("ServerLockThreadEntryPoint join returned with %d and the exit reason is %d"), retVal, exitReason ); |
|
271 return retVal; |
|
272 } |
|
273 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // CTestLibcbackend::ServerLockTest |
|
276 // Testing backend implementation of opening a directory |
|
277 // This test case can be invoked with below syntax: |
|
278 // OpenDir <Directory to be opened: String> <Mode:Integer> |
|
279 // Example: OpenDir c:\Logs\NotExisting MODE_WRITE |
|
280 // ----------------------------------------------------------------------------- |
|
281 // |
|
282 TInt CTestLibcbackend::OpenDirTest() |
|
283 { |
|
284 TInt retVal = KErrNone; |
|
285 TInt mode = MODE_READ; |
|
286 |
|
287 //Read Directory Name and mode from CFG file |
|
288 TPtrC dirName; |
|
289 _LIT( KaKey, "Param%d" ); |
|
290 TBuf<8> pNameBuf; |
|
291 pNameBuf.Format(KaKey,++iParamCnt); |
|
292 TBool res = GetStringFromConfig(ConfigSection(), pNameBuf, dirName); |
|
293 if(!res) |
|
294 { |
|
295 _LIT(Kerr , "Unable to retrieve string parameter") ; |
|
296 INFO_PRINTF1(Kerr); |
|
297 } |
|
298 ReadIntParam( mode ); |
|
299 switch( mode ) |
|
300 { |
|
301 case MODE_WRITE: |
|
302 { |
|
303 mode = O_WRONLY; |
|
304 break; |
|
305 } |
|
306 case MODE_READWRITE: |
|
307 { |
|
308 mode = O_RDWR; |
|
309 break; |
|
310 } |
|
311 default: |
|
312 case MODE_READ: |
|
313 { |
|
314 mode = O_RDONLY; |
|
315 } |
|
316 } |
|
317 |
|
318 TBuf8<KMaxFileName> tempDir; |
|
319 TChar endChar('\0'); |
|
320 tempDir.Copy(dirName); |
|
321 tempDir.Append(endChar); |
|
322 char* dir = (char*)tempDir.Ptr(); |
|
323 |
|
324 char* file = "c:\\dircontents.txt"; |
|
325 int fd = open(dir, mode); |
|
326 if( fd > 0 ) |
|
327 { |
|
328 char buff[200]; |
|
329 int retVal = read(fd, buff, 200); |
|
330 if( retVal > 0 ) |
|
331 { |
|
332 FILE* fp = fopen(file, "w"); |
|
333 if( fp ) |
|
334 { |
|
335 for(int i=0; i<retVal; i++) |
|
336 fprintf(fp, "%c", buff[i]); |
|
337 fclose(fp); |
|
338 } |
|
339 retVal = 0; |
|
340 } |
|
341 close(fd); |
|
342 } |
|
343 //It should fail with EISDIR |
|
344 else |
|
345 { |
|
346 if( errno != EISDIR ) |
|
347 { |
|
348 retVal = fd; |
|
349 } |
|
350 } |
|
351 |
|
352 return retVal; |
|
353 } |
|
354 |
|
355 // ----------------------------------------------------------------------------- |
|
356 // CTestLibcbackend::ServerLockTest |
|
357 // Testing backend implementation of popen API |
|
358 // This test case can be invoked with below syntax: |
|
359 // PopenPipe <Mode:Integer> |
|
360 // Example: PopenPipe MODE_WRITE |
|
361 // ----------------------------------------------------------------------------- |
|
362 // |
|
363 TInt CTestLibcbackend::PopenPipeTest() |
|
364 { |
|
365 TInt retVal = KErrNone; |
|
366 TInt mode = MODE_READ; |
|
367 char pipeMode = 'r'; |
|
368 const char* command = NULL; |
|
369 ReadIntParam( mode ); |
|
370 |
|
371 //popen works only on device because of Symbian Emulator limitation |
|
372 #ifdef __ARMCC__ |
|
373 if ( mode == MODE_WRITE ) |
|
374 { |
|
375 pipeMode = 'w'; |
|
376 command = KWriteProcess; |
|
377 } |
|
378 else |
|
379 { |
|
380 pipeMode = 'r'; |
|
381 command = KReadProcess; |
|
382 } |
|
383 |
|
384 FILE* fp = popen( command, &pipeMode); |
|
385 if( fp ) |
|
386 { |
|
387 if( mode == MODE_WRITE ) |
|
388 { |
|
389 //Child Pipe Should get this string!! |
|
390 fprintf(fp, "PROCESS"); |
|
391 } |
|
392 else |
|
393 { |
|
394 //Child Pipe Should give this string!! |
|
395 char string[50]; |
|
396 int ret = fscanf(fp, "%s", string); |
|
397 } |
|
398 //close the pipe |
|
399 pclose(fp); |
|
400 } |
|
401 //Error case |
|
402 else |
|
403 { |
|
404 int err = errno; |
|
405 retVal = KErrGeneral; |
|
406 } |
|
407 #endif // __ARMCC__ |
|
408 |
|
409 return retVal; |
|
410 } |
|
411 |
|
412 // ----------------------------------------------------------------------------- |
|
413 // SocketReadThreadEntryPoint |
|
414 // Thread Entry Function for Socket read thread |
|
415 // ----------------------------------------------------------------------------- |
|
416 // |
|
417 void* SocketReadThreadEntryPoint( void* aParam ) |
|
418 { |
|
419 FILE* logFile; |
|
420 TInt retVal = KErrNone; |
|
421 TInt count = (TInt) aParam; |
|
422 TInt portNum = KPortNum + count; |
|
423 int serverFd = 0; |
|
424 int newFd = 0; |
|
425 size_t addrSize; |
|
426 struct sockaddr_in servAddr; |
|
427 struct sockaddr_in sockAddr; |
|
428 const char* buff = "Server --> Sending Data Item : "; |
|
429 char sendBuff[50]; |
|
430 char recvBuff[100]; |
|
431 const unsigned int maxRecv = 100; |
|
432 |
|
433 logFile = fopen(KThreadOneLogFile, "w"); |
|
434 |
|
435 if(logFile == NULL) |
|
436 { |
|
437 return (void*) KErrGeneral; |
|
438 } |
|
439 |
|
440 fprintf(logFile, "Server Socket Thread\n"); |
|
441 serverFd = socket(AF_INET, SOCK_STREAM, 0); |
|
442 if( serverFd == -1 ) |
|
443 { |
|
444 fprintf(logFile, "Socket Creation Failed!!\n"); |
|
445 retVal = KErrGeneral; |
|
446 } |
|
447 |
|
448 IN_SET_LOOPBACK_ADDR( &servAddr ); |
|
449 servAddr.sin_port = htons( (TUint16) portNum ); |
|
450 retVal |= bind( serverFd, (struct sockaddr*)&servAddr, sizeof(servAddr) ); |
|
451 if( retVal != 0 ) |
|
452 { |
|
453 fprintf(logFile, "Socket bind Failed!!\n"); |
|
454 close( serverFd ); |
|
455 retVal = KErrGeneral; |
|
456 } |
|
457 |
|
458 retVal |= listen( serverFd, 1 ); |
|
459 if( retVal != 0 ) |
|
460 { |
|
461 fprintf(logFile, "Socket listen Failed!!\n"); |
|
462 close( serverFd ); |
|
463 retVal = KErrGeneral; |
|
464 } |
|
465 |
|
466 addrSize = sizeof( sockAddr ); |
|
467 newFd = accept( serverFd, (struct sockaddr*)&sockAddr, &addrSize); |
|
468 if( newFd == -1 ) |
|
469 { |
|
470 fprintf(logFile, "Socket accept Failed!!\n"); |
|
471 close( serverFd ); |
|
472 retVal = KErrGeneral; |
|
473 } |
|
474 |
|
475 if( KErrNone == retVal ) |
|
476 { |
|
477 //Now Receive and Send some Data |
|
478 for(TInt i=1; i<=count; i++) |
|
479 { |
|
480 TInt ret = recv(newFd, recvBuff, maxRecv, 0); |
|
481 if( ret == -1 ) |
|
482 { |
|
483 fprintf(logFile, "Socket recv Failed!!\n"); |
|
484 close( newFd ); |
|
485 close( serverFd ); |
|
486 retVal = KErrGeneral; |
|
487 break; |
|
488 } |
|
489 fprintf(logFile, "Socket received %s\n", recvBuff); |
|
490 sprintf(sendBuff, "%s %d", buff, i); |
|
491 ret = send(newFd, sendBuff, sizeof(sendBuff), 0); |
|
492 if( ret == -1 ) |
|
493 { |
|
494 fprintf(logFile, "Socket send Failed!!\n"); |
|
495 close( newFd ); |
|
496 close( serverFd ); |
|
497 retVal = KErrGeneral; |
|
498 break; |
|
499 } |
|
500 } |
|
501 } |
|
502 |
|
503 if( KErrNone == retVal ) |
|
504 { |
|
505 close( newFd ); |
|
506 close( serverFd ); |
|
507 } |
|
508 fprintf(logFile, "Server Thread Completed with %d\n", retVal); |
|
509 fclose(logFile); |
|
510 return (void*)retVal; |
|
511 } |
|
512 |
|
513 // ----------------------------------------------------------------------------- |
|
514 // SocketWriteThreadEntryPoint |
|
515 // Thread Entry Function for Socket write thread |
|
516 // ----------------------------------------------------------------------------- |
|
517 // |
|
518 void* SocketWriteThreadEntryPoint( void* aParam ) |
|
519 { |
|
520 FILE* logFile; |
|
521 TInt retVal = KErrNone; |
|
522 TInt count = (TInt) aParam; |
|
523 |
|
524 TInt portNum = KPortNum + count; |
|
525 int clientFd; |
|
526 size_t addrSize; |
|
527 struct sockaddr_in servAddr; |
|
528 const char* buff = "Client --> Sending Data Item : "; |
|
529 char sendBuff[50]; |
|
530 char recvBuff[100]; |
|
531 const unsigned int maxRecv = 100; |
|
532 |
|
533 IN_SET_LOOPBACK_ADDR( &servAddr ); |
|
534 servAddr.sin_port = htons( (unsigned short)portNum ); |
|
535 |
|
536 logFile = fopen(KThreadTwoLogFile, "w"); |
|
537 if(logFile == 0) |
|
538 { |
|
539 return (void*) KErrGeneral; |
|
540 } |
|
541 |
|
542 fprintf(logFile, "Client Socket Thread\n"); |
|
543 |
|
544 clientFd = socket(AF_INET, SOCK_STREAM, 0); |
|
545 if( clientFd == -1 ) |
|
546 { |
|
547 fprintf(logFile, "Socket creation Failed!!\n"); |
|
548 retVal = KErrGeneral; |
|
549 } |
|
550 |
|
551 addrSize = sizeof(servAddr); |
|
552 retVal = connect(clientFd, (struct sockaddr*)&servAddr, addrSize); |
|
553 //This should Pass |
|
554 if( retVal == -1 ) |
|
555 { |
|
556 fprintf(logFile, "Socket connect Failed!!\n"); |
|
557 close(clientFd); |
|
558 retVal = KErrGeneral; |
|
559 } |
|
560 |
|
561 if( KErrNone == retVal ) |
|
562 { |
|
563 //Now Send and Receive some Data |
|
564 for(TInt i=1; i<=count; i++) |
|
565 { |
|
566 sprintf(sendBuff, "%s %d", buff, i); |
|
567 TInt ret = send(clientFd, sendBuff, sizeof(sendBuff), 0); |
|
568 if(ret == -1) |
|
569 { |
|
570 fprintf(logFile, "Socket send Failed!!\n"); |
|
571 close( clientFd ); |
|
572 retVal = KErrGeneral; |
|
573 break; |
|
574 } |
|
575 ret = recv(clientFd, recvBuff, maxRecv, 0); |
|
576 if(ret == -1) |
|
577 { |
|
578 fprintf(logFile, "Socket recv Failed!!\n"); |
|
579 close( clientFd ); |
|
580 retVal = KErrGeneral; |
|
581 break; |
|
582 } |
|
583 fprintf(logFile, "Socket received %s\n", recvBuff); |
|
584 } |
|
585 } |
|
586 |
|
587 if (KErrNone == retVal ) |
|
588 { |
|
589 close( clientFd ); |
|
590 } |
|
591 |
|
592 fprintf(logFile, "Client Thread Completed with %d\n", retVal); |
|
593 fclose(logFile); |
|
594 return (void*)retVal; |
|
595 } |
|
596 |
|
597 // ----------------------------------------------------------------------------- |
|
598 // FileReadThreadEntryPoint |
|
599 // Thread Entry Function for File read thread |
|
600 // ----------------------------------------------------------------------------- |
|
601 // |
|
602 void* FileReadThreadEntryPoint( void* aParam ) |
|
603 { |
|
604 TInt retVal = KErrNone; |
|
605 char string[80]; |
|
606 int count = 0; |
|
607 int index = 0; |
|
608 TThreadParam* pThreadParam = ( TThreadParam* ) aParam; |
|
609 FILE* fp = pThreadParam->iFp; |
|
610 |
|
611 for( ;index < pThreadParam->iDataCount; index++ ) |
|
612 { |
|
613 //Wait for the other thread to write some data to file |
|
614 retVal = sem_wait(&pThreadParam->iSemaphore); |
|
615 if( retVal != 0 ) |
|
616 { |
|
617 retVal = KErrGeneral; |
|
618 break; |
|
619 } |
|
620 fscanf(fp, "%s %d", string, &count); |
|
621 } |
|
622 |
|
623 return (void*)retVal; |
|
624 } |
|
625 |
|
626 // ----------------------------------------------------------------------------- |
|
627 // FileWriteThreadEntryPoint |
|
628 // Thread Entry Function for File write thread |
|
629 // ----------------------------------------------------------------------------- |
|
630 // |
|
631 void* FileWriteThreadEntryPoint( void* aParam ) |
|
632 { |
|
633 TInt retVal = KErrNone; |
|
634 char string[] = "Writing some ASCII Data : "; |
|
635 int index = 0; |
|
636 TThreadParam* pThreadParam = ( TThreadParam* ) aParam; |
|
637 FILE* fp = pThreadParam->iFp; |
|
638 //Open the File in write mode |
|
639 |
|
640 for( ;index < pThreadParam->iDataCount; index++ ) |
|
641 { |
|
642 fprintf(fp, "%s %d", string, index); |
|
643 //Tell the other thread that data is ready for reading |
|
644 retVal = sem_post(&pThreadParam->iSemaphore); |
|
645 if( retVal != 0 ) |
|
646 { |
|
647 retVal = KErrGeneral; |
|
648 break; |
|
649 } |
|
650 } |
|
651 |
|
652 return (void*)retVal; |
|
653 } |
|
654 |
|
655 // ----------------------------------------------------------------------------- |
|
656 // FileWriteThreadEntryPoint |
|
657 // Thread Entry Function for File write thread |
|
658 // ----------------------------------------------------------------------------- |
|
659 // |
|
660 void* ServerLockThreadEntryPoint( void* /*aParam*/ ) |
|
661 { |
|
662 const char* fileName = "c:\\Logs\\TestReport.txt"; |
|
663 TInt retVal = KErrNone; |
|
664 struct stat buf; |
|
665 retVal = stat(fileName, &buf); |
|
666 return (void*)retVal; |
|
667 } |
|
668 |
|
669 // End of File |