Exemple #1
0
static int
ktimer_delete(struct filter *filt, struct knote *kn)
{

    if (kn->data.handle == NULL || kn->kn_event_whandle == NULL)
        return (0);

    if(!UnregisterWaitEx(kn->kn_event_whandle, INVALID_HANDLE_VALUE)) {
        dbg_lasterror("UnregisterWait()");
        return (-1);
    }

    if (!CancelWaitableTimer(kn->data.handle)) {
        dbg_lasterror("CancelWaitableTimer()");
        return (-1);
    }
    if (!CloseHandle(kn->data.handle)) {
        dbg_lasterror("CloseHandle()");
        return (-1);
    }

    if( !(kn->kev.flags & EV_ONESHOT) )
        knote_release(kn);

    kn->data.handle = NULL;
    return (0);
}
DirectoryWinAPI::~DirectoryWinAPI()
{
	for(auto it = callbacks.begin(); it != callbacks.end(); ++it)
	{
		UnregisterWaitEx(it->second.waitHandle,  INVALID_HANDLE_VALUE);
		FindCloseChangeNotification(it->first);
		delete it->second.cb;
	}
}
Exemple #3
0
void CEXIETHERNET::RecvStop()
{
	if (!IsActivated())
		return;

	UnregisterWaitEx(mHReadWait, INVALID_HANDLE_VALUE);

	CloseHandle(mHRecvEvent);
	mHRecvEvent = INVALID_HANDLE_VALUE;
}
Exemple #4
0
/*
 * Disconnect, but do not close, a pipe handle; and deregister
 * any pending waiter threads from its event handles.
 *
 * XXX: This must be called from primary thread, or lock held if not!
 */
void
pipe_disconnect(pipe_instance_t *pp)
{

    TRACE0(ENTER, "Entering pipe_disconnect");

    if (pp == NULL)
	return;
    /*
     * Cancel pending I/O before deregistering the callback,
     * and disconnect the pipe, to avoid race conditions.
     * We also reset the event(s) to avoid being signalled for
     * things which haven't actually happened yet.
     *
     * XXX: To avoid races during shutdown, we may have to
     * NULL out the second argument to UnregisterWaitEx().
     * We can't, however, do that from a service thread.
     */
    if (pp->cwait != NULL) {
        UnregisterWaitEx(pp->cwait, pp->cevent);
	ResetEvent(pp->cevent);
	pp->cwait = NULL;
    }
    if (pp->rwait != NULL) {
        UnregisterWaitEx(pp->rwait, pp->revent);
	ResetEvent(pp->revent);
	pp->rwait = NULL;
    }

    if (pp->pipe != NULL) {
        CancelIo(pp->pipe);
	if (pp->state == PIPE_STATE_CONNECTED ||
	    pp->state == PIPE_STATE_LISTEN) {
	    DisconnectNamedPipe(pp->pipe);
	}
    }

    pp->state = PIPE_STATE_INIT;

    TRACE0(ENTER, "Leaving pipe_disconnect");
}
Exemple #5
0
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
    UnregisterWaitEx(handle->wait_handle, handle->close_handle);
    handle->wait_handle = NULL;

    RegisterWaitForSingleObject(&handle->wait_handle, handle->close_handle,
        close_wait_callback, (void*)handle, INFINITE,
        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
  } else {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}
Exemple #6
0
static PyObject *
overlapped_UnregisterWaitEx(PyObject *self, PyObject *args)
{
    HANDLE WaitHandle, Event;
    BOOL ret;

    if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event))
        return NULL;

    Py_BEGIN_ALLOW_THREADS
    ret = UnregisterWaitEx(WaitHandle, Event);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}
Exemple #7
0
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
  uv__handle_start(handle);

  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    /* This blocks until either the wait was cancelled, or the callback has */
    /* completed. */
    BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
    if (!r) {
      /* This should never happen, and if it happens, we can't recover... */
      uv_fatal_error(GetLastError(), "UnregisterWaitEx");
    }

    handle->wait_handle = INVALID_HANDLE_VALUE;
  }

  if (!handle->exit_cb_pending) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}
