--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/networking/winsockprt/src/wsp_session.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,223 @@
+// wsp_session.cpp
+//
+// Copyright (c) 2002 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+
+#include "wsp_session.h"
+#include "wsp_factory.h"
+#include "wsp_request.h"
+#include "wsp_panic.h"
+#include "wsp_log.h"
+
+
+//
+// Constants.
+//
+
+_LIT(KWspThreadName, "WinSockPrtThread");
+_LIT(KWspThreadNameWhilstWaitingForDeath, "WinSockPrtThread_WaitingForDeath_%Ld");
+_LIT(KWspThreadStartSemaphoreName, "WinSockPrtThreadStartSemaphore");
+const TInt KWspThreadStackSize = KDefaultStackSize;
+const TInt KWspThreadMinHeapSize = 0x4000; // 16 kb
+const TInt KWspThreadMaxHeapSize = 0x40000; // 256 kb
+
+
+//
+// RWin32Session.
+//
+
+TInt RWin32Session::Open()
+ {
+ return CreateThread();
+ }
+
+void RWin32Session::Close()
+ {
+ if (iThread.Handle())
+ {
+ iWin32Message.Set(CWin32Session::EClose);
+ iRequest.MakeRequest(iWin32Message);
+ iThread.Close();
+ }
+ }
+
+TInt RWin32Session::MakeRequest(TWin32Message& aMessage)
+ {
+ return iRequest.MakeRequest(aMessage);
+ }
+
+TInt RWin32Session::CreateThread()
+ {
+ WSP_LOG(WspLog::Write(_L("RWin32Session::CreateThread")));
+#ifdef _DEBUG
+ TFindThread findThread(KWspThreadName);
+ TFullName name;
+ __ASSERT_DEBUG(findThread.Next(name)==KErrNotFound, Panic(EWinSockPrtThreadAlreadyExists));
+#endif
+
+ RSemaphore threadStartSemaphore;
+ TInt err = threadStartSemaphore.CreateGlobal(KWspThreadStartSemaphoreName, 0, EOwnerThread);
+ if (err)
+ {
+ return err;
+ }
+
+ err = iThread.Create(KWspThreadName, WinSockPrtThreadStart, KWspThreadStackSize, KWspThreadMinHeapSize, KWspThreadMaxHeapSize, &iRequest, EOwnerThread);
+ if (err == KErrNone)
+ {
+ err = iRequest.DuplicateParentThreadHandle(iThread);
+ if (err)
+ {
+ iThread.Close();
+ threadStartSemaphore.Close();
+ return err;
+ }
+ //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.
+ iThread.Resume();
+ threadStartSemaphore.Wait();
+ threadStartSemaphore.Close();
+ }
+ else
+ {
+ threadStartSemaphore.Close();
+ }
+ return err;
+ }
+
+
+//
+// Thread start functions.
+//
+
+GLDEF_C TInt WinSockPrtThreadStart(TAny* aPtr)
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* trapCleanup = CTrapCleanup::New();
+ if (trapCleanup == NULL)
+ {
+ return KErrNoMemory;
+ }
+ TRAPD(err, InitialiseAndRunThreadL(aPtr));
+ WSP_LOG(WspLog::Close());
+ delete trapCleanup;
+ __UHEAP_MARKEND;
+ return err;
+ }
+
+GLDEF_C void InitialiseAndRunThreadL(TAny* aPtr)
+ {
+ WSP_LOG(User::LeaveIfError(WspLog::Open()));
+ CWin32Scheduler* win32Scheduler = CWin32Scheduler::NewL();
+ CleanupStack::PushL(win32Scheduler);
+ TWin32Request* request = static_cast<TWin32Request*>(aPtr);
+ CWin32Factory* win32Factory = CWin32Factory::NewL(*request, *win32Scheduler);
+ CleanupStack::PushL(win32Factory);
+
+ RSemaphore threadStartSemaphore;
+ User::LeaveIfError(threadStartSemaphore.OpenGlobal(KWspThreadStartSemaphoreName, EOwnerThread));
+ threadStartSemaphore.Signal();
+ threadStartSemaphore.Close();
+
+ win32Scheduler->Start();
+
+ CleanupStack::PopAndDestroy(2, win32Scheduler);
+ }
+
+
+//
+// CWin32Session.
+//
+
+void CWin32Session::AddSubSessionL(CWin32SubSession* aSubSession)
+ {
+ TInt subSessionHandle = reinterpret_cast<TInt>(aSubSession);
+ TPckg<TInt> subSessionHandlePckg(subSessionHandle);
+ iRequest.Message().WriteBuffer().Copy(subSessionHandlePckg);
+ CleanupStack::PushL(aSubSession);
+ User::LeaveIfError(iSubSessions.Append(aSubSession));
+ CleanupStack::Pop(aSubSession);
+ }
+
+CWin32Session::~CWin32Session()
+ {
+ __ASSERT_DEBUG(iSubSessions.Count() == 0, Panic(EWinSockPrtSubSessionListNotEmpty));
+ iSubSessions.Close();
+ }
+
+CWin32Session::CWin32Session(TWin32Request& aRequest, CWin32Scheduler& aScheduler)
+ : CWin32ActiveObject(aScheduler), iRequest(aRequest)
+ {
+ }
+
+void CWin32Session::ConstructL()
+ {
+ CWin32ActiveObject::ConstructL();
+ iRequest.SetEventHandle(iEvent);
+ }
+
+void CWin32Session::Run()
+ {
+ TInt err = KErrNone;
+
+ CWin32SubSession* subSession = reinterpret_cast<CWin32SubSession*>(iRequest.SubSession());
+ TWin32Message& message = iRequest.Message();
+ if (subSession == NULL)
+ {
+ switch (message.OppCode())
+ {
+ case EClose:
+ {
+ Close();
+ break;
+ }
+ case ECloseSubSession:
+ {
+ CloseSubSession();
+ break;
+ }
+ default:
+ {
+ // Pass on to sub-class.
+ TRAP(err, ServiceL(message));
+ }
+ }
+ }
+ else
+ {
+ TRAP(err, subSession->ServiceL(message));
+ }
+
+ iRequest.Requested(err);
+ }
+
+void CWin32Session::Close()
+ {
+ // 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.
+ TTime time;
+ time.UniversalTime();
+ const TInt64& int64 = time.Int64();
+ TBuf<64> newThreadName;
+ newThreadName.Format(KWspThreadNameWhilstWaitingForDeath(), int64);
+ User::RenameThread(newThreadName); // Throw away error code.
+ iScheduler.Stop();
+ }
+
+void CWin32Session::CloseSubSession()
+ {
+ TInt handle;
+ TPckg<TInt> handlePckg(handle);
+ handlePckg.Copy(iRequest.Message().ReadBuffer());
+ CWin32SubSession* subSessionToClose = reinterpret_cast<CWin32SubSession*>(handle);
+ TInt pos = iSubSessions.Find(subSessionToClose);
+ __ASSERT_DEBUG(pos >= 0, Panic(EWinSockPrtUnableToFindSubSession));
+ delete subSessionToClose;
+ iSubSessions.Remove(pos);
+ }