/* Copyright (c) 2015, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "internal.h"

#include <stdio.h>


#if !defined(OPENSSL_NO_THREADS)

#if defined(OPENSSL_WINDOWS)

OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))

typedef HANDLE thread_t;

static DWORD WINAPI thread_run(LPVOID arg) {
  void (*thread_func)(void);
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&thread_func, &arg, sizeof(thread_func));
  thread_func();
  return 0;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  void *arg;
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&arg, &thread_func, sizeof(arg));

  *out_thread = CreateThread(NULL /* security attributes */,
                             0 /* default stack size */, thread_run, arg,
                             0 /* run immediately */, NULL /* ignore id */);
  return *out_thread != NULL;
}

static int wait_for_thread(thread_t thread) {
  return WaitForSingleObject(thread, INFINITE) == 0;
}

#else

#include <pthread.h>
#include <string.h>
#include <time.h>

typedef pthread_t thread_t;

static void *thread_run(void *arg) {
  void (*thread_func)(void) = arg;
  thread_func();
  return NULL;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  return pthread_create(out_thread, NULL /* default attributes */, thread_run,
                        thread_func) == 0;
}

static int wait_for_thread(thread_t thread) {
  return pthread_join(thread, NULL) == 0;
}

#endif  /* OPENSSL_WINDOWS */

static unsigned g_once_init_called = 0;

static void once_init(void) {
  g_once_init_called++;

  /* Sleep briefly so one |call_once_thread| instance will call |CRYPTO_once|
   * while the other is running this function. */
#if defined(OPENSSL_WINDOWS)
  Sleep(1 /* milliseconds */);
#else
  struct timespec req;
  OPENSSL_memset(&req, 0, sizeof(req));
  req.tv_nsec = 1000000;
  nanosleep(&req, NULL);
#endif
}

static CRYPTO_once_t g_test_once = CRYPTO_ONCE_INIT;

static void call_once_thread(void) {
  CRYPTO_once(&g_test_once, once_init);
}

static int test_once(void) {
  if (g_once_init_called != 0) {
    fprintf(stderr, "g_once_init_called was non-zero at start.\n");
    return 0;
  }

  thread_t thread1, thread2;
  if (!run_thread(&thread1, call_once_thread) ||
      !run_thread(&thread2, call_once_thread) ||
      !wait_for_thread(thread1) ||
      !wait_for_thread(thread2)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  CRYPTO_once(&g_test_once, once_init);

  if (g_once_init_called != 1) {
    fprintf(stderr, "Expected init function to be called once, but found %u.\n",
            g_once_init_called);
    return 0;
  }

  return 1;
}


static int g_test_thread_ok = 0;
static unsigned g_destructor_called_count = 0;

static void thread_local_destructor(void *arg) {
  if (arg == NULL) {
    return;
  }

  unsigned *count = arg;
  (*count)++;
}

static void thread_local_test_thread(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    return;
  }

  if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_TEST,
                               &g_destructor_called_count,
                               thread_local_destructor)) {
    return;
  }

  if (CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST) !=
      &g_destructor_called_count) {
    return;
  }

  g_test_thread_ok = 1;
}

static void thread_local_test2_thread(void) {}

static int test_thread_local(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    fprintf(stderr, "Thread-local data was non-NULL at start.\n");
  }

  thread_t thread;
  if (!run_thread(&thread, thread_local_test_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  if (!g_test_thread_ok) {
    fprintf(stderr, "Thread-local data didn't work in thread.\n");
    return 0;
  }

  if (g_destructor_called_count != 1) {
    fprintf(stderr,
            "Destructor should have been called once, but actually called %u "
            "times.\n",
            g_destructor_called_count);
    return 0;
  }

  /* thread_local_test2_thread doesn't do anything, but it tests that the
   * thread destructor function works even if thread-local storage wasn't used
   * for a thread. */
  if (!run_thread(&thread, thread_local_test2_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  return 1;
}

int main(int argc, char **argv) {
  if (!test_once() ||
      !test_thread_local()) {
    return 1;
  }

  printf("PASS\n");
  return 0;
}

#else  /* OPENSSL_NO_THREADS */

int main(int argc, char **argv) {
  printf("PASS\n");
  return 0;
}

#endif
