/*
 *      Pthreads-win32 - POSIX Threads Library for Win32
 *      Copyright(C) 1998 John E. Bossom
 *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 *      Copyright(C) 2026 mingw-w64 project
 *
 *      Contact Email: mingw-w64-public@lists.sourceforge.net
 *
 *      The current list of contributors is contained
 *      in the file CONTRIBUTORS included with the source
 *      code distribution. The list can also be seen at the
 *      following World Wide Web location:
 *      http://sources.redhat.com/pthreads-win32/contributors.html
 *
 *      This library is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU Lesser General Public
 *      License as published by the Free Software Foundation; either
 *      version 2 of the License, or (at your option) any later version.
 *
 *      This library is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *      Lesser General Public License for more details.
 *
 *      You should have received a copy of the GNU Lesser General Public
 *      License along with this library in the file COPYING.LIB;
 *      if not, write to the Free Software Foundation, Inc.,
 *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include "test.h"

/**
 * Test Summary:
 *
 * Main thread M creates default-type mutex L.
 *
 * Thread A locks L.
 *
 * Thread A attempts to lock L again; this must result in a dead lock.
 *
 * Thread M unlocks and destroys L.
 */

static LONG IsThreadABlocked = FALSE;

static void *ThreadA(void *arg)
{
  pthread_mutex_t *mutex = arg;

  assert(pthread_mutex_lock(mutex) == 0);
  /**
   * Signal thread M that thread A locked L.
   */
  InterlockedExchange(&IsThreadABlocked, TRUE);
  /**
   * Attempt to recursively lock NORMAL mutex must result in a dead lock.
   * Wait for main thread to unlock...
   */
  assert(pthread_mutex_lock(mutex) == 0);
  /**
   * Signal thread M that thread A was unblocked.
   */
  InterlockedExchange(&IsThreadABlocked, FALSE);
  assert(pthread_mutex_unlock(mutex) == 0);

  return arg;
}

int main(void)
{
  pthread_mutex_t mutex;
  pthread_t thread;
  void *result;

  assert(pthread_mutex_init(&mutex, NULL) == 0);
  assert(pthread_create(&thread, NULL, ThreadA, &mutex) == 0);
  /**
   * Wait until thread A locks L.
   */
  while (!IsThreadABlocked) {
    YieldProcessor();
  }
  Sleep(10);
  /**
   * Thread A must be deadlocked.
   */
  assert(IsThreadABlocked);
  /**
   * POSIX states that calling `pthread_mutex_unlock` on NORMAL mutex that is
   * not owned by the calling thread is undefined behavior.
   *
   * Our implementation for NORMAL mutexes does not check ownership at all,
   * so call to `pthread_mutex_unlock` on a valid NORMAL mutex always succeeds.
   */
  do {
    assert(pthread_mutex_unlock(&mutex) == 0);
    YieldProcessor();
  } while (IsThreadABlocked);
  assert(pthread_join (thread, &result) == 0);
  assert(result == &mutex);
  assert(pthread_mutex_destroy(&mutex) == 0);

  return 0;
}
