os/persistentdata/loggingservices/eventlogger/test/src/t_logbench.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) 2002-2010 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
//
sl@0
    15
sl@0
    16
#define __PROFILING__
sl@0
    17
#include <s32file.h>
sl@0
    18
#include "t_logutil2.h"
sl@0
    19
#include <logview.h>
sl@0
    20
sl@0
    21
RTest TheTest(_L("t_logbench"));
sl@0
    22
sl@0
    23
TLogConfig theConfig;
sl@0
    24
sl@0
    25
_LIT(KTestString, "%dabcdefghijklmnopqrstuvwxyz");
sl@0
    26
_LIT(KResultFile, "C:\\LOGENG_TEST.TXT");
sl@0
    27
sl@0
    28
const TInt KLogSize = 50;
sl@0
    29
const TInt KTestFactor = 2;  
sl@0
    30
sl@0
    31
// Class used to record test details
sl@0
    32
class TTestDetails
sl@0
    33
	{
sl@0
    34
public:
sl@0
    35
	TInt iEventNum;
sl@0
    36
	TInt iTimeToAdd;
sl@0
    37
	//
sl@0
    38
	TInt iViewSize;
sl@0
    39
	TInt iTimeToNavigate;
sl@0
    40
	//
sl@0
    41
	TInt iDatabaseSize;
sl@0
    42
	TInt iHeapSize;
sl@0
    43
	};
sl@0
    44
sl@0
    45
LOCAL_C TInt GetHeapSizeL()
sl@0
    46
	{	
sl@0
    47
	TInt heap = 0;
sl@0
    48
	heap = User::Heap().Size();
sl@0
    49
sl@0
    50
	return heap;
sl@0
    51
	}
sl@0
    52
sl@0
    53
LOCAL_C TInt GetServerHeapSizeL()
sl@0
    54
	{
sl@0
    55
	return 1024 * 1024;//By default - the process heap is 1M.
sl@0
    56
	}
sl@0
    57
sl@0
    58
LOCAL_C TInt DatabaseSizeL()
sl@0
    59
	{
sl@0
    60
		return TestUtils::DatabaseSizeL();
sl@0
    61
	}
sl@0
    62
sl@0
    63
/**
sl@0
    64
@SYMTestCaseID          SYSLIB-LOGENG-CT-0988
sl@0
    65
@SYMTestCaseDesc	    Sets the configuration setup for the tests
sl@0
    66
@SYMTestPriority 	    High
sl@0
    67
@SYMTestActions  	    Setup for the environment for the tests
sl@0
    68
@SYMTestExpectedResults Test must not fail
sl@0
    69
@SYMREQ                 REQ0000
sl@0
    70
*/
sl@0
    71
LOCAL_C void TestSetupL(CLogClient& aClient)
sl@0
    72
	{
sl@0
    73
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-LOGENG-CT-0988 "));
sl@0
    74
	CTestActive* active = new(ELeave)CTestActive;
sl@0
    75
	CleanupStack::PushL(active);
sl@0
    76
sl@0
    77
	// Get configuration
sl@0
    78
	aClient.GetConfig(theConfig, active->iStatus);
sl@0
    79
	active->StartL();
sl@0
    80
	CActiveScheduler::Start();
sl@0
    81
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
    82
sl@0
    83
	TheTest.Printf(_L("  Log size: %d\n"), theConfig.iMaxLogSize);
sl@0
    84
	TheTest.Printf(_L("  Recent list size: %d\n"), theConfig.iMaxRecentLogSize);
sl@0
    85
	TheTest.Printf(_L("  Max Event Age: %d\n"), theConfig.iMaxEventAge);
sl@0
    86
sl@0
    87
	TestUtils::DeleteDatabaseL();
sl@0
    88
sl@0
    89
	// Get configuration
sl@0
    90
	aClient.GetConfig(theConfig, active->iStatus);
sl@0
    91
	active->StartL();
sl@0
    92
	CActiveScheduler::Start();
sl@0
    93
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
    94
sl@0
    95
	// Wait for user interation
sl@0
    96
	//TheTest.Printf(_L("  Quick tests performed if no key pressed in next 10 seconds\n"));
sl@0
    97
    //TKeyCode key;
sl@0
    98
	//if (!TestUtils::WaitForKeyL(10000000, key))
sl@0
    99
		{
sl@0
   100
		theConfig.iMaxLogSize = KLogSize;
sl@0
   101
sl@0
   102
		// Set configuration in database
sl@0
   103
		aClient.ChangeConfig(theConfig, active->iStatus);
sl@0
   104
		active->StartL();
sl@0
   105
		CActiveScheduler::Start();
sl@0
   106
		TEST2(active->iStatus.Int(), KErrNone);
sl@0
   107
		}
sl@0
   108
sl@0
   109
	CleanupStack::PopAndDestroy(); // active
sl@0
   110
	}