Exemple #8
0
/* This code gets executed when a child process is terminated. */
void WINAPI deadChildProcCallBack(
    PVOID          lpParameter,
    BOOLEAN        timeoutHappened)
{
    DeadChildInfo  childInfo = (DeadChildInfo)lpParameter;
    DWORD          exitcode;

    if (timeoutHappened)  /* Timeout happened. */
        return;

    /* Unregister the wait handler. */
    UnregisterWaitEx(childInfo->waitHandle, NULL);

    /* Retrieves the termination status of the specified process. */
    if (!GetExitCodeProcess(childInfo->procHandle, &exitcode))
    {
        fprintf(stderr, "could not read exit code for process\n");
        exitcode = 255;
    }
}
bool ObjectWatcher::StopWatching() {
  if (!wait_object_)
    return false;

  // Make sure ObjectWatcher is used in a single-threaded fashion.
  assert(origin_loop_ == MessageLoop::current());

  // Blocking call to cancel the wait. Any callbacks already in progress will
  // finish before we return from this call.
  if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {
    return false;
  }

  signal_weakflag_.Cancel();
  object_ = NULL;
  wait_object_ = NULL;

  MessageLoop::current()->RemoveDestructionObserver(this);
  return true;
}
Exemple #10
0
		bool ObjectWatcher::StopWatching() {
			if (!wait_object_)
				return false;

			// Make sure ObjectWatcher is used in a single-threaded fashion.
			DCHECK_EQ(origin_loop_, MessageLoop::current());

			// Blocking call to cancel the wait. Any callbacks already in progress will
			// finish before we return from this call.
			if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {
				DPLOG(FATAL) << "UnregisterWaitEx failed";
				return false;
			}

			weak_factory_.InvalidateWeakPtrs();
			object_ = NULL;
			wait_object_ = NULL;

			MessageLoop::current()->RemoveDestructionObserver(this);
			return true;
		}
