Пример #1
0
err_t submit_socket_request(struct socket *s, struct sockreq *req, int type, struct msghdr *msg, unsigned int timeout) {
  struct timer timer;
  int rc;

  if (timeout == 0) return -ETIMEOUT;

  req->socket = s;
  req->thread = self();
  req->type = type;
  req->msg = msg;
  req->rc = 0;

  req->next = NULL;
  req->prev = s->waittail;
  if (s->waittail) s->waittail->next = req;
  s->waittail = req;
  if (!s->waithead) s->waithead = req;

  if (timeout != INFINITE) {
    init_timer(&timer, socket_timeout, req);
    timer.expires = ticks + timeout / MSECS_PER_TICK;
    add_timer(&timer);
  }

  rc = enter_alertable_wait(THREAD_WAIT_SOCKET);
  if (rc < 0) {
    cancel_socket_request(req);
    req->rc = rc;
  }

  if (timeout != INFINITE) del_timer(&timer);

  return req->rc;
}
Пример #2
0
DWORD
mono_win32_sleep_ex (DWORD timeout, BOOL alertable)
{
	DWORD result = WAIT_FAILED;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = SleepEx (timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	return result;
}
Пример #3
0
DWORD
mono_win32_wsa_wait_for_multiple_events (DWORD count, const WSAEVENT FAR *handles, BOOL waitAll, DWORD timeout, BOOL alertable)
{
	DWORD result = WAIT_FAILED;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = WSAWaitForMultipleEvents (count, handles, waitAll, timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	return result;
}
Пример #4
0
DWORD
mono_win32_signal_object_and_wait (HANDLE toSignal, HANDLE toWait, DWORD timeout, BOOL alertable)
{
	DWORD result = WAIT_FAILED;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = SignalObjectAndWait (toSignal, toWait, timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	return result;
}
Пример #5
0
DWORD
mono_win32_msg_wait_for_multiple_objects_ex (DWORD count, CONST HANDLE *handles, DWORD timeout, DWORD wakeMask, DWORD flags)
{
	DWORD result = WAIT_FAILED;
	BOOL alertable = flags & MWMO_ALERTABLE;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = MsgWaitForMultipleObjectsEx (count, handles, timeout, wakeMask, flags);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	return result;
}
Пример #6
0
DWORD
mono_win32_wait_for_single_object_ex (HANDLE handle, DWORD timeout, BOOL alertable)
{
	DWORD result = WAIT_FAILED;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = WaitForSingleObjectEx (handle, timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (alertable && info) {
		leave_alertable_wait (info);
	}

	return result;
}
Пример #7
0
DWORD
mono_win32_wait_for_multiple_objects_ex (DWORD count, CONST HANDLE *handles, BOOL waitAll, DWORD timeout, BOOL alertable, MonoError *error)
{
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	DWORD const result = WaitForMultipleObjectsEx (count, handles, waitAll, timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	// This is not perfect, but it is the best you can do in usermode and matches CoreCLR.
	// i.e. handle-based instead of object-based.

	if (result == WAIT_FAILED && waitAll && error &&
			count > 1 && count <= MAXIMUM_WAIT_OBJECTS
			&& GetLastError () == ERROR_INVALID_PARAMETER) {
		gpointer handles_sorted [MAXIMUM_WAIT_OBJECTS]; // 64
		memcpy (handles_sorted, handles, count * sizeof (handles [0]));
		qsort (handles_sorted, count, sizeof (handles_sorted [0]), g_direct_equal);
		for (DWORD i = 1; i < count; ++i) {
			if (handles_sorted [i - 1] == handles_sorted [i]) {
				mono_error_set_duplicate_wait_object (error);
				mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_HANDLE, "%s: handle %p is duplicated", __func__, handles_sorted [i]);
				// Preserve LastError, but reduce triggering write breakpoints.
				if (GetLastError () != ERROR_INVALID_PARAMETER)
					SetLastError (ERROR_INVALID_PARAMETER);
				break;
			}
		}
	}

	return result;
}