plugins/networking/winsockprt/src/wsp_session.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // wsp_session.cpp
       
     2 // 
       
     3 // Copyright (c) 2002 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 
       
    14 #include "wsp_session.h"
       
    15 #include "wsp_factory.h"
       
    16 #include "wsp_request.h"
       
    17 #include "wsp_panic.h"
       
    18 #include "wsp_log.h"
       
    19 
       
    20 
       
    21 //
       
    22 // Constants.
       
    23 //
       
    24 
       
    25 _LIT(KWspThreadName, "WinSockPrtThread");
       
    26 _LIT(KWspThreadNameWhilstWaitingForDeath, "WinSockPrtThread_WaitingForDeath_%Ld");
       
    27 _LIT(KWspThreadStartSemaphoreName, "WinSockPrtThreadStartSemaphore");
       
    28 const TInt KWspThreadStackSize = KDefaultStackSize;
       
    29 const TInt KWspThreadMinHeapSize = 0x4000;		// 16 kb
       
    30 const TInt KWspThreadMaxHeapSize = 0x40000;		// 256 kb
       
    31 
       
    32 
       
    33 //
       
    34 // RWin32Session.
       
    35 //
       
    36 
       
    37 TInt RWin32Session::Open()
       
    38 	{
       
    39 	return CreateThread();
       
    40 	}
       
    41 
       
    42 void RWin32Session::Close()
       
    43 	{
       
    44 	if (iThread.Handle())
       
    45 		{
       
    46 		iWin32Message.Set(CWin32Session::EClose);
       
    47 		iRequest.MakeRequest(iWin32Message);
       
    48 		iThread.Close();
       
    49 		}
       
    50 	}
       
    51 
       
    52 TInt RWin32Session::MakeRequest(TWin32Message& aMessage)
       
    53 	{
       
    54 	return iRequest.MakeRequest(aMessage);
       
    55 	}
       
    56 
       
    57 TInt RWin32Session::CreateThread()
       
    58 	{
       
    59 	WSP_LOG(WspLog::Write(_L("RWin32Session::CreateThread")));
       
    60 #ifdef _DEBUG
       
    61 	TFindThread findThread(KWspThreadName);
       
    62 	TFullName name;
       
    63 	__ASSERT_DEBUG(findThread.Next(name)==KErrNotFound, Panic(EWinSockPrtThreadAlreadyExists));
       
    64 #endif
       
    65 	
       
    66 	RSemaphore threadStartSemaphore;
       
    67 	TInt err = threadStartSemaphore.CreateGlobal(KWspThreadStartSemaphoreName, 0, EOwnerThread);
       
    68 	if (err)
       
    69 		{
       
    70 		return err;
       
    71 		}
       
    72 
       
    73 	err = iThread.Create(KWspThreadName, WinSockPrtThreadStart, KWspThreadStackSize, KWspThreadMinHeapSize, KWspThreadMaxHeapSize, &iRequest, EOwnerThread);
       
    74 	if (err == KErrNone)
       
    75 		{
       
    76 		err = iRequest.DuplicateParentThreadHandle(iThread);
       
    77 		if (err)
       
    78 			{
       
    79 			iThread.Close();
       
    80 			threadStartSemaphore.Close();
       
    81 			return err;
       
    82 			}
       
    83 		//iThread.SetPriority(EPriorityAbsoluteVeryLow); // Hack to prevent the thread from blocking all threads lower than the default priority. Should really be using a raw Win32 thread rather than a Symbian one.
       
    84 		iThread.Resume();
       
    85 		threadStartSemaphore.Wait();
       
    86 		threadStartSemaphore.Close();
       
    87 		}
       
    88 	else
       
    89 		{
       
    90 		threadStartSemaphore.Close();
       
    91 		}
       
    92 	return err;
       
    93 	}
       
    94 
       
    95 
       
    96 //
       
    97 // Thread start functions.
       
    98 //
       
    99 
       
   100 GLDEF_C TInt WinSockPrtThreadStart(TAny* aPtr)
       
   101 	{
       
   102 	__UHEAP_MARK;
       
   103 	CTrapCleanup* trapCleanup = CTrapCleanup::New();
       
   104 	if (trapCleanup == NULL)
       
   105 		{
       
   106 		return KErrNoMemory;
       
   107 		}
       
   108 	TRAPD(err, InitialiseAndRunThreadL(aPtr));
       
   109 	WSP_LOG(WspLog::Close());
       
   110 	delete trapCleanup;
       
   111 	__UHEAP_MARKEND;
       
   112 	return err;
       
   113 	}
       
   114 
       
   115 GLDEF_C void InitialiseAndRunThreadL(TAny* aPtr)
       
   116 	{
       
   117 	WSP_LOG(User::LeaveIfError(WspLog::Open()));
       
   118 	CWin32Scheduler* win32Scheduler = CWin32Scheduler::NewL();
       
   119 	CleanupStack::PushL(win32Scheduler);
       
   120 	TWin32Request* request = static_cast<TWin32Request*>(aPtr);
       
   121 	CWin32Factory* win32Factory = CWin32Factory::NewL(*request, *win32Scheduler);
       
   122 	CleanupStack::PushL(win32Factory);
       
   123 
       
   124 	RSemaphore threadStartSemaphore;
       
   125 	User::LeaveIfError(threadStartSemaphore.OpenGlobal(KWspThreadStartSemaphoreName, EOwnerThread));
       
   126 	threadStartSemaphore.Signal();
       
   127 	threadStartSemaphore.Close();
       
   128 	
       
   129 	win32Scheduler->Start();
       
   130 
       
   131 	CleanupStack::PopAndDestroy(2, win32Scheduler);
       
   132 	}
       
   133 
       
   134 
       
   135 //
       
   136 // CWin32Session.
       
   137 //
       
   138 
       
   139 void CWin32Session::AddSubSessionL(CWin32SubSession* aSubSession)
       
   140 	{
       
   141 	TInt subSessionHandle = reinterpret_cast<TInt>(aSubSession);
       
   142 	TPckg<TInt> subSessionHandlePckg(subSessionHandle);
       
   143 	iRequest.Message().WriteBuffer().Copy(subSessionHandlePckg);
       
   144 	CleanupStack::PushL(aSubSession);
       
   145 	User::LeaveIfError(iSubSessions.Append(aSubSession));
       
   146 	CleanupStack::Pop(aSubSession);
       
   147 	}
       
   148 
       
   149 CWin32Session::~CWin32Session()
       
   150 	{
       
   151 	__ASSERT_DEBUG(iSubSessions.Count() == 0, Panic(EWinSockPrtSubSessionListNotEmpty));
       
   152 	iSubSessions.Close();
       
   153 	}
       
   154 
       
   155 CWin32Session::CWin32Session(TWin32Request& aRequest, CWin32Scheduler& aScheduler)
       
   156 	: CWin32ActiveObject(aScheduler), iRequest(aRequest)
       
   157 	{
       
   158 	}
       
   159 
       
   160 void CWin32Session::ConstructL()
       
   161 	{
       
   162 	CWin32ActiveObject::ConstructL();
       
   163 	iRequest.SetEventHandle(iEvent);
       
   164 	}
       
   165 
       
   166 void CWin32Session::Run()
       
   167 	{
       
   168 	TInt err = KErrNone;
       
   169 
       
   170 	CWin32SubSession* subSession = reinterpret_cast<CWin32SubSession*>(iRequest.SubSession());
       
   171 	TWin32Message& message = iRequest.Message();
       
   172 	if (subSession == NULL)
       
   173 		{
       
   174 		switch (message.OppCode())
       
   175 			{
       
   176 			case EClose:
       
   177 				{
       
   178 				Close();
       
   179 				break;
       
   180 				}
       
   181 			case ECloseSubSession:
       
   182 				{
       
   183 				CloseSubSession();
       
   184 				break;
       
   185 				}
       
   186 			default:
       
   187 				{
       
   188 				// Pass on to sub-class.
       
   189 				TRAP(err, ServiceL(message));
       
   190 				}
       
   191 			}
       
   192 		}
       
   193 	else
       
   194 		{
       
   195 		TRAP(err, subSession->ServiceL(message));
       
   196 		}
       
   197 
       
   198 	iRequest.Requested(err);
       
   199 	}
       
   200 
       
   201 void CWin32Session::Close()
       
   202 	{
       
   203 	// This thread could take a while to die, so give it a different name so that subsequent client attempt to create another one don't fail with KErrInUse.
       
   204 	TTime time;
       
   205 	time.UniversalTime();
       
   206 	const TInt64& int64 = time.Int64();
       
   207 	TBuf<64> newThreadName;
       
   208 	newThreadName.Format(KWspThreadNameWhilstWaitingForDeath(), int64);
       
   209 	User::RenameThread(newThreadName); // Throw away error code.
       
   210 	iScheduler.Stop();
       
   211 	}
       
   212 
       
   213 void CWin32Session::CloseSubSession()
       
   214 	{
       
   215 	TInt handle;
       
   216 	TPckg<TInt> handlePckg(handle);
       
   217 	handlePckg.Copy(iRequest.Message().ReadBuffer());
       
   218 	CWin32SubSession* subSessionToClose = reinterpret_cast<CWin32SubSession*>(handle);
       
   219 	TInt pos = iSubSessions.Find(subSessionToClose);
       
   220 	__ASSERT_DEBUG(pos >= 0, Panic(EWinSockPrtUnableToFindSubSession));
       
   221 	delete subSessionToClose;
       
   222 	iSubSessions.Remove(pos);
       
   223 	}