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 + }