/* Copyright (c) 2011 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef PPAPI_TESTS_PP_THREAD_H_
#define PPAPI_TESTS_PP_THREAD_H_

#include "ppapi/c/pp_macros.h"
#include "ppapi/tests/test_utils.h"

#if defined(PPAPI_POSIX)
#include <pthread.h>
#elif defined(PPAPI_OS_WIN)
#include <process.h>
#include <windows.h>
#else
#error No thread library detected.
#endif

/**
 * @file
 * This file provides platform-independent wrappers around threads. This is for
 * use by PPAPI wrappers and tests which need to run on multiple platforms to
 * support both trusted platforms (Windows, Mac, Linux) and untrusted (Native
 * Client). Apps that use PPAPI only with Native Client should generally use the
 * Native Client POSIX implementation instead.
 *
 * TODO(dmichael): Move this file to ppapi/c and delete this comment, if we end
 * up needing platform independent threads in PPAPI C or C++. This file was
 * written using inline functions and PPAPI naming conventions with the intent
 * of making it possible to put it in to ppapi/c. Currently, however, it's only
 * used in ppapi/tests, so is not part of the published API.
 */

typedef void (PP_ThreadFunction)(void* data);

#if defined(PPAPI_POSIX)
typedef pthread_t PP_Thread;
#elif defined(PPAPI_OS_WIN)
struct PP_Thread {
  HANDLE handle;
  PP_ThreadFunction* thread_func;
  void* thread_arg;
};
#endif

PP_INLINE bool PP_CreateThread(PP_Thread* thread,
                               PP_ThreadFunction function,
                               void* thread_arg);
PP_INLINE void PP_JoinThread(PP_Thread thread);

#if defined(PPAPI_POSIX)
/* Because POSIX thread functions return void* and Windows thread functions do
 * not, we make PPAPI thread functions have the least capability (no returns).
 * This struct wraps the user data & function so that we can use the correct
 * function type on POSIX platforms.
 */
struct PP_ThreadFunctionArgWrapper {
  void* user_data;
  PP_ThreadFunction* user_function;
};

PP_INLINE void* PP_POSIXThreadFunctionThunk(void* posix_thread_arg) {
  PP_ThreadFunctionArgWrapper* arg_wrapper =
      (PP_ThreadFunctionArgWrapper*)posix_thread_arg;
  arg_wrapper->user_function(arg_wrapper->user_data);
  free(posix_thread_arg);
  return NULL;
}

PP_INLINE bool PP_CreateThread(PP_Thread* thread,
                               PP_ThreadFunction function,
                               void* thread_arg) {
  PP_ThreadFunctionArgWrapper* arg_wrapper =
      (PP_ThreadFunctionArgWrapper*)malloc(sizeof(PP_ThreadFunctionArgWrapper));
  arg_wrapper->user_function = function;
  arg_wrapper->user_data = thread_arg;
  return (pthread_create(thread,
                         NULL,
                         PP_POSIXThreadFunctionThunk,
                         arg_wrapper) == 0);
}

PP_INLINE void PP_JoinThread(PP_Thread thread) {
  void* exit_status;
  pthread_join(thread, &exit_status);
}

#elif defined(PPAPI_OS_WIN)

PP_INLINE unsigned __stdcall PP_WindowsThreadFunction(void* param) {
  PP_Thread* thread = reinterpret_cast<PP_Thread*>(param);
  thread->thread_func(thread->thread_arg);
  return 0;
}

PP_INLINE bool PP_CreateThread(PP_Thread* thread,
                               PP_ThreadFunction function,
                               void* thread_arg) {
  if (!thread)
    return false;
  thread->thread_func = function;
  thread->thread_arg = thread_arg;
  uintptr_t raw_handle = ::_beginthreadex(NULL,
                                          0,  /* Use default stack size. */
                                          &PP_WindowsThreadFunction,
                                          thread,
                                          0,
                                          NULL);
  thread->handle = reinterpret_cast<HANDLE>(raw_handle);
  return (thread->handle != NULL);
}

PP_INLINE void PP_JoinThread(PP_Thread thread) {
  ::WaitForSingleObject(thread.handle, INFINITE);
  ::CloseHandle(thread.handle);
}

#endif


/**
 * @}
 */

#endif  /* PPAPI_TESTS_PP_THREAD_H_ */

