/* cygwait.h

   This file is part of Cygwin.

   This software is a copyrighted work licensed under the terms of the
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
   details.  */

#include "winsup.h"
#include "sigproc.h"
#include "cygwait.h"
#include "ntdll.h"

#define is_cw_cancel		(mask & cw_cancel)
#define is_cw_cancel_self	(mask & cw_cancel_self)
#define is_cw_sig		(mask & cw_sig)
#define is_cw_sig_eintr		(mask & cw_sig_eintr)
#define is_cw_sig_cont		(mask & cw_sig_cont)
#define is_cw_sig_restart	(mask & cw_sig_restart)

#define is_cw_sig_handle	(mask & (cw_sig | cw_sig_eintr \
					 | cw_sig_cont | cw_sig_restart))

LARGE_INTEGER cw_nowait_storage;

DWORD
cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
{
  DWORD res;
  DWORD num = 0;
  HANDLE wait_objects[4];
  pthread_t thread = pthread::self ();

  /* Do not change the wait order.
     The object must have higher priority than the cancel event,
     because WaitForMultipleObjects will return the smallest index
     if both objects are signaled. */
  if (object)
    wait_objects[num++] = object;

  wait_signal_arrived thread_waiting (is_cw_sig_handle, wait_objects[num]);
  debug_only_printf ("object %p, thread waiting %d, signal_arrived %p", object, (int) thread_waiting, _my_tls.signal_arrived);
  DWORD sig_n;
  if (!thread_waiting)
    sig_n = WAIT_TIMEOUT + 1;
  else
    sig_n = WAIT_OBJECT_0 + num++;

  DWORD cancel_n;
  if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
      thread->cancelstate == PTHREAD_CANCEL_DISABLE)
    cancel_n = WAIT_TIMEOUT + 1;
  else
    {
      cancel_n = WAIT_OBJECT_0 + num++;
      wait_objects[cancel_n] = thread->cancel_event;
    }

  DWORD timeout_n;
  if (!timeout)
    timeout_n = WAIT_TIMEOUT + 1;
  else
    {
      timeout_n = WAIT_OBJECT_0 + num++;
      if (!_my_tls.locals.cw_timer)
	NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
		       NotificationTimer);
      NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
      wait_objects[timeout_n] = _my_tls.locals.cw_timer;
    }

  while (1)
    {
      res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
      debug_only_printf ("res %d", res);
      if (res == cancel_n)
	res = WAIT_CANCELED;
      else if (res == timeout_n)
	res = WAIT_TIMEOUT;
      else if (res != sig_n)
	/* all set */;
      else
	{
	  int sig = _my_tls.sig;
	  if (is_cw_sig_cont && sig == SIGCONT)
	    _my_tls.sig = 0;
	  if (!sig)
	    continue;
	  if (is_cw_sig_eintr || (is_cw_sig_cont && sig == SIGCONT))
	    ;
	  else if (_my_tls.call_signal_handler () || is_cw_sig_restart)
	    continue;
	  res = WAIT_SIGNALED;	/* caller will deal with signals */
	}
      break;
    }

  if (timeout)
    {
      TIMER_BASIC_INFORMATION tbi;

      NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
		    sizeof tbi, NULL);
      /* if timer expired, TimeRemaining is negative and represents the
	  system uptime when signalled */
      if (timeout->QuadPart < 0LL)
	timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
      NtCancelTimer (_my_tls.locals.cw_timer, NULL);
    }

  if (res == WAIT_CANCELED && is_cw_cancel_self)
    pthread::static_cancel_self ();

  return res;
}
