os/ossrv/genericopenlibs/cstdlib/TSTLIB/TCANCEL.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/TSTLIB/TCANCEL.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,272 @@
     1.4 +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Test code for interrupted IO operations
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <e32std.h>
    1.22 +#include <e32svr.h>	// for RDebug
    1.23 +#include <stdlib.h>
    1.24 +#include <unistd.h>
    1.25 +#include <stdio.h>
    1.26 +#include <string.h>
    1.27 +#include <sys/fcntl.h>
    1.28 +#include <sys/errno.h>
    1.29 +
    1.30 +#include <sys/ioctl.h>		// for E32IOSELECT
    1.31 +#include <sys/socket.h>
    1.32 +#include <libc/netinet/in.h>
    1.33 +
    1.34 +extern "C" {
    1.35 +#include "CTEST.H"
    1.36 +}
    1.37 +test_Data;
    1.38 +
    1.39 +#include <estlib.h>	// for multi-threading control
    1.40 +
    1.41 +int testFid;
    1.42 +struct sockaddr_in testAddr;
    1.43 +RSemaphore semaphores[2];
    1.44 +
    1.45 +void init_test()
    1.46 +	{
    1.47 +	// We need a datagram socket that we can send to
    1.48 +
    1.49 +	test_Next("Create datagram socket");
    1.50 +	testFid=socket(PF_INET, SOCK_DGRAM, 0);
    1.51 +	test_ok(testFid>=0);
    1.52 +	
    1.53 +	test_Next("Bind to local address");
    1.54 +	IN_SET_LOOPBACK_ADDR(&testAddr);
    1.55 +	testAddr.sin_port=0;
    1.56 +
    1.57 +	size_t len=sizeof(testAddr);
    1.58 +	int err=bind(testFid, (struct sockaddr*)&testAddr, len);
    1.59 +	test_ok(err==0);
    1.60 +
    1.61 +	err=getsockname(testFid, (struct sockaddr*)&testAddr, &len);
    1.62 +	test_ok(err==0);
    1.63 +
    1.64 +	// We now have a datagram socket with a known address
    1.65 +
    1.66 +	test_Next("Create semaphores for test synchronisation");
    1.67 +	for (int i=0; i<2; i++)
    1.68 +		{
    1.69 +		err=semaphores[i].CreateLocal(0);
    1.70 +		test(err==KErrNone);
    1.71 +		}
    1.72 +	}
    1.73 +
    1.74 +/**
    1.75 +Test of the asynchronous ioctl & cancel code
    1.76 +
    1.77 +@SYMTestCaseID          SYSLIB-STDLIB-CT-1044
    1.78 +@SYMTestCaseDesc	    Tests for the asynchronous ioctl & cancel code
    1.79 +@SYMTestPriority 	    High
    1.80 +@SYMTestActions  	    Tests that E32IOSELECT ioctl is working
    1.81 +						Tests for asynchronous IOCTL.
    1.82 +						Setup asynchronous IOCTL which won't complete, then cancel.Check for cancel status
    1.83 +						Cancel a completed asynchronous IOCTL,and check for no error
    1.84 +@SYMTestExpectedResults Test must not fail
    1.85 +@SYMREQ                 REQ0000
    1.86 +*/		
    1.87 +void test_ioctl()
    1.88 +	{
    1.89 +	// confirm that the E32IOSELECT ioctl is working
    1.90 +	test_Next("Check synchronous IOCTL");
    1.91 +	int mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
    1.92 +	int err=ioctl(testFid,E32IOSELECT,&mask);
    1.93 +	test_ok(err==0);
    1.94 +	test(mask==E32SELECT_WRITE);
    1.95 +
    1.96 +	test_Next("Check asynchronous IOCTL");
    1.97 +	TRequestStatus status;
    1.98 +	mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
    1.99 +	err=ioctl(testFid,E32IOSELECT,&mask,status);
   1.100 +	test_ok(err==0);
   1.101 +	User::WaitForRequest(status);
   1.102 +	test(status.Int()==KErrNone);
   1.103 +	err=ioctl_complete(testFid,E32IOSELECT,&mask,status);
   1.104 +	test_ok(err==0);
   1.105 +	test(mask==E32SELECT_WRITE);
   1.106 +
   1.107 +	test_Next("Setup asynchronous IOCTL which won't complete, then cancel");
   1.108 +	mask=E32SELECT_READ;
   1.109 +	err=ioctl(testFid,E32IOSELECT,&mask,status);
   1.110 +	test_ok(err==0);
   1.111 +	test(status.Int()==KRequestPending);	// i.e. waiting for input to arrive
   1.112 +
   1.113 +	// test_Next("Cancel the pending IOCTL");
   1.114 +	// Sadly this will do write() which will get a KErrInUse and then panic...
   1.115 +	err=ioctl_cancel(testFid);
   1.116 +	test_ok(err==0);
   1.117 +	User::WaitForRequest(status);
   1.118 +	test_Next("Check that ioctl_cancel worked");
   1.119 +	test(status.Int()==KErrCancel);			// i.e. it was cancelled
   1.120 +
   1.121 +	test_Next("Cancel a completed asynchronous IOCTL");
   1.122 +	mask=E32SELECT_WRITE;
   1.123 +	err=ioctl(testFid,E32IOSELECT,&mask,status);
   1.124 +	test_ok(err==0);
   1.125 +	
   1.126 +	while (status.Int() == KRequestPending)
   1.127 +		User::After(5000);
   1.128 +
   1.129 +	test(status.Int()!=KRequestPending);	// i.e. select has completed
   1.130 +
   1.131 +	// test_Next("Cancel the pending IOCTL");
   1.132 +	// Sadly this will do write() which will get a KErrInUse and then panic...
   1.133 +	err=ioctl_cancel(testFid);
   1.134 +	test_ok(err==0);
   1.135 +	User::WaitForRequest(status);
   1.136 +	test(status.Int()==KErrNone);			// i.e. it was cancelled
   1.137 +
   1.138 +	}
   1.139 +
   1.140 +// Thread functions which will block accessing the socket
   1.141 +
   1.142 +TInt ioctl_block(TAny* aSemIndex)
   1.143 +	{
   1.144 +	semaphores[(TInt)aSemIndex].Wait();		// block until the test is ready
   1.145 +
   1.146 +	int mask=E32SELECT_READ;
   1.147 +	int err=ioctl(testFid,E32IOSELECT,&mask);
   1.148 +	test_ok(err==0);
   1.149 +	test(mask==E32SELECT_READ);
   1.150 +	return 1;
   1.151 +	}
   1.152 +
   1.153 +TInt recv_block(TAny* aSemIndex)
   1.154 +	{
   1.155 +	semaphores[(TInt)aSemIndex].Wait();		// block until the test is ready
   1.156 +
   1.157 +	char buf[256];
   1.158 +	// Problem in recvfrom: int err=recvfrom(testFid,buf,MSG_PEEK,sizeof(buf),0,0);
   1.159 +	struct sockaddr_in junk;
   1.160 +	size_t junklen=sizeof(junk);
   1.161 +	// Problem in esock/tcpip: int err=recvfrom(testFid,buf,sizeof(buf),MSG_PEEK,(struct sockaddr*)&junk,&junklen);
   1.162 +	int err=recvfrom(testFid,buf,sizeof(buf),0,(struct sockaddr*)&junk,&junklen);
   1.163 +	// Problem in recfrom: test_ok(err>0);
   1.164 +	test_ok(err>=0);
   1.165 +	return 1;
   1.166 +	}
   1.167 +
   1.168 +void kill_and_check(RThread& aVictim, TRequestStatus& aVictimStatus, TRequestStatus& aSurvivorStatus)
   1.169 +	{
   1.170 +	test(aVictimStatus.Int()==KRequestPending);
   1.171 +	test(aSurvivorStatus.Int()==KRequestPending);
   1.172 +	aVictim.Kill(666);
   1.173 +	char* KDatagram="Mine is the last voice you will ever hear";
   1.174 +	int length=strlen(KDatagram)+1;
   1.175 +	
   1.176 +	test_Next("Send datagram");
   1.177 +	int err=sendto(testFid,KDatagram, length,0,(struct sockaddr*)&testAddr,sizeof(testAddr));
   1.178 +	test_ok(err==length);
   1.179 +	User::After(1);
   1.180 +
   1.181 +	test_Next("Check the victim status");
   1.182 +	User::WaitForRequest(aVictimStatus);
   1.183 +	test(aVictimStatus.Int()==666);
   1.184 +
   1.185 +	test_Next("Check the survivor status");
   1.186 +	User::WaitForRequest(aSurvivorStatus);
   1.187 +	test(aSurvivorStatus.Int()==1);
   1.188 +
   1.189 +	// Check to see if the datagram has been swallowed
   1.190 +	int mask=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT;
   1.191 +	err=ioctl(testFid,E32IOSELECT,&mask);
   1.192 +	test_ok(err==0);
   1.193 +	if ((mask&E32SELECT_READ)==0)
   1.194 +		return;		// yes - nothing to read
   1.195 +
   1.196 +	test_Next("Consume the datagram");
   1.197 +	char buf[256];
   1.198 +	// Problem in recvfrom: err=recvfrom(testFid,buf,sizeof(buf),0,0,0);
   1.199 +	struct sockaddr_in junk;
   1.200 +	size_t junklen=sizeof(junk);
   1.201 +	err=recvfrom(testFid,buf,sizeof(buf),0,(struct sockaddr*)&junk,&junklen);
   1.202 +	// Problem in recfrom: test_ok(err==length);
   1.203 +	test_ok(err>=0);
   1.204 +	}
   1.205 +/**
   1.206 +@SYMTestCaseID          SYSLIB-STDLIB-CT-1045
   1.207 +@SYMTestCaseDesc	    Tests for killing an ioctl
   1.208 +@SYMTestPriority 	    High
   1.209 +@SYMTestActions  	    Create two threads which will block on the socket
   1.210 +						then kill one of them and send a datagram 
   1.211 +						check the exit status of both threads
   1.212 +@SYMTestExpectedResults Test must not fail
   1.213 +@SYMREQ                 REQ0000
   1.214 +*/		
   1.215 +void test_killing(TInt aThread, TThreadFunction aFunction, char* aTitle)
   1.216 +	{
   1.217 +	_LIT(KThreadName, "TCancel Test Thread %d");
   1.218 +	TBuf<80> threadName;
   1.219 +	static TInt threadNumber=0;
   1.220 +
   1.221 +	test_Next(aTitle);
   1.222 +	// test_Next("Create test thread A");
   1.223 +	RThread thread1;
   1.224 +	TRequestStatus status1;
   1.225 +	threadName.Format(KThreadName,++threadNumber);
   1.226 +	TInt err=thread1.Create(threadName,aFunction,0x10000,NULL,(TAny*)0);
   1.227 +	test(err==KErrNone);
   1.228 +	thread1.Logon(status1);
   1.229 +	thread1.Resume();
   1.230 +
   1.231 +	// test_Next("Create test thread B");
   1.232 +	RThread thread2;
   1.233 +	TRequestStatus status2;
   1.234 +	threadName.Format(KThreadName,++threadNumber);
   1.235 +	err=thread2.Create(threadName,aFunction,0x10000,NULL,(TAny*)1);
   1.236 +	test(err==KErrNone);
   1.237 +	thread2.Logon(status2);
   1.238 +	thread2.Resume();
   1.239 +
   1.240 +	test_Next("Start thread A, then thread B...");
   1.241 +	semaphores[0].Signal();
   1.242 +	User::After(1);
   1.243 +	semaphores[1].Signal();
   1.244 +	User::After(1);
   1.245 +
   1.246 +	if (aThread==1)
   1.247 +		{
   1.248 +		test_Next("Kill thread A");
   1.249 +		kill_and_check(thread1, status1, status2);
   1.250 +		}
   1.251 +	else
   1.252 +		{
   1.253 +		test_Next("Kill thread B");
   1.254 +		kill_and_check(thread2, status2, status1);
   1.255 +		}
   1.256 +
   1.257 +	thread1.Close();
   1.258 +	thread2.Close();
   1.259 +	}
   1.260 +
   1.261 +int main()
   1.262 +	{
   1.263 +	
   1.264 +	start_redirection_server();
   1.265 +
   1.266 +	test_Title("TCANCEL");
   1.267 +	init_test();
   1.268 +	test_ioctl();		// explicit cancellation
   1.269 +	test_killing(1,ioctl_block, "Cancellation of active ioctl");	
   1.270 +	test_killing(2,ioctl_block, "Cancellation of queued ioctl");
   1.271 +	test_killing(1,recv_block,  "Cancellation of active recvfrom");	
   1.272 +	test_killing(2,recv_block,  "Cancellation of queued recvfrom");
   1.273 +	test_Close();
   1.274 +	return KErrNone;
   1.275 +	}