Alien-uv

 view release on metacpan or  search on metacpan

libuv/src/win/signal.c  view on Meta::CPAN

}


int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
  uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
  handle->pending_signum = 0;
  handle->signum = 0;
  handle->signal_cb = NULL;

  UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ);
  handle->signal_req.data = handle;

  return 0;
}


int uv_signal_stop(uv_signal_t* handle) {
  uv_signal_t* removed_handle;

  /* If the watcher wasn't started, this is a no-op. */
  if (handle->signum == 0)
    return 0;

  EnterCriticalSection(&uv__signal_lock);

  removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
  assert(removed_handle == handle);

  LeaveCriticalSection(&uv__signal_lock);

  handle->signum = 0;
  uv__handle_stop(handle);

  return 0;
}


int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
  return uv__signal_start(handle, signal_cb, signum, 0);
}


int uv_signal_start_oneshot(uv_signal_t* handle,
                            uv_signal_cb signal_cb,
                            int signum) {
  return uv__signal_start(handle, signal_cb, signum, 1);
}


int uv__signal_start(uv_signal_t* handle,
                            uv_signal_cb signal_cb,
                            int signum,
                            int oneshot) {
  /* Test for invalid signal values. */
  if (signum <= 0 || signum >= NSIG)
    return UV_EINVAL;

  /* Short circuit: if the signal watcher is already watching {signum} don't go
   * through the process of deregistering and registering the handler.
   * Additionally, this avoids pending signals getting lost in the (small) time
   * frame that handle->signum == 0. */
  if (signum == handle->signum) {
    handle->signal_cb = signal_cb;
    return 0;
  }

  /* If the signal handler was already active, stop it first. */
  if (handle->signum != 0) {
    int r = uv_signal_stop(handle);
    /* uv_signal_stop is infallible. */
    assert(r == 0);
  }

  EnterCriticalSection(&uv__signal_lock);

  handle->signum = signum;
  if (oneshot)
    handle->flags |= UV_SIGNAL_ONE_SHOT;

  RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);

  LeaveCriticalSection(&uv__signal_lock);

  handle->signal_cb = signal_cb;
  uv__handle_start(handle);

  return 0;
}


void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
    uv_req_t* req) {
  long dispatched_signum;

  assert(handle->type == UV_SIGNAL);
  assert(req->type == UV_SIGNAL_REQ);

  dispatched_signum = InterlockedExchange(
          (volatile LONG*) &handle->pending_signum, 0);
  assert(dispatched_signum != 0);

  /* Check if the pending signal equals the signum that we are watching for.
   * These can get out of sync when the handler is stopped and restarted while
   * the signal_req is pending. */
  if (dispatched_signum == handle->signum)
    handle->signal_cb(handle, dispatched_signum);

  if (handle->flags & UV_SIGNAL_ONE_SHOT)
    uv_signal_stop(handle);

  if (handle->flags & UV_HANDLE_CLOSING) {
    /* When it is closing, it must be stopped at this point. */
    assert(handle->signum == 0);
    uv_want_endgame(loop, (uv_handle_t*) handle);
  }
}


void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
  uv_signal_stop(handle);
  uv__handle_closing(handle);



( run in 0.976 second using v1.01-cache-2.11-cpan-df04353d9ac )