sl@0
   111
sl@0
   112
/**
sl@0
   113
@SYMTestCaseID          SYSLIB-LOGENG-CT-0989
sl@0
   114
@SYMTestCaseDesc	    Benchmark test
sl@0
   115
						Tests for writing the log details to a file
sl@0
   116
@SYMTestPriority 	    High
sl@0
   117
@SYMTestActions  	    Add events to the log and write the configuration details to a file
sl@0
   118
@SYMTestExpectedResults Test must not fail
sl@0
   119
@SYMREQ                 REQ0000
sl@0
   120
*/
sl@0
   121
LOCAL_C void BenchmarkTestL(CLogClient& aClient, RFile& aFile)
sl@0
   122
	{
sl@0
   123
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-LOGENG-CT-0989 "));
sl@0
   124
	CTestActive* active = new(ELeave)CTestActive;
sl@0
   125
	CleanupStack::PushL(active);
sl@0
   126
sl@0
   127
	CLogViewEvent* view = CLogViewEvent::NewL(aClient);
sl@0
   128
	CleanupStack::PushL(view);
sl@0
   129
sl@0
   130
	CLogFilter* filter = CLogFilter::NewL();
sl@0
   131
	CleanupStack::PushL(filter);
sl@0
   132
sl@0
   133
	CLogEvent* event = CLogEvent::NewL();
sl@0
   134
	CleanupStack::PushL(event);
sl@0
   135
	event->SetEventType(KLogCallEventTypeUid);
sl@0
   136
sl@0
   137
	aFile.Write(_L8("Adding Events\n"));
sl@0
   138
sl@0
   139
	TBuf8<256> buf;
sl@0
   140
	TInt count = 0;
sl@0
   141
sl@0
   142
	TLogString string;
sl@0
   143
	string.Format(KTestString, count);
sl@0
   144
sl@0
   145
	while(count++ < theConfig.iMaxLogSize * KTestFactor)
sl@0
   146
		{
sl@0
   147
		event->SetRemoteParty(string);
sl@0
   148
		event->SetSubject(string);
sl@0
   149
		event->SetNumber(string);
sl@0
   150
		event->SetStatus(string);
sl@0
   151
sl@0
   152
		if (count % 10 == 0)
sl@0
   153
			string.Format(KTestString, count);
sl@0
   154
sl@0
   155
		TTime before;
sl@0
   156
		before.UniversalTime();
sl@0
   157
sl@0
   158
		// Add a new event
sl@0
   159
		aClient.AddEvent(*event, active->iStatus);
sl@0
   160
		active->StartL();
sl@0
   161
		CActiveScheduler::Start();
sl@0
   162
		TEST2(active->iStatus.Int(), KErrNone);
sl@0
   163
sl@0
   164
		TTime after;
sl@0
   165
		after.UniversalTime();
sl@0
   166
		TTimeIntervalMicroSeconds interval = after.MicroSecondsFrom(before);
sl@0
   167
sl@0
   168
		TInt dbSize = DatabaseSizeL();
sl@0
   169
		TInt heapSize = GetHeapSizeL();
sl@0
   170
		TInt serverHeapSize = GetServerHeapSizeL();
sl@0
   171
sl@0
   172
		// Store details in file
sl@0
   173
		TheTest.Printf(_L("  Num: %d, Time: %d, Db Size: %d, Hs: %d, Server Hs: %d\n"), count, I64INT(interval.Int64()), dbSize, heapSize, serverHeapSize);
sl@0
   174
		buf.Format(_L8("%d,%d,%d,%d,%d\n"), count, I64INT(interval.Int64()), dbSize, heapSize, serverHeapSize);
sl@0
   175
		aFile.Write(buf);
sl@0
   176
		}
sl@0
   177
sl@0
   178
	aFile.Write(_L8("Navigating View\n"));
sl@0
   179
	count = 1;
sl@0
   180
sl@0
   181
	// Navigate the view
sl@0
   182
	TEST(view->SetFilterL(*filter, active->iStatus));
sl@0
   183
	active->StartL();
sl@0
   184
	CActiveScheduler::Start();
sl@0
   185
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
   186
sl@0
   187
	while(view->NextL(active->iStatus))
sl@0
   188
		{
sl@0
   189
		TTime before;
sl@0
   190
		before.UniversalTime();
sl@0
   191
sl@0
   192
		active->StartL();
sl@0
   193
		CActiveScheduler::Start();
sl@0
   194
		TEST2(active->iStatus.Int(), KErrNone);
sl@0
   195
sl@0
   196
		TTime after;
sl@0
   197
		after.UniversalTime();
sl@0
   198
		TTimeIntervalMicroSeconds interval = after.MicroSecondsFrom(before);
sl@0
   199
sl@0
   200
		TInt heapSize = GetHeapSizeL();
sl@0
   201
		TInt serverHeapSize = GetServerHeapSizeL();
sl@0
   202
sl@0
   203
		// Store details in file
sl@0
   204
		TheTest.Printf(_L("  Count: %d, Time: %d, Hs: %d, Server Hs: %d\n"), count, I64INT(interval.Int64()), heapSize, serverHeapSize);
sl@0
   205
		buf.Format(_L8("%d,%d,%d,%d\n"), count++, I64INT(interval.Int64()), heapSize, serverHeapSize);
sl@0
   206
		aFile.Write(buf);
sl@0
   207
		}
sl@0
   208
sl@0
   209
	CleanupStack::PopAndDestroy(4); // event, filter, view, active
sl@0
   210
	}
