os/ossrv/genericopenlibs/cstdlib/TSTLIB/TCANCEL.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1999-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 // Test code for interrupted IO operations
    15 // 
    16 //
    17 
    18 #include <e32std.h>
    19 #include <e32svr.h>	// for RDebug
    20 #include <stdlib.h>
    21 #include <unistd.h>
    22 #include <stdio.h>
    23 #include <string.h>
    24 #include <sys/fcntl.h>
    25 #include <sys/errno.h>
    26 
    27 #include <sys/ioctl.h>		// for E32IOSELECT
    28 #include <sys/socket.h>
    29 #include <libc/netinet/in.h>
    30 
    31 extern "C" {
    32 #include "CTEST.H"
    33 }
    34 test_Data;
    35 
    36 #include <estlib.h>	// for multi-threading control
    37 
    38 int testFid;
    39 struct sockaddr_in testAddr;
    40 RSemaphore semaphores[2];
    41 
    42 void init_test()
    43 	{
    44 	// We need a datagram socket that we can send to
    45 
    46 	test_Next("Create datagram socket");
    47 	testFid=socket(PF_INET, SOCK_DGRAM, 0);
    48 	test_ok(testFid>=0);
    49 	
    50 	test_Next("Bind to local address");
    51 	IN_SET_LOOPBACK_ADDR(&testAddr);
    52 	testAddr.sin_port=0;
    53 
    54 	size_t len=sizeof(testAddr);
    55 	int err=bind(testFid, (struct sockaddr*)&testAddr, len);
    56 	test_ok(err==0);
    57 
    58 	err=getsockname(testFid, (struct sockaddr*)&testAddr, &len);
    59 	test_ok(err==0);
    60 
    61 	// We now have a datagram socket with a known address
    62 
    63 	test_Next("Create semaphores for test synchronisation");
    64 	for (int i=0; i<2; i++)
    65 		{
    66 		err=semaphores[i].CreateLocal(0);
    67 		test(err==KErrNone);
    68 		}
    69 	}
    70 
    71 /**
    72 Test of the asynchronous ioctl & cancel code
    73 
    74 @SYMTestCaseID          SYSLIB-STDLIB-CT-1044
    75 @SYMTestCaseDesc	    Tests for the asynchronous ioctl & cancel code
    76 @SYMTestPriority 	    High
    77 @SYMTestActions  	    Tests that E32IOSELECT ioctl is working
    78 						Tests for asynchronous IOCTL.
    79 						Setup asynchronous IOCTL which won't complete, then cancel.Check for cancel status
    80 						Cancel a completed asynchronous IOCTL,and check for no error
    81 @SYMTestExpectedResults Test must not fail
    82 @SYMREQ                 REQ0000
    83 */		
    84 void test_ioctl()
    85 	{
    86 	// confirm that the E32IOSELECT ioctl is working
    87 	test_Next("Check synchronous IOCTL");
    88 	int mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
    89 	int err=ioctl(testFid,E32IOSELECT,&mask);
    90 	test_ok(err==0);
    91 	test(mask==E32SELECT_WRITE);
    92 
    93 	test_Next("Check asynchronous IOCTL");
    94 	TRequestStatus status;
    95 	mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
    96 	err=ioctl(testFid,E32IOSELECT,&mask,status);
    97 	test_ok(err==0);
    98 	User::WaitForRequest(status);
    99 	test(status.Int()==KErrNone);
   100 	err=ioctl_complete(testFid,E32IOSELECT,&mask,status);
   101 	test_ok(err==0);
   102 	test(mask==E32SELECT_WRITE);
   103 
   104 	test_Next("Setup asynchronous IOCTL which won't complete, then cancel");
   105 	mask=E32SELECT_READ;
   106 	err=ioctl(testFid,E32IOSELECT,&mask,status);
   107 	test_ok(err==0);
   108 	test(status.Int()==KRequestPending);	// i.e. waiting for input to arrive
   109 
   110 	// test_Next("Cancel the pending IOCTL");
   111 	// Sadly this will do write() which will get a KErrInUse and then panic...
   112 	err=ioctl_cancel(testFid);
   113 	test_ok(err==0);
   114 	User::WaitForRequest(status);
   115 	test_Next("Check that ioctl_cancel worked");
   116 	test(status.Int()==KErrCancel);			// i.e. it was cancelled
   117 
   118 	test_Next("Cancel a completed asynchronous IOCTL");
   119 	mask=E32SELECT_WRITE;
   120 	err=ioctl(testFid,E32IOSELECT,&mask,status);
   121 	test_ok(err==0);
   122 	
   123 	while (status.Int() == KRequestPending)
   124 		User::After(5000);
   125 
   126 	test(status.Int()!=KRequestPending);	// i.e. select has completed
   127 
   128 	// test_Next("Cancel the pending IOCTL");
   129 	// Sadly this will do write() which will get a KErrInUse and then panic...
   130 	err=ioctl_cancel(testFid);
   131 	test_ok(err==0);
   132 	User::WaitForRequest(status);
   133 	test(status.Int()==KErrNone);			// i.e. it was cancelled
   134 
   135 	}
   136 
   137 // Thread functions which will block accessing the socket
   138 
   139 TInt ioctl_block(TAny* aSemIndex)
   140 	{
   141 	semaphores[(TInt)aSemIndex].Wait();		// block until the test is ready
   142 
   143 	int mask=E32SELECT_READ;
   144 	int err=ioctl(testFid,E32IOSELECT,&mask);
   145 	test_ok(err==0);
   146 	test(mask==E32SELECT_READ);
   147 	return 1;
   148 	}
   149 
   150 TInt recv_block(TAny* aSemIndex)
   151 	{
   152 	semaphores[(TInt)aSemIndex].Wait();		// block until the test is ready
   153 
   154 	char buf[256];
   155 	// Problem in recvfrom: int err=recvfrom(testFid,buf,MSG_PEEK,sizeof(buf),0,0);
   156 	struct sockaddr_in junk;
   157 	size_t junklen=sizeof(junk);
   158 	// Problem in esock/tcpip: int err=recvfrom(testFid,buf,sizeof(buf),MSG_PEEK,(struct sockaddr*)&junk,&junklen);
   159 	int err=recvfrom(testFid,buf,sizeof(buf),0,(struct sockaddr*)&junk,&junklen);
   160 	// Problem in recfrom: test_ok(err>0);
   161 	test_ok(err>=0);
   162 	return 1;
   163 	}
   164 
   165 void kill_and_check(RThread& aVictim, TRequestStatus& aVictimStatus, TRequestStatus& aSurvivorStatus)
   166 	{
   167 	test(aVictimStatus.Int()==KRequestPending);
   168 	test(aSurvivorStatus.Int()==KRequestPending);
   169 	aVictim.Kill(666);
   170 	char* KDatagram="Mine is the last voice you will ever hear";
   171 	int length=strlen(KDatagram)+1;
   172 	
   173 	test_Next("Send datagram");
   174 	int err=sendto(testFid,KDatagram, length,0,(struct sockaddr*)&testAddr,sizeof(testAddr));
   175 	test_ok(err==length);
   176 	User::After(1);
   177 
   178 	test_Next("Check the victim status");
   179 	User::WaitForRequest(aVictimStatus);
   180 	test(aVictimStatus.Int()==666);
   181 
   182 	test_Next("Check the survivor status");
   183 	User::WaitForRequest(aSurvivorStatus);
   184 	test(aSurvivorStatus.Int()==1);
   185 
   186 	// Check to see if the datagram has been swallowed
   187 	int mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
   188 	err=ioctl(testFid,E32IOSELECT,&mask);
   189 	test_ok(err==0);
   190 	if ((mask&E32SELECT_READ)==0)
   191 		return;		// yes - nothing to read
   192 
   193 	test_Next("Consume the datagram");
   194 	char buf[256];
   195 	// Problem in recvfrom: err=recvfrom(testFid,buf,sizeof(buf),0,0,0);
   196 	struct sockaddr_in junk;
   197 	size_t junklen=sizeof(junk);
   198 	err=recvfrom(testFid,buf,sizeof(buf),0,(struct sockaddr*)&junk,&junklen);
   199 	// Problem in recfrom: test_ok(err==length);
   200 	test_ok(err>=0);
   201 	}
   202 /**
   203 @SYMTestCaseID          SYSLIB-STDLIB-CT-1045
   204 @SYMTestCaseDesc	    Tests for killing an ioctl
   205 @SYMTestPriority 	    High
   206 @SYMTestActions  	    Create two threads which will block on the socket
   207 						then kill one of them and send a datagram 
   208 						check the exit status of both threads
   209 @SYMTestExpectedResults Test must not fail
   210 @SYMREQ                 REQ0000
   211 */		
   212 void test_killing(TInt aThread, TThreadFunction aFunction, char* aTitle)
   213 	{
   214 	_LIT(KThreadName, "TCancel Test Thread %d");
   215 	TBuf<80> threadName;
   216 	static TInt threadNumber=0;
   217 
   218 	test_Next(aTitle);
   219 	// test_Next("Create test thread A");
   220 	RThread thread1;
   221 	TRequestStatus status1;
   222 	threadName.Format(KThreadName,++threadNumber);
   223 	TInt err=thread1.Create(threadName,aFunction,0x10000,NULL,(TAny*)0);
   224 	test(err==KErrNone);
   225 	thread1.Logon(status1);
   226 	thread1.Resume();
   227 
   228 	// test_Next("Create test thread B");
   229 	RThread thread2;
   230 	TRequestStatus status2;
   231 	threadName.Format(KThreadName,++threadNumber);
   232 	err=thread2.Create(threadName,aFunction,0x10000,NULL,(TAny*)1);
   233 	test(err==KErrNone);
   234 	thread2.Logon(status2);
   235 	thread2.Resume();
   236 
   237 	test_Next("Start thread A, then thread B...");
   238 	semaphores[0].Signal();
   239 	User::After(1);
   240 	semaphores[1].Signal();
   241 	User::After(1);
   242 
   243 	if (aThread==1)
   244 		{
   245 		test_Next("Kill thread A");
   246 		kill_and_check(thread1, status1, status2);
   247 		}
   248 	else
   249 		{
   250 		test_Next("Kill thread B");
   251 		kill_and_check(thread2, status2, status1);
   252 		}
   253 
   254 	thread1.Close();
   255 	thread2.Close();
   256 	}
   257 
   258 int main()
   259 	{
   260 	
   261 	start_redirection_server();
   262 
   263 	test_Title("TCANCEL");
   264 	init_test();
   265 	test_ioctl();		// explicit cancellation
   266 	test_killing(1,ioctl_block, "Cancellation of active ioctl");	
   267 	test_killing(2,ioctl_block, "Cancellation of queued ioctl");
   268 	test_killing(1,recv_block,  "Cancellation of active recvfrom");	
   269 	test_killing(2,recv_block,  "Cancellation of queued recvfrom");
   270 	test_Close();
   271 	return KErrNone;
   272 	}