//-----------------------------------------------------------------------------
// Function:    PeoplePickerModelDestroy
//
// Purpose:     Frees up all the resources needed by the model
//              
// Returns:        VOID
//
VOID PeoplePickerModelDestroy()
{
    UnregisterWaitEx(g_hModelWaitObject,INVALID_HANDLE_VALUE);
    PeerCollabUnregisterEvent(g_hModelPeerEvent);
    CloseHandle(g_hModelEvent);
}
Exemple #12
0
/* callback from ares when socket operation is started */
static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
    int write) {
  /* look to see if we have a handle for this socket in our list */
  uv_loop_t* loop = (uv_loop_t*) data;
  uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(loop, sock);

  if (read == 0 && write == 0) {
    /* if read and write are 0, cleanup existing data */
    /* The code assumes that c-ares does a callback with read = 0 and */
    /* write = 0 when the socket is closed. After we receive this we stop */
    /* monitoring the socket. */
    if (uv_handle_ares != NULL) {
      uv_req_t* uv_ares_req;

      uv_handle_ares->h_close_event = CreateEvent(NULL, FALSE, FALSE, NULL);
      /* remove Wait */
      if (uv_handle_ares->h_wait) {
        UnregisterWaitEx(uv_handle_ares->h_wait,
                         uv_handle_ares->h_close_event);
        uv_handle_ares->h_wait = NULL;
      }

      /* detach socket from the event */
      WSAEventSelect(sock, NULL, 0);
      if (uv_handle_ares->h_event != WSA_INVALID_EVENT) {
        WSACloseEvent(uv_handle_ares->h_event);
        uv_handle_ares->h_event = WSA_INVALID_EVENT;
      }
      /* remove handle from list */
      uv_remove_ares_handle(uv_handle_ares);

      /* Post request to cleanup the Task */
      uv_ares_req = &uv_handle_ares->ares_req;
      uv_req_init(loop, uv_ares_req);
      uv_ares_req->type = UV_ARES_CLEANUP_REQ;
      uv_ares_req->data = uv_handle_ares;

      /* post ares done with socket - finish cleanup when all threads done. */
      POST_COMPLETION_FOR_REQ(loop, uv_ares_req);
    } else {
      assert(0);
      uv_fatal_error(ERROR_INVALID_DATA, "ares_SockStateCB");
    }
  } else {
    if (uv_handle_ares == NULL) {
      /* setup new handle */
      /* The code assumes that c-ares will call us when it has an open socket.
        We need to call into c-ares when there is something to read,
        or when it becomes writable. */
      uv_handle_ares = (uv_ares_task_t*)malloc(sizeof(uv_ares_task_t));
      if (uv_handle_ares == NULL) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
      }
      uv_handle_ares->type = UV_ARES_TASK;
      uv_handle_ares->close_cb = NULL;
      uv_handle_ares->loop = loop;
      uv_handle_ares->data = loop;
      uv_handle_ares->sock = sock;
      uv_handle_ares->h_wait = NULL;
      uv_handle_ares->flags = 0;

      /* create an event to wait on socket signal */
      uv_handle_ares->h_event = WSACreateEvent();
      if (uv_handle_ares->h_event == WSA_INVALID_EVENT) {
        uv_fatal_error(WSAGetLastError(), "WSACreateEvent");
      }

      /* tie event to socket */
      if (SOCKET_ERROR == WSAEventSelect(sock,
                                         uv_handle_ares->h_event,
                                         FD_READ | FD_WRITE | FD_CONNECT)) {
        uv_fatal_error(WSAGetLastError(), "WSAEventSelect");
      }

      /* add handle to list */
      uv_add_ares_handle(loop, uv_handle_ares);
      uv_ref(loop);

      /*
       * we have a single polling timer for all ares sockets.
       * This is preferred to using ares_timeout. See ares_timeout.c warning.
       * if timer is not running start it, and keep socket count
       */
      if (loop->ares_active_sockets == 0) {
        uv_timer_init(loop, &loop->ares_polling_timer);
        uv_timer_start(&loop->ares_polling_timer, uv_ares_poll, 1000L, 1000L);
      }
      loop->ares_active_sockets++;

      /* specify thread pool function to call when event is signaled */
      if (RegisterWaitForSingleObject(&uv_handle_ares->h_wait,
                                  uv_handle_ares->h_event,
                                  uv_ares_socksignal_tp,
                                  (void*)uv_handle_ares,
                                  INFINITE,
                                  WT_EXECUTEINWAITTHREAD) == 0) {
        uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
      }
    } else {
      /* found existing handle.  */
      assert(uv_handle_ares->type == UV_ARES_TASK);
      assert(uv_handle_ares->data != NULL);
      assert(uv_handle_ares->h_event != WSA_INVALID_EVENT);
    }
  }
}
Exemple #13
0
void WINAPI
pipe_reread_cb(void *ctx)
{
    pipe_instance_t *pp;
    DWORD result;
    int failed;

    pp = (pipe_instance_t *)ctx;
    EnterCriticalSection(&pp->rcs);
    TRACE1(ENTER, "Entering pipe_reread_cb %p", ctx);

    failed = 0;

    if (pp->state != PIPE_STATE_CONNECTED) {
	TRACE0(NETWORK, "WARNING: not PIPE_STATE_CONNECTED");
    }

    /*
     * Tear down and wire up read thread callback again.
     * This is probably inefficient.
     */
    UnregisterWaitEx(pp->rwait, pp->revent);
    ResetEvent(pp->revent); /* XXX ReadFile() should do this for us? */
    pp->rwait = NULL;
    /*
     * Post a new read request. Deal with fatal errors.
     */
    result = ReadFile(pp->pipe, pp->rbuf, pp->rsize, NULL, &pp->rov);
    if (result == 0) {
	result = GetLastError();
	if (result != ERROR_IO_PENDING) {
	    TRACE1(ANY, "WARNING: pipe_reread_cb read returned %d", result);
	}
	if (result == ERROR_BROKEN_PIPE) {
	    failed = 1;
	    goto fail;
	}
    }
    /*
     * Now, and only now, do we kick off the read thread, in order
     * to avoid being preempted if the client disconnects.
     */
    result = RegisterWaitForSingleObject(&(pp->rwait), pp->revent,
					 pipe_read_cb, pp, INFINITE,
					 WT_EXECUTEINIOTHREAD |
					 WT_EXECUTEONLYONCE);
    if (result == 0) {
	result = GetLastError();
	TRACE1(CONFIGURATION, "Error %u RegisterWaitForSingleObject()", result);
	failed = 1;
    }

  fail:
    /*
     * If a fatal error occurred, disconnect the pipe client, and
     * listen for a new connection on this instance.
     */
    if (failed) {
	ResetEvent(pp->revent);
	QueueUserWorkItem(
	    (LPTHREAD_START_ROUTINE)pipe_relisten_cb, (PVOID)pp, WT_EXECUTEINIOTHREAD);
    }
  out:
    TRACE0(ENTER, "Leaving pipe_reread_cb");
    LeaveCriticalSection(&pp->rcs);
}
Exemple #14
0
/*
 * XXX: This must be called from primary thread, or lock held if not!
 */
