--- a/hostsupport/hostthreadadapter/group/bld.inf Thu Aug 26 19:08:32 2010 +0100
+++ b/hostsupport/hostthreadadapter/group/bld.inf Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Build meta data for the hostthreadadapter component
+
+PRJ_PLATFORMS
+
+TOOLS2
+
+PRJ_MMPFILES
+
+hostthreadadapter.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostthreadadapter/group/hostthreadadapter.mmp Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// hostthreadadapter library build meta data
+
+TARGET hostthreadadapter.lib
+
+TARGETTYPE lib
+
+SOURCEPATH ../src
+SOURCE platformthreading.cpp
+
+USERINCLUDE ../inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostthreadadapter/inc/hostthreadadapter.h Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Host thread adapter header file
+
+#ifndef HOSTTHREADADAPTER_H
+#define HOSTTHREADADAPTER_H
+
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define _WIN32_WINNT 0x0400
+
+#include "platformthreading.h"
+
+#endif // HOSTTHREADADAPTER
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostthreadadapter/inc/platformthreading.h Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,164 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This header is to create platform independent
+// threading / synchronization API types and values.
+
+#ifndef PSU_PLATFORMTHREADING_H
+#define PSU_PLATFORMTHREADING_H
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#endif
+
+#include "platformtypes.h"
+
+namespace Psu
+{
+
+#ifdef WIN32
+
+ typedef HANDLE PLATFORM_THREAD_T;
+ typedef DWORD PLATFORM_THREADFUNC_RETTYPE;
+ typedef LPTHREAD_START_ROUTINE PLATFORM_THREADFUNC;
+ typedef CRITICAL_SECTION PLATFORM_MUTEX_T;
+ typedef HANDLE PLATFORM_SEMAPHORE_T;
+ typedef DWORD STATUS_T;
+
+#ifdef __GNUG__
+ typedef void (*PLATFORM_INTERRUPT_HANDLER)(ULONG_PTR);
+#else
+ typedef VOID CALLBACK PLATFORM_INTERRUPT_HANDLER (__in ULONG_PTR);
+#endif
+
+#else // LINUX
+
+ typedef pthread_t PLATFORM_THREAD_T;
+ typedef void * PLATFORM_THREADFUNC_RETTYPE;
+ typedef void * (*PLATFORM_THREADFUNC)(void *);
+ typedef pthread_mutex_t PLATFORM_MUTEX_T;
+ typedef sem_t PLATFORM_SEMAPHORE_T;
+ typedef int STATUS_T;
+
+ typedef void (*PLATFORM_INTERRUPT_HANDLER)(int);
+
+#define WINAPI
+
+#endif
+
+#ifndef WIN32
+ extern const int MicrosecsInMillisec;
+#endif
+
+
+ /**
+ * Creates a thread with the default attributes.
+ */
+ int platform_create_simple_thread(PLATFORM_THREAD_T * pThreadHandle,
+ PLATFORM_THREADFUNC pFunc,
+ void * param);
+
+ /**
+ * Releases a thread (does not kill it).
+ */
+ void platform_release_thread(PLATFORM_THREAD_T threadHandle);
+
+ /**
+ * Waits for a thread to terminate.
+ */
+ STATUS_T platform_join_thread(PLATFORM_THREAD_T threadHandle);
+
+ /**
+ * Initializes a mutex (CRITICAL_SECTION on windows).
+ */
+ void platform_mutex_init(PLATFORM_MUTEX_T * pMutex);
+
+ /**
+ * Destroys a mutex (CRITICAL_SECTION on windows).
+ */
+ void platform_mutex_destroy(PLATFORM_MUTEX_T * pMutex);
+
+ /**
+ *Locks a mutex ("enters" a CRITICAL_SECTION on windows).
+ */
+ void platform_mutex_lock(PLATFORM_MUTEX_T * pMutex);
+
+ /**
+ * Unlocks a mutex ("exits" a CRITICAL_SECTION on windows).
+ */
+ void platform_mutex_unlock(PLATFORM_MUTEX_T * pMutex);
+
+
+ /**
+ * Sleeps for a certain duration for given milliseconds.
+ */
+ void platform_sleep(int millisecs);
+
+ /**
+ * Creates a semaphore with the default attributes.
+ */
+ STATUS_T platform_create_semaphore(PLATFORM_SEMAPHORE_T& semHandle,
+ int initialCount,int maximumCount);
+
+
+ /**
+ * wait for the semaphore signal
+ */
+ STATUS_T platform_wait_for_signal(PLATFORM_SEMAPHORE_T& semHandle);
+
+ /**
+ * Posts a semaphore signal so that the pending thread can continue
+ */
+ void platform_signal_semaphore(PLATFORM_SEMAPHORE_T& semHandle);
+
+ /**
+ * releases a semaphore object/handle.
+ */
+ void platform_release_semaphore(PLATFORM_SEMAPHORE_T& semHandle);
+
+ /**
+ * do an interruptable sleep
+ * @param length the length thread should sleep, in milliseconds
+ * @return 0 if the sleep expires normally, non-zero if the sleep has
+ * been interrupted
+ */
+ int32_t platform_interruptable_sleep(int64_t length);
+
+ /**
+ * signals a thread to interrupt a sleep
+ * @param handle PLATFORM_THREAD_T handle to the thread
+ * @return whether the interrupt succeeded or not
+ */
+ bool platform_interrupt_sleep(PLATFORM_THREAD_T handle);
+
+#ifndef WIN32
+ class SignalUSR1Handler
+ {
+ private:
+ SignalUSR1Handler();
+ ~SignalUSR1Handler();
+
+ struct sigaction sa;
+ struct sigaction old;
+
+ public:
+ static SignalUSR1Handler instance;
+ };
+#endif
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostthreadadapter/inc/platformtypes.h Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,90 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Cross platform types
+
+#ifndef PSU_PLATFORMTYPES_H
+#define PSU_PLATFORMTYPES_H
+
+#include <limits.h>
+
+
+#ifdef WIN32
+#define DllExport __declspec( dllexport )
+#else // LINUX
+#define DllExport
+#endif
+
+
+#ifdef WIN32
+
+#if !defined(__STDC_CONSTANT_MACROS) && !defined(HAVE_STDINT_H)
+#define __STDC_CONSTANT_MACROS
+ /* MSVC++ does not have the standard header <stdint.h>, so we need to
+ write here all the declarations that <stdint.h> shall contain */
+#ifndef HAVE_INT8_T
+#define HAVE_INT8_T 1
+ typedef signed __int8 int8_t;
+#endif
+#ifndef HAVE_INT16_T
+#define HAVE_INT16_T 1
+ typedef signed __int16 int16_t;
+#endif
+#ifndef HAVE_INT32_T
+#define HAVE_INT32_T 1
+ typedef signed __int32 int32_t;
+#endif
+#ifndef HAVE_INT64_T
+#define HAVE_INT64_T 1
+ typedef signed __int64 int64_t;
+#endif
+#ifndef HAVE_U_INT8_T
+#define HAVE_U_INT8_T 1
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int8 u_int8_t;
+#endif
+#ifndef HAVE_U_INT16_T
+#define HAVE_U_INT16_T 1
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int16 u_int16_t;
+#endif
+#ifndef HAVE_U_INT32_T
+#define HAVE_U_INT32_T 1
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int32 u_int32_t;
+#endif
+#ifndef HAVE_U_INT64_T
+#define HAVE_U_INT64_T 1
+ typedef unsigned __int64 uint64_t;
+ typedef unsigned __int64 u_int64_t;
+#endif
+
+
+
+// on both Linux and Windows platforms, size_t is a 4-bytes unsigned integer
+// on Linux, ssize_t is a 4 bytes signed integer
+// Windows does not seem to have a ssize_t
+typedef int32_t ssize_t;
+
+#endif // __STDC_CONSTANT_MACROS
+#else
+#include <stdint.h>
+#include <sys/types.h>
+#endif
+
+
+// a byte will be an unsigned char, i.e. an unsigned int8_t
+// this typedef works fine on both Linux and Windows
+typedef unsigned char byte_t;
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostthreadadapter/src/platformthreading.cpp Thu Sep 02 11:20:15 2010 +0100
@@ -0,0 +1,271 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Cross platform threading support library
+
+#include "platformthreading.h"
+
+#ifdef WIN32
+#include <windows.h>
+#include <WinBase.h>
+#else
+#include <unistd.h>
+#include <time.h>
+#include <signal.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef WIN32
+#ifdef __GNUG__
+static void CALLBACK default_interrupt_handler(ULONG_PTR)
+#else // MSVC
+static VOID CALLBACK default_interrupt_handler(__in ULONG_PTR)
+#endif
+#else // LINUX
+static void default_interrupt_handler(int)
+#endif
+{
+ // does nothing
+ ;
+}
+
+namespace Psu
+{
+
+#ifndef WIN32
+ const int MicrosecsInMillisec = 1000;
+#endif
+
+
+ int platform_create_simple_thread(PLATFORM_THREAD_T * pThreadHandle,
+ PLATFORM_THREADFUNC pFunc,
+ void * param)
+ {
+ int
+ rv = 0;
+
+#ifdef WIN32
+ DWORD
+ threadId,
+ stackSize = 0,
+ creationFlags = 0;
+
+ PLATFORM_THREAD_T
+ tmp = CreateThread(NULL,
+ stackSize,
+ pFunc,
+ param,
+ creationFlags,
+ &threadId);
+ if (tmp == NULL)
+ {
+ rv = GetLastError();
+ }
+ else
+ {
+ *pThreadHandle = tmp;
+ }
+#else
+ rv = pthread_create(pThreadHandle,
+ 0,
+ pFunc,
+ param);
+#endif
+
+ return rv;
+ }
+
+
+ void platform_release_thread(PLATFORM_THREAD_T threadHandle)
+ {
+#ifdef WIN32
+ CloseHandle(threadHandle);
+#else
+ pthread_detach(threadHandle);
+#endif
+ }
+
+
+ STATUS_T platform_join_thread(PLATFORM_THREAD_T threadHandle)
+ {
+ STATUS_T retVal;
+#ifdef WIN32
+
+ retVal = WaitForSingleObject(threadHandle,INFINITE);
+#else
+ retVal = pthread_join(threadHandle, NULL);
+#endif
+ return retVal;
+ }
+
+
+ void platform_mutex_init(PLATFORM_MUTEX_T * pMutex)
+ {
+#ifdef WIN32
+ InitializeCriticalSection(pMutex);
+#else
+ pthread_mutex_init(pMutex,
+ 0);
+#endif
+ }
+
+
+ void platform_mutex_destroy(PLATFORM_MUTEX_T * pMutex)
+ {
+#ifdef WIN32
+ DeleteCriticalSection(pMutex);
+#else
+ pthread_mutex_destroy(pMutex);
+#endif
+ }
+
+
+ void platform_mutex_lock(PLATFORM_MUTEX_T * pMutex)
+ {
+#ifdef WIN32
+ EnterCriticalSection(pMutex);
+#else
+ pthread_mutex_lock(pMutex);
+#endif
+ }
+
+
+ void platform_mutex_unlock(PLATFORM_MUTEX_T * pMutex)
+ {
+#ifdef WIN32
+ LeaveCriticalSection(pMutex);
+#else
+ pthread_mutex_unlock(pMutex);
+#endif
+ }
+
+
+ void platform_sleep(int millisecs)
+ {
+#ifdef WIN32
+ Sleep(millisecs);
+#else
+ usleep(millisecs * MicrosecsInMillisec);
+#endif
+ }
+
+
+ STATUS_T platform_create_semaphore(PLATFORM_SEMAPHORE_T& semHandle,
+ int initialCount,int maximumCount)
+ {
+
+ STATUS_T rv =0;
+#ifdef WIN32
+
+ PLATFORM_SEMAPHORE_T
+ tmp = CreateSemaphore(NULL,
+ initialCount,
+ maximumCount,
+ NULL);
+ if (tmp == NULL)
+ {
+ rv = GetLastError();
+ }
+ else
+ {
+ semHandle = tmp;
+ }
+#else
+ rv = sem_init(&semHandle,
+ 0,
+ initialCount);
+#endif
+
+ return rv;
+ }
+
+
+ STATUS_T platform_wait_for_signal(PLATFORM_SEMAPHORE_T& semHandle)
+ {
+ STATUS_T retVal;
+#ifdef WIN32
+
+ retVal = WaitForSingleObject(semHandle, INFINITE);
+#else
+ retVal = sem_wait(&semHandle);
+#endif
+ return retVal;
+ }
+
+
+ void platform_signal_semaphore(PLATFORM_SEMAPHORE_T& semHandle)
+ {
+#ifdef WIN32
+ ReleaseSemaphore(semHandle, 1, NULL);
+#else
+ sem_post(&semHandle);
+#endif
+ }
+
+ void platform_release_semaphore(PLATFORM_SEMAPHORE_T& semHandle)
+ {
+#ifdef WIN32
+
+ CloseHandle(semHandle);
+#else
+
+ sem_destroy(&semHandle);
+#endif
+ }
+
+ int32_t platform_interruptable_sleep(int64_t length)
+ {
+#ifdef WIN32
+ return SleepEx(static_cast<DWORD>(length), TRUE);
+#else
+ struct timespec req = {0};
+ time_t sec = (int)(length/1000);
+ length = length - (sec*1000);
+ req.tv_sec = sec;
+ req.tv_nsec = length*1000000L;
+
+ int ret = nanosleep(&req, NULL);
+
+ return ret;
+#endif
+ }
+
+ bool platform_interrupt_sleep(PLATFORM_THREAD_T handle)
+ {
+#ifdef WIN32
+ int32_t result = QueueUserAPC(default_interrupt_handler, handle, 0);
+
+ return (result!=0);
+#else
+ return (0 == pthread_kill(handle, SIGUSR1));
+#endif
+ }
+
+#ifndef WIN32
+ SignalUSR1Handler SignalUSR1Handler::instance;
+
+ SignalUSR1Handler::SignalUSR1Handler()
+ {
+ //sa = {0}, old = {0};
+ sa.sa_handler = &default_interrupt_handler;
+ sigaction(SIGUSR1, &sa, &old);
+ }
+
+ SignalUSR1Handler::~SignalUSR1Handler()
+ {
+ sigaction(SIGUSR1, &old, NULL);
+ }
+#endif
+
+}