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