int
pipe_listen(pipe_instance_t *pp)
{
    int retval;
    DWORD result;

    retval = -1;

    TRACE1(ENTER, "Entering pipe_listen %p", pp);

    if (pp == NULL || pp->state != PIPE_STATE_INIT)
	return (retval);

    /*
     * Register a pool thread to wait for pipe connection.
     * Clear event state to avoid spurious signals.
     */
    ResetEvent(pp->cevent);
    result = RegisterWaitForSingleObject(&(pp->cwait), pp->cevent,
					 pipe_connect_cb, pp, INFINITE,
					 WT_EXECUTEINIOTHREAD |
					 WT_EXECUTEONLYONCE);
    if (result == 0) {
	result = GetLastError();
	TRACE1(CONFIGURATION, "Error %u RegisterWaitForSingleObject()", result);
	goto fail;
    }

    /*
     * Register a pool thread to wait for data to be received on the pipe.
     * We don't cause this to be activated until we post a read request
     * from within the connection callback.
     * XXX: We want the read callback to be called whenever the
     * object is signalled, not just once.
     */
    ResetEvent(pp->revent);
    result = RegisterWaitForSingleObject(&(pp->rwait), pp->revent,
					 pipe_read_cb, pp, INFINITE,
					 WT_EXECUTEINIOTHREAD |
					 WT_EXECUTEONLYONCE);
    if (result == 0) {
	result = GetLastError();
	TRACE1(CONFIGURATION, "Error %u RegisterWaitForSingleObject()", result);
	goto fail;
    }

    /*
     * Post the connection request. If it returns non-zero, then the
     * connection attempt is pending and the thread will be signalled
     * when complete. If it returns zero, then there's a problem.
     * ERROR_NO_DATA means the client disconnected, but we didn't
     * call DisconnectNamedPipe().
     * ConnectNamedPipe() does not reset the event object associated
     * with the OVERLAPPED parameter.
     */
    result = ConnectNamedPipe(pp->pipe, &pp->cov);
    if (result == 0) {
	result = GetLastError();
	if (result == ERROR_PIPE_LISTENING) {
	    TRACE0(NETWORK, "Error: listening; Reconnecting named pipe");
	    result = ConnectNamedPipe(pp->pipe, &pp->cov);
	}
	if (result == ERROR_PIPE_CONNECTED) {
	    TRACE0(NETWORK, "Error: named pipe already connected");
	    goto fail;
	}
	if (result == ERROR_NO_DATA) {
	    TRACE0(NETWORK, "Error: previous session not cleaned up");
	    goto fail;
	}
    }

    pp->state = PIPE_STATE_LISTEN;

    retval = 0;
  fail:
    if (retval == -1) {
	if (pp->cwait != NULL) {
	    UnregisterWaitEx(pp->cwait, pp->cevent);
	    ResetEvent(pp->cevent);
	    pp->cwait = NULL;
	}
	if (pp->rwait != NULL) {
	    UnregisterWaitEx(pp->rwait, pp->revent);
	    ResetEvent(pp->revent);
	    pp->rwait = NULL;
	}
    }
    TRACE1(ENTER, "Leaving pipe_listen", pp);
    return (retval);
}