sl@0
   211
sl@0
   212
/**
sl@0
   213
@SYMTestCaseID          SYSLIB-LOGENG-CT-0990
sl@0
   214
@SYMTestCaseDesc	    Tests for CLogViewRecent::SetRecentListL(),CLogViewRecent::DuplicatesL() functions
sl@0
   215
@SYMTestPriority 	    High
sl@0
   216
@SYMTestActions  	    Set the recent log view list and refresh for the duplicates view.
sl@0
   217
                        Check for ErrNone flag
sl@0
   218
@SYMTestExpectedResults Test must not fail
sl@0
   219
@SYMREQ                 REQ0000
sl@0
   220
*/
sl@0
   221
LOCAL_C void DoTestRecentViewsL(CLogClient& aClient, TLogRecentList aList, TInt aRecentCount, TInt aDuplicateCount)
sl@0
   222
	{
sl@0
   223
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-LOGENG-CT-0990 "));
sl@0
   224
	CTestActive* active = new(ELeave)CTestActive();
sl@0
   225
	CleanupStack::PushL(active);
sl@0
   226
sl@0
   227
	CLogViewRecent* recent = CLogViewRecent::NewL(aClient);
sl@0
   228
	CleanupStack::PushL(recent);
sl@0
   229
sl@0
   230
	CLogViewDuplicate* duplicate = CLogViewDuplicate::NewL(aClient);
sl@0
   231
	CleanupStack::PushL(duplicate);
sl@0
   232
sl@0
   233
	TEST(recent->SetRecentListL(aList, active->iStatus) || aRecentCount == 0);
sl@0
   234
	do
sl@0
   235
		{
sl@0
   236
		if (aRecentCount == 0)
sl@0
   237
			break;
sl@0
   238
sl@0
   239
		active->StartL();
sl@0
   240
		CActiveScheduler::Start();
sl@0
   241
		TEST2(active->iStatus.Int(), KErrNone);
sl@0
   242
sl@0
   243
		TEST(recent->DuplicatesL(*duplicate, active->iStatus) || aDuplicateCount == 0);
sl@0
   244
		do
sl@0
   245
			{
sl@0
   246
			if (aDuplicateCount == 0)
sl@0
   247
				break;
sl@0
   248
sl@0
   249
			active->StartL();
sl@0
   250
			CActiveScheduler::Start();
sl@0
   251
			TEST2(active->iStatus.Int(), KErrNone);
sl@0
   252
			}
sl@0
   253
		while(duplicate->NextL(active->iStatus));
sl@0
   254
		TEST(duplicate->CountL() == aDuplicateCount);
sl@0
   255
		}
sl@0
   256
	while(recent->NextL(active->iStatus));
sl@0
   257
	TEST(recent->CountL() == aRecentCount);
sl@0
   258
sl@0
   259
	CleanupStack::PopAndDestroy(3); // active, recent, duplicate
sl@0
   260
	}
sl@0
   261
sl@0
   262
/**
sl@0
   263
@SYMTestCaseID          SYSLIB-LOGENG-CT-0991
sl@0
   264
@SYMTestCaseDesc	    Tests to clear the duplicates in a view
sl@0
   265
                        Tests CLogViewRecent::ClearDuplicatesL() function
sl@0
   266
@SYMTestPriority 	    High
sl@0
   267
@SYMTestActions  	    Set the recent log view list.Check for ErrNone flag.
sl@0
   268
                        Write the details to a file.
sl@0
   269
@SYMTestExpectedResults Test must not fail
sl@0
   270
@SYMREQ                 REQ0000
sl@0
   271
*/
sl@0
   272
LOCAL_C void DoTestClearDuplicateL(CLogClient& aClient, TLogRecentList aList, RFile& aFile)
sl@0
   273
	{
sl@0
   274
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-LOGENG-CT-0991 "));
sl@0
   275
	CTestActive* active = new(ELeave)CTestActive();
sl@0
   276
	CleanupStack::PushL(active);
sl@0
   277
sl@0
   278
	CLogViewRecent* recent = CLogViewRecent::NewL(aClient);
sl@0
   279
	CleanupStack::PushL(recent);
sl@0
   280
sl@0
   281
	TTime before;
sl@0
   282
	before.UniversalTime();
sl@0
   283
sl@0
   284
	recent->SetRecentListL(aList, active->iStatus);
sl@0
   285
	active->StartL();
sl@0
   286
	CActiveScheduler::Start();
sl@0
   287
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
   288
	recent->ClearDuplicatesL();
sl@0
   289
sl@0
   290
	TTime after;
sl@0
   291
	after.UniversalTime();
sl@0
   292
	TTimeIntervalMicroSeconds interval = after.MicroSecondsFrom(before);
sl@0
   293
sl@0
   294
	TBuf8<256> buf;
sl@0
   295
	TheTest.Printf(_L("Clearing Duplicates for List %d, %d\n"), recent->RecentList(), I64INT(interval.Int64()));
sl@0
   296
	buf.Format(_L8("Clearing Duplicates for List %d, %d\n"), recent->RecentList(), I64INT(interval.Int64()));
sl@0
   297
	aFile.Write(buf);
sl@0
   298
sl@0
   299
	CleanupStack::PopAndDestroy(2); // recent, active
sl@0
   300
	}
sl@0
   301
sl@0
   302
/**
sl@0
   303
@SYMTestCaseID          SYSLIB-LOGENG-CT-0992
sl@0
   304
@SYMTestCaseDesc	    Recent lists view test
sl@0
   305
@SYMTestPriority 	    High
sl@0
   306
@SYMTestActions  	    Add the events to the log and execute the test functions. 
sl@0
   307
@SYMTestExpectedResults Test must not fail
sl@0
   308
@SYMREQ                 REQ0000
sl@0
   309
*/
sl@0
   310
LOCAL_C void TestRecentListsL(CLogClient& aClient, RFile& aFile)
sl@0
   311
	{
sl@0
   312
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-LOGENG-CT-0992 "));
sl@0
   313
	aFile.Write(_L8("Recent Lists\n"));
sl@0
   314
sl@0
   315
	CTestActive* active = new(ELeave)CTestActive();
sl@0
   316
	CleanupStack::PushL(active);
sl@0
   317
sl@0
   318
	TLogConfig config;
sl@0
   319
	active->StartL();
sl@0
   320
	aClient.GetConfig(config, active->iStatus);
sl@0
   321
	CActiveScheduler::Start();
sl@0
   322
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
   323
sl@0
   324
	CLogEvent* event = CLogEvent::NewL();
sl@0
   325
	CleanupStack::PushL(event);
sl@0
   326
	event->SetEventType(KLogCallEventTypeUid);
sl@0
   327
sl@0
   328
	for(TInt duplicates = 0; duplicates < 10; duplicates++)
sl@0
   329
		{
sl@0
   330
		TTime before;
sl@0
   331
		before.UniversalTime();
sl@0
   332
sl@0
   333
		// Incoming
sl@0
   334
		TLogString incoming;
sl@0
   335
		aClient.GetString(incoming, R_LOG_DIR_IN);
sl@0
   336
		event->SetDirection(incoming);
sl@0
   337
sl@0
   338
		TInt count;
sl@0
   339
		for(count = 0; count < config.iMaxRecentLogSize; count++)
sl@0
   340
			{
sl@0
   341
			TLogString number;
sl@0
   342
			number.Num(count);
sl@0
   343
			event->SetNumber(number);
sl@0
   344
sl@0
   345
			active->StartL();
sl@0
   346
			aClient.AddEvent(*event, active->iStatus);
sl@0
   347
			CActiveScheduler::Start();
sl@0
   348
			TEST2(active->iStatus.Int(), KErrNone);
sl@0
   349
			}
sl@0
   350
sl@0
   351
		// Outgoing
sl@0
   352
		TLogString outgoing;
sl@0
   353
		aClient.GetString(outgoing, R_LOG_DIR_OUT);
sl@0
   354
		event->SetDirection(outgoing);
sl@0
   355
sl@0
   356
		for(count = 0; count < config.iMaxRecentLogSize; count++)
sl@0
   357
			{
sl@0
   358
			TLogString number;
sl@0
   359
			number.Num(count);
sl@0
   360
			event->SetNumber(number);
sl@0
   361
sl@0
   362
			active->StartL();
sl@0
   363
			aClient.AddEvent(*event, active->iStatus);
sl@0
   364
			CActiveScheduler::Start();
sl@0
   365
			TEST2(active->iStatus.Int(), KErrNone);
sl@0
   366
			}
sl@0
   367
sl@0
   368
		// Missed
sl@0
   369
		TLogString missed;
sl@0
   370
		aClient.GetString(missed, R_LOG_DIR_MISSED);
sl@0
   371
		event->SetDirection(missed);
sl@0
   372
sl@0
   373
		for(count = 0; count < config.iMaxRecentLogSize; count++)
sl@0
   374
			{
sl@0
   375
			TLogString number;
sl@0
   376
			number.Num(count);
sl@0
   377
			event->SetNumber(number);
sl@0
   378
sl@0
   379
			active->StartL();
sl@0
   380
			aClient.AddEvent(*event, active->iStatus);
sl@0
   381
			CActiveScheduler::Start();
sl@0
   382
			TEST2(active->iStatus.Int(), KErrNone);
sl@0
   383
			}
sl@0
   384
sl@0
   385
		TTime afterAdd;
sl@0
   386
		afterAdd.UniversalTime();
sl@0
   387
sl@0
   388
		DoTestRecentViewsL(aClient, KLogRecentIncomingCalls, config.iMaxRecentLogSize, duplicates);
sl@0
   389
		DoTestRecentViewsL(aClient, KLogRecentOutgoingCalls, config.iMaxRecentLogSize, duplicates);
sl@0
   390
		DoTestRecentViewsL(aClient, KLogRecentMissedCalls, config.iMaxRecentLogSize, duplicates);
sl@0
   391
sl@0
   392
		TTime afterNav;
sl@0
   393
		afterNav.UniversalTime();
sl@0
   394
sl@0
   395
		TTimeIntervalMicroSeconds interval1 = afterAdd.MicroSecondsFrom(before);
sl@0
   396
		TTimeIntervalMicroSeconds interval2 = afterNav.MicroSecondsFrom(afterAdd);
sl@0
   397
sl@0
   398
		// Store details in file
sl@0
   399
		TBuf8<256> buf;
sl@0
   400
		TheTest.Printf(_L("  Count: %d, Add: %d, Nav: %d\n"), duplicates, I64INT(interval1.Int64()), I64INT(interval2.Int64()));
sl@0
   401
		buf.Format(_L8("%d,%d,%d\n"), duplicates, I64INT(interval1.Int64()), I64INT(interval2.Int64()));
sl@0
   402
		aFile.Write(buf);
sl@0
   403
		}
sl@0
   404
sl@0
   405
	DoTestClearDuplicateL(aClient, KLogRecentIncomingCalls, aFile);
sl@0
   406
	DoTestClearDuplicateL(aClient, KLogRecentOutgoingCalls, aFile);
sl@0
   407
	DoTestClearDuplicateL(aClient, KLogRecentMissedCalls, aFile);
sl@0
   408
sl@0
   409
	CleanupStack::PopAndDestroy(2); // active, event
sl@0
   410
	}
sl@0
   411
sl@0
   412
sl@0
   413
void doTestsL()
sl@0
   414
	{
sl@0
   415
	TestUtils::Initialize(_L("t_logbench"));
sl@0
   416
sl@0
   417
	CLogChangeNotifier* notifier = CLogChangeNotifier::NewL();
sl@0
   418
	CleanupStack::PushL(notifier);
sl@0
   419
sl@0
   420
	CLogClient* client = CLogClient::NewL(theFs);
sl@0
   421
	CleanupStack::PushL(client);
sl@0
   422
sl@0
   423
	CTestActive* active = new(ELeave)CTestActive();
sl@0
   424
	CleanupStack::PushL(active);
sl@0
   425
sl@0
   426
	TLogConfig config;
sl@0
   427
	client->GetConfig(config, active->iStatus);
sl@0
   428
	active->StartL();
sl@0
   429
	CActiveScheduler::Start();
sl@0
   430
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
   431
sl@0
   432
	TheTest.Start(_L("Setup"));
sl@0
   433
	TestSetupL(*client);
sl@0
   434
	theLog.Write(_L8("Test 1 OK\n"));
sl@0
   435
	
sl@0
   436
	RFile results;
sl@0
   437
	LEAVE_IF_ERROR(results.Replace(theFs, KResultFile, EFileWrite|EFileShareExclusive));
sl@0
   438
sl@0
   439
	TheTest.Next(_L("Benchmark tests"));
sl@0
   440
	BenchmarkTestL(*client, results);
sl@0
   441
	theLog.Write(_L8("Test 2 OK\n"));
sl@0
   442
sl@0
   443
	TestUtils::DeleteDatabaseL();
sl@0
   444
sl@0
   445
	TheTest.Next(_L("Recent List tests"));
sl@0
   446
	TestRecentListsL(*client, results);
sl@0
   447
	theLog.Write(_L8("Test 3 OK\n"));
sl@0
   448
sl@0
   449
	// Restore Config
sl@0
   450
	client->ChangeConfig(config, active->iStatus);
sl@0
   451
	active->StartL();
sl@0
   452
	CActiveScheduler::Start();
sl@0
   453
	TEST2(active->iStatus.Int(), KErrNone);
sl@0
   454
sl@0
   455
	results.Close();
sl@0
   456
	CleanupStack::PopAndDestroy(3); // active, notifier, client;
sl@0
   457
	}
sl@0
   458