Пример #1
0
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
    uv_write_t* req) {
  assert(handle->type == UV_TCP);

  assert(handle->write_queue_size >= req->queued_bytes);
  handle->write_queue_size -= req->queued_bytes;

  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    if (req->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(req->wait_handle);
    }
    if (req->event_handle) {
      CloseHandle(req->event_handle);
    }
  }

  if (req->cb) {
    uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
    ((uv_write_cb)req->cb)(req, loop->last_err.code == UV_OK ? 0 : -1);
  }

  handle->write_reqs_pending--;
  if (handle->flags & UV_HANDLE_SHUTTING &&
      handle->write_reqs_pending == 0) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
  uv_unref(loop);
}
//********************************************************************************************
// Function: CleanupDrt
//
// Description: Deletes and Frees the various objects and providers used by the DRT
//
//********************************************************************************************
void CleanupDrt(DRT_CONTEXT *Drt)
{
    for(UINT i=0; i<Drt->registrations.size(); i++)
    {
        DrtUnregisterKey(Drt->registrations[i].hDrtReg);

        if(Drt->registrations[i].regInfo.key.pb)
            free(Drt->registrations[i].regInfo.key.pb);
        if(Drt->registrations[i].regInfo.appData.pb)
            free(Drt->registrations[i].regInfo.appData.pb);
    }
    Drt->registrations.clear();
    
    if (Drt->DrtWaitEvent != NULL)
    {
        UnregisterWait(Drt->DrtWaitEvent);
    }
    
    if (Drt->hDrt != NULL)
    {
        DrtClose(Drt->hDrt);
        Drt->hDrt = NULL;
    }
    
    if (Drt->eventHandle!= NULL)
    {
        CloseHandle(Drt->eventHandle);
        Drt->eventHandle = NULL;
    }

    if (Drt->settings.pBootstrapProvider != NULL)
    {
        if(Drt->BootstrapProviderType == 0)
            DrtDeleteDnsBootstrapResolver(Drt->settings.pBootstrapProvider);
        else if(Drt->BootstrapProviderType == 1)
            DrtDeletePnrpBootstrapResolver(Drt->settings.pBootstrapProvider);
        else if(Drt->BootstrapProviderType == 2)
            DrtDeleteCustomBootstrapResolver(Drt->settings.pBootstrapProvider);
    }

    if (Drt->settings.pSecurityProvider != NULL)
    {
        if(Drt->SecurityProviderType == 0)
            DrtDeleteNullSecurityProvider(Drt->settings.pSecurityProvider);
        else if(Drt->SecurityProviderType == 1)
            DrtDeleteDerivedKeySecurityProvider(Drt->settings.pSecurityProvider);
        else if(Drt->SecurityProviderType == 2)
            DrtDeleteCustomSecurityProvider(Drt->settings.pSecurityProvider);
    }

    if (Drt->pRoot != NULL)
    {
        CertFreeCertificateContext(Drt->pRoot);
    }

    if (Drt->pLocal != NULL)
    {
        CertFreeCertificateContext(Drt->pLocal);
    }
}
Пример #3
0
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
  DWORD exit_code;

  /* Unregister from process notification. */
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    UnregisterWait(handle->wait_handle);
    handle->wait_handle = INVALID_HANDLE_VALUE;
  }

  if (handle->process_handle != INVALID_HANDLE_VALUE) {
    /* Get the exit code. */
    if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
      exit_code = 127;
    }

    /* Clean-up the process handle. */
    CloseHandle(handle->process_handle);
    handle->process_handle = INVALID_HANDLE_VALUE;
  } else {
    /* We probably left the child stdio handles open to report the error */
    /* asynchronously, so close them now. */
    close_child_stdio(handle);

    /* The process never even started in the first place. */
    exit_code = 127;
  }

  /* Fire the exit callback. */
  if (handle->exit_cb) {
    handle->exit_cb(handle, exit_code, handle->exit_signal);
  }
}
Пример #4
0
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
    uv_write_t* req) {
  int err;

  assert(handle->type == UV_TCP);

  assert(handle->write_queue_size >= req->queued_bytes);
  handle->write_queue_size -= req->queued_bytes;

  UNREGISTER_HANDLE_REQ(loop, handle, req);

  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    if (req->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(req->wait_handle);
      req->wait_handle = INVALID_HANDLE_VALUE;
    }
    if (req->event_handle) {
      CloseHandle(req->event_handle);
      req->event_handle = NULL;
    }
  }

  if (req->cb) {
    err = GET_REQ_SOCK_ERROR(req);
    req->cb(req, uv_translate_sys_error(err));
  }

  handle->write_reqs_pending--;
  if (handle->shutdown_req != NULL &&
      handle->write_reqs_pending == 0) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Пример #5
0
static void CALLBACK trigger_process_detection( void* lpParameter, BOOLEAN TimerOrWaitFired )
{
    opal_process_handle_t* handle = (opal_process_handle_t*)lpParameter;
    DWORD exitCode;

    opal_list_remove_item( &registered_cb, (opal_list_item_t*)handle );
    /**
     * As this item will never be triggered again, we can safely remove the
     * registered handle.
     */
    if( 0 == UnregisterWait( handle->registered_handle ) ) {
		/**
		 * If any callback functions associated with the timer have not completed when
		 * UnregisterWait is called, UnregisterWait unregisters the wait on the callback
		 * functions and fails with the ERROR_IO_PENDING error code. The error code does
		 * not indicate that the function has failed, and the function does not need to
		 * be called again. If your code requires an error code to set only when the
		 * unregister operation has failed, call UnregisterWaitEx instead.
		 */
        int error = GetLastError();
    }
    handle->registered_handle = INVALID_HANDLE_VALUE;
    /**
     * Get the exit code of the process.
     */
    if( 0 == GetExitCodeProcess( (HANDLE)handle->pid, &exitCode ) ) {
        int error = GetLastError();
    }
    handle->status = (int)exitCode;
    handle->callback(handle->pid, handle->status, handle->data);
    OBJ_RELEASE( handle );
}
Пример #6
0
static void CALLBACK try_wait_callback( void * data, BOOLEAN is_timeout )
{
    struct _cmdtab_t * slot = ( struct _cmdtab_t * )data;
    WaitForSingleObject( process_queue.write_okay, INFINITE );
    process_queue.job_index = slot - cmdtab;
    assert( !is_timeout );
    SetEvent( process_queue.read_okay );
    /* Okay.  Non-blocking. */
    UnregisterWait( slot->wait_handle );
}
Пример #7
0
void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
    uv_write_t* req) {
  assert(handle->type == UV_NAMED_PIPE);

  assert(handle->write_queue_size >= req->queued_bytes);
  handle->write_queue_size -= req->queued_bytes;

  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    if (req->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(req->wait_handle);
      req->wait_handle = INVALID_HANDLE_VALUE;
    }
    if (req->event_handle) {
      CloseHandle(req->event_handle);
      req->event_handle = NULL;
    }
  }

  if (req->ipc_header) {
    if (req == &handle->ipc_header_write_req) {
      req->type = UV_UNKNOWN_REQ;
    } else {
      free(req);
    }
  } else {
    if (req->cb) {
      if (!REQ_SUCCESS(req)) {
        uv__set_sys_error(loop, GET_REQ_ERROR(req));
        ((uv_write_cb)req->cb)(req, -1);
      } else {
        ((uv_write_cb)req->cb)(req, 0);
      }
    }
  }

  handle->write_reqs_pending--;

  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
      handle->non_overlapped_writes_tail) {
    assert(handle->write_reqs_pending > 0);
    uv_queue_non_overlapped_write(handle);
  }

  if (handle->write_reqs_pending == 0) {
    uv_unref(loop);
  }

  if (handle->write_reqs_pending == 0 &&
      handle->flags & UV_HANDLE_SHUTTING) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Пример #8
0
VOID CALLBACK WindowsOpAutoUpdatePI::PackageExtractor::WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    g_thread_tools->PostMessageToMainThread(MSG_AUTOUPDATE_UNPACKING_COMPLETE, (MH_PARAM_1)lpParameter, NULL);

    PackageExtractor* pkg_ext = (PackageExtractor*)lpParameter;

    UnregisterWait(pkg_ext->m_wait_object);

    CloseHandle(pkg_ext->m_process_handle);

    delete pkg_ext;
}
Пример #9
0
static void opal_process_handle_destruct( opal_object_t* obj )
{
    opal_process_handle_t* handle = (opal_process_handle_t*)obj;

    if( INVALID_HANDLE_VALUE != handle->registered_handle ) {
        if( 0 == UnregisterWait( handle->registered_handle ) ) {
            int error = GetLastError();
        }
        if( 0 == CloseHandle( handle->registered_handle ) ) {
            int error = GetLastError();
        }
        handle->registered_handle = INVALID_HANDLE_VALUE;
    }
}
Пример #10
0
static PyObject *
overlapped_UnregisterWait(PyObject *self, PyObject *args)
{
    HANDLE WaitHandle;
    BOOL ret;

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

    Py_BEGIN_ALLOW_THREADS
    ret = UnregisterWait(WaitHandle);
    Py_END_ALLOW_THREADS

    if (!ret)
        return SetFromWindowsErr(0);
    Py_RETURN_NONE;
}
Пример #11
0
Файл: tty.c Проект: hghazal/node
static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
  uv_loop_t* loop;
  uv_tty_t* handle;
  uv_req_t* req;

  assert(data);
  assert(!didTimeout);

  req = (uv_req_t*) data;
  handle = (uv_tty_t*) req->data;
  loop = handle->loop;

  UnregisterWait(handle->read_raw_wait);
  handle->read_raw_wait = NULL;

  SET_REQ_SUCCESS(req);
  POST_COMPLETION_FOR_REQ(loop, req);
}
Пример #12
0
static
VOID CALLBACK pthreads_win32_unnotice(void* parameter, BOOLEAN timerOrWait)
{
  pthread_t pth = parameter;
  pthread_t self = tls_impersonate(pth);

  tls_call_destructors();
  CloseHandle(pth->handle);
  /*
  if (pth->fiber && pth->own_fiber) {
    DeleteFiber(pth->fiber);
    } */
  UnregisterWait(pth->wait_handle);

  tls_impersonate(self);
  pthread_mutex_destroy(&pth->fiber_lock);
  pthread_mutex_destroy(&pth->lock);
  free(pth);
}
Пример #13
0
    Bool Instance::Unload()
    {
        // free wait handle
        if( _wait_handle )
            UnregisterWait(_wait_handle);

        // unload injected dll
        _injector.Unload();

        // close process handle
        if( _process )
            CloseHandle(_process);

        // reset
        _process_id = 0;
        _process = NULL;
        _wait_handle = NULL;

        return true;
    }
Пример #14
0
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
    uv_write_t* req) {
  int err;

  assert(handle->type == UV_TCP);

  assert(handle->write_queue_size >= req->u.io.queued_bytes);
  handle->write_queue_size -= req->u.io.queued_bytes;

  UNREGISTER_HANDLE_REQ(loop, handle, req);

  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    if (req->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(req->wait_handle);
      req->wait_handle = INVALID_HANDLE_VALUE;
    }
    if (req->event_handle) {
      CloseHandle(req->event_handle);
      req->event_handle = NULL;
    }
  }

  if (req->cb) {
    err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req));
    if (err == UV_ECONNABORTED) {
      /* use UV_ECANCELED for consistency with Unix */
      err = UV_ECANCELED;
    }
    req->cb(req, err);
  }

  handle->stream.conn.write_reqs_pending--;
  if (handle->stream.conn.shutdown_req != NULL &&
      handle->stream.conn.write_reqs_pending == 0) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Пример #15
0
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
  DWORD exit_code;

  assert(handle->exit_cb_pending);
  handle->exit_cb_pending = 0;

  /* If we're closing, don't call the exit callback. Just schedule a close */
  /* callback now. */
  if (handle->flags & UV__HANDLE_CLOSING) {
    uv_want_endgame(loop, (uv_handle_t*)handle);
    return;
  }

  /* Unregister from process notification. */
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
#ifndef WINONECORE
    UnregisterWait(handle->wait_handle);
#endif
    handle->wait_handle = INVALID_HANDLE_VALUE;
  }

  /* Set the handle to inactive: no callbacks will be made after the exit */
  /* callback.*/
  uv__handle_stop(handle);

  if (handle->spawn_error.code != UV_OK) {
    /* Spawning failed. */
    exit_code = (DWORD) - 1;
  } else if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
    /* Unable to to obtain the exit code. This should never happen. */
    exit_code = (DWORD) - 1;
  }

  /* Fire the exit callback. */
  if (handle->exit_cb) {
    loop->last_err = handle->spawn_error;
    handle->exit_cb(handle, exit_code, handle->exit_signal);
  }
}
Пример #16
0
int
__pmSetSignalHandler(int sig, __pmSignalHandler func)
{
    int sts, index;
    char *signame, evname[64];
    HANDLE eventhdl, waithdl;

    if ((signame = MapSignals(sig, &index)) < 0)
	return index;

    if (signals[index].callback) {	/* remove old handler */
	UnregisterWait(signals[index].waithandle);
	CloseHandle(signals[index].eventhandle);
	signals[index].callback = NULL;
	signals[index].signal = -1;
    }

    if (func == SIG_IGN)
	return 0;

    sts = 0;
    snprintf(evname, sizeof(evname), "PCP/%" FMT_PID "/%s", getpid(), signame);
    if (!(eventhdl = CreateEvent(NULL, FALSE, FALSE, TEXT(evname)))) {
	sts = GetLastError();
	fprintf(stderr, "CreateEvent::%s failed (%d)\n", signame, sts);
    }
    else if (!RegisterWaitForSingleObject(&waithdl, eventhdl,
		SignalCallback, (PVOID)index, INFINITE, 0)) {
	sts = GetLastError();
	fprintf(stderr, "RegisterWait::%s failed (%d)\n", signame, sts);
    }
    else {
	signals[index].eventhandle = eventhdl;
	signals[index].waithandle = waithdl;
	signals[index].callback = func;
	signals[index].signal = sig;
    }
    return sts;
}
Пример #17
0
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_process_t* handle) {
  int i;
  DWORD exit_code;

  /* Close stdio handles. */
  for (i = 0; i < COUNTOF(handle->stdio_pipes); i++) {
    if (handle->stdio_pipes[i].child_pipe != INVALID_HANDLE_VALUE) {
      CloseHandle(handle->stdio_pipes[i].child_pipe);
      handle->stdio_pipes[i].child_pipe = INVALID_HANDLE_VALUE;
    }
  }

  /* Unregister from process notification. */
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    UnregisterWait(handle->wait_handle);
    handle->wait_handle = INVALID_HANDLE_VALUE;
  }

  if (handle->process_handle != INVALID_HANDLE_VALUE) {
    /* Get the exit code. */
    if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
      exit_code = 127;
    }

    /* Clean-up the process handle. */
    CloseHandle(handle->process_handle);
    handle->process_handle = INVALID_HANDLE_VALUE;
  } else {
    /* The process never even started in the first place. */
    exit_code = 127;
  }

  /* Fire the exit callback. */
  if (handle->exit_cb) {
    handle->exit_cb(handle, exit_code, handle->exit_signal);
  }
}
Пример #18
0
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
  int64_t exit_code;
  DWORD status;

  assert(handle->exit_cb_pending);
  handle->exit_cb_pending = 0;

  /* If we're closing, don't call the exit callback. Just schedule a close */
  /* callback now. */
  if (handle->flags & UV__HANDLE_CLOSING) {
    uv_want_endgame(loop, (uv_handle_t*) handle);
    return;
  }

  /* Unregister from process notification. */
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    UnregisterWait(handle->wait_handle);
    handle->wait_handle = INVALID_HANDLE_VALUE;
  }

  /* Set the handle to inactive: no callbacks will be made after the exit */
  /* callback.*/
  uv__handle_stop(handle);

  if (GetExitCodeProcess(handle->process_handle, &status)) {
    exit_code = status;
  } else {
    /* Unable to to obtain the exit code. This should never happen. */
    exit_code = uv_translate_sys_error(GetLastError());
  }

  /* Fire the exit callback. */
  if (handle->exit_cb) {
    handle->exit_cb(handle, exit_code, handle->exit_signal);
  }
}
Пример #19
0
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
  int status;
  int sys_error;
  unsigned int i;
  uv_tcp_accept_t* req;

  if (handle->flags & UV_HANDLE_CONNECTION &&
      handle->flags & UV_HANDLE_SHUTTING &&
      !(handle->flags & UV_HANDLE_SHUT) &&
      handle->write_reqs_pending == 0) {

    if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) {
      status = 0;
      handle->flags |= UV_HANDLE_SHUT;
    } else {
      status = -1;
      sys_error = WSAGetLastError();
    }
    if (handle->shutdown_req->cb) {
      if (status == -1) {
        uv__set_sys_error(loop, sys_error);
      }
      handle->shutdown_req->cb(handle->shutdown_req, status);
    }

    DECREASE_PENDING_REQ_COUNT(handle);
    return;
  }

  if (handle->flags & UV_HANDLE_CLOSING &&
      handle->reqs_pending == 0) {
    assert(!(handle->flags & UV_HANDLE_CLOSED));
    handle->flags |= UV_HANDLE_CLOSED;

    if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) {
      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
        for (i = 0; i < uv_simultaneous_server_accepts; i++) {
          req = &handle->accept_reqs[i];
          if (req->wait_handle != INVALID_HANDLE_VALUE) {
            UnregisterWait(req->wait_handle);
            req->wait_handle = INVALID_HANDLE_VALUE;
          }
          if (req->event_handle) {
            CloseHandle(req->event_handle);
            req->event_handle = NULL;
          }
        }
      }

      free(handle->accept_reqs);
      handle->accept_reqs = NULL;
    }

    if (handle->close_cb) {
      handle->close_cb((uv_handle_t*)handle);
    }

    active_tcp_streams--;

    uv_unref(loop);
  }
}
Пример #20
0
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
  int status;
  unsigned int i;
  uv_tcp_accept_t* req;

  if (handle->flags & UV_HANDLE_CONNECTION &&
      handle->shutdown_req != NULL &&
      handle->write_reqs_pending == 0) {

    UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);

    if (handle->flags & UV__HANDLE_CLOSING) {
      status = -1;
      uv__set_artificial_error(loop, UV_ECANCELED);
    } else if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) {
      status = 0;
    } else {
      status = -1;
      uv__set_sys_error(loop, WSAGetLastError());
    }

    if (handle->shutdown_req->cb) {
      handle->shutdown_req->cb(handle->shutdown_req, status);
    }

    handle->shutdown_req = NULL;
    DECREASE_PENDING_REQ_COUNT(handle);
    return;
  }

  if (handle->flags & UV__HANDLE_CLOSING &&
      handle->reqs_pending == 0) {
    assert(!(handle->flags & UV_HANDLE_CLOSED));

    if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
      closesocket(handle->socket);
      handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
    }

    if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) {
      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
        for (i = 0; i < uv_simultaneous_server_accepts; i++) {
          req = &handle->accept_reqs[i];
          if (req->wait_handle != INVALID_HANDLE_VALUE) {
            UnregisterWait(req->wait_handle);
            req->wait_handle = INVALID_HANDLE_VALUE;
          }
          if (req->event_handle) {
            CloseHandle(req->event_handle);
            req->event_handle = NULL;
          }
        }
      }

      free(handle->accept_reqs);
      handle->accept_reqs = NULL;
    }

    if (handle->flags & UV_HANDLE_CONNECTION &&
        handle->flags & UV_HANDLE_EMULATE_IOCP) {
      if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
        UnregisterWait(handle->read_req.wait_handle);
        handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
      }
      if (handle->read_req.event_handle) {
        CloseHandle(handle->read_req.event_handle);
        handle->read_req.event_handle = NULL;
      }
    }

    uv__handle_close(handle);
    loop->active_tcp_streams--;
  }
}
Пример #21
0
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
  unsigned int uv_alloced;
  DWORD result;
  uv_shutdown_t* req;
  NTSTATUS nt_status;
  IO_STATUS_BLOCK io_status;
  FILE_PIPE_LOCAL_INFORMATION pipe_info;

  if (handle->flags & UV_HANDLE_SHUTTING &&
      !(handle->flags & UV_HANDLE_SHUT) &&
      handle->write_reqs_pending == 0) {
    req = handle->shutdown_req;

    /* Try to avoid flushing the pipe buffer in the thread pool. */
    nt_status = pNtQueryInformationFile(handle->handle,
                                        &io_status,
                                        &pipe_info,
                                        sizeof pipe_info,
                                        FilePipeLocalInformation);

    if (nt_status != STATUS_SUCCESS) {
      /* Failure */
      handle->flags &= ~UV_HANDLE_SHUTTING;
      if (req->cb) {
        uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
        req->cb(req, -1);
      }
      DECREASE_PENDING_REQ_COUNT(handle);
      return;
    }

    if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
      handle->flags |= UV_HANDLE_SHUT;

      /* Short-circuit, no need to call FlushFileBuffers. */
      uv_insert_pending_req(loop, (uv_req_t*) req);
      return;
    }

    /* Run FlushFileBuffers in the thread pool. */
    result = QueueUserWorkItem(pipe_shutdown_thread_proc,
                               req,
                               WT_EXECUTELONGFUNCTION);
    if (result) {
      /* Mark the handle as shut now to avoid going through this again. */
      handle->flags |= UV_HANDLE_SHUT;
      return;

    } else {
      /* Failure. */
      handle->flags &= ~UV_HANDLE_SHUTTING;
      if (req->cb) {
        uv__set_sys_error(loop, GetLastError());
        req->cb(req, -1);
      }
      DECREASE_PENDING_REQ_COUNT(handle);
      return;
    }
  }

  if (handle->flags & UV_HANDLE_CLOSING &&
      handle->reqs_pending == 0) {
    assert(!(handle->flags & UV_HANDLE_CLOSED));
    handle->flags |= UV_HANDLE_CLOSED;

    if (handle->flags & UV_HANDLE_CONNECTION) {
      if (handle->pending_socket_info) {
        free(handle->pending_socket_info);
        handle->pending_socket_info = NULL;
      }
      
      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
        if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
          UnregisterWait(handle->read_req.wait_handle);
          handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
        }
        if (handle->read_req.event_handle) {
          CloseHandle(handle->read_req.event_handle);
          handle->read_req.event_handle = NULL;
        }
      }
    }

    if (handle->flags & UV_HANDLE_PIPESERVER) {
      assert(handle->accept_reqs);
      free(handle->accept_reqs);
      handle->accept_reqs = NULL;
    }

    /* Remember the state of this flag because the close callback is */
    /* allowed to clobber or free the handle's memory */
    uv_alloced = handle->flags & UV_HANDLE_UV_ALLOCED;

    if (handle->close_cb) {
      handle->close_cb((uv_handle_t*)handle);
    }

    if (uv_alloced) {
      free(handle);
    }

    uv_unref(loop);
  }
}
Пример #22
0
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
  DWORD result;
  uv_shutdown_t* req;
  NTSTATUS nt_status;
  IO_STATUS_BLOCK io_status;
  FILE_PIPE_LOCAL_INFORMATION pipe_info;

  if ((handle->flags & UV_HANDLE_CONNECTION) &&
      handle->shutdown_req != NULL &&
      handle->write_reqs_pending == 0) {
    req = handle->shutdown_req;

    /* Clear the shutdown_req field so we don't go here again. */
    handle->shutdown_req = NULL;

    if (handle->flags & UV__HANDLE_CLOSING) {
      UNREGISTER_HANDLE_REQ(loop, handle, req);

      /* Already closing. Cancel the shutdown. */
      if (req->cb) {
        uv__set_artificial_error(loop, UV_ECANCELED);
        req->cb(req, -1);
      }

      DECREASE_PENDING_REQ_COUNT(handle);
      return;
    }

    /* Try to avoid flushing the pipe buffer in the thread pool. */
    nt_status = pNtQueryInformationFile(handle->handle,
                                        &io_status,
                                        &pipe_info,
                                        sizeof pipe_info,
                                        FilePipeLocalInformation);

    if (nt_status != STATUS_SUCCESS) {
      /* Failure */
      UNREGISTER_HANDLE_REQ(loop, handle, req);

      handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
      if (req->cb) {
        uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
        req->cb(req, -1);
      }

      DECREASE_PENDING_REQ_COUNT(handle);
      return;
    }

    if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
      /* Short-circuit, no need to call FlushFileBuffers. */
      uv_insert_pending_req(loop, (uv_req_t*) req);
      return;
    }

    /* Run FlushFileBuffers in the thread pool. */
    result = QueueUserWorkItem(pipe_shutdown_thread_proc,
                               req,
                               WT_EXECUTELONGFUNCTION);
    if (result) {
      return;

    } else {
      /* Failure. */
      UNREGISTER_HANDLE_REQ(loop, handle, req);

      handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
      if (req->cb) {
        uv__set_sys_error(loop, GetLastError());
        req->cb(req, -1);
      }

      DECREASE_PENDING_REQ_COUNT(handle);
      return;
    }
  }

  if (handle->flags & UV__HANDLE_CLOSING &&
      handle->reqs_pending == 0) {
    assert(!(handle->flags & UV_HANDLE_CLOSED));

    if (handle->flags & UV_HANDLE_CONNECTION) {
      if (handle->pending_ipc_info.socket_info) {
        free(handle->pending_ipc_info.socket_info);
        handle->pending_ipc_info.socket_info = NULL;
      }

      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
        if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
          UnregisterWait(handle->read_req.wait_handle);
          handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
        }
        if (handle->read_req.event_handle) {
          CloseHandle(handle->read_req.event_handle);
          handle->read_req.event_handle = NULL;
        }
      }
    }

    if (handle->flags & UV_HANDLE_PIPESERVER) {
      assert(handle->accept_reqs);
      free(handle->accept_reqs);
      handle->accept_reqs = NULL;
    }

    uv__handle_close(handle);
  }
}
Пример #23
0
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
    uv_process_options_t options) {
  int err = 0, keep_child_stdio_open = 0;
  wchar_t* path = NULL;
  int size;
  BOOL result;
  wchar_t* application_path = NULL, *application = NULL, *arguments = NULL,
    *env = NULL, *cwd = NULL;
  HANDLE* child_stdio = process->child_stdio;
  STARTUPINFOW startup;
  PROCESS_INFORMATION info;

  if (!options.file) {
    uv__set_artificial_error(loop, UV_EINVAL);
    return -1;
  }

  uv_process_init(loop, process);

  process->exit_cb = options.exit_cb;
  UTF8_TO_UTF16(options.file, application);
  arguments = options.args ? make_program_args(options.args,
      options.windows_verbatim_arguments) : NULL;
  env = options.env ? make_program_env(options.env) : NULL;

  if (options.cwd) {
    UTF8_TO_UTF16(options.cwd, cwd);
  } else {
    size  = GetCurrentDirectoryW(0, NULL) * sizeof(wchar_t);
    if (size) {
      cwd = (wchar_t*)malloc(size);
      if (!cwd) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
      }
      GetCurrentDirectoryW(size, cwd);
    } else {
      uv__set_sys_error(loop, GetLastError());
      err = -1;
      goto done;
    }
  }

  /* Get PATH env. variable. */
  size = GetEnvironmentVariableW(L"PATH", NULL, 0) + 1;
  path = (wchar_t*)malloc(size * sizeof(wchar_t));
  if (!path) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }
  GetEnvironmentVariableW(L"PATH", path, size * sizeof(wchar_t));
  path[size - 1] = L'\0';

  application_path = search_path(application,
                                 cwd,
                                 path);

  if (!application_path) {
    /* CreateProcess will fail, but this allows us to pass this error to */
    /* the user asynchronously. */
    application_path = application;
  }

  /* Create stdio pipes. */
  if (options.stdin_stream) {
    if (options.stdin_stream->ipc) {
      err = uv_create_stdio_pipe_pair(
          loop,
          options.stdin_stream,
          &child_stdio[0],
          PIPE_ACCESS_DUPLEX,
          GENERIC_READ | FILE_WRITE_ATTRIBUTES | GENERIC_WRITE,
          1);
    } else {
      err = uv_create_stdio_pipe_pair(
          loop,
          options.stdin_stream,
          &child_stdio[0],
          PIPE_ACCESS_OUTBOUND,
          GENERIC_READ | FILE_WRITE_ATTRIBUTES,
          0);
    }
  } else {
    err = duplicate_std_handle(loop, STD_INPUT_HANDLE, &child_stdio[0]);
  }
  if (err) {
    goto done;
  }

  if (options.stdout_stream) {
    err = uv_create_stdio_pipe_pair(
        loop, options.stdout_stream,
        &child_stdio[1],
        PIPE_ACCESS_INBOUND,
        GENERIC_WRITE,
        0);
  } else {
    err = duplicate_std_handle(loop, STD_OUTPUT_HANDLE, &child_stdio[1]);
  }
  if (err) {
    goto done;
  }

  if (options.stderr_stream) {
    err = uv_create_stdio_pipe_pair(
        loop,
        options.stderr_stream,
        &child_stdio[2],
        PIPE_ACCESS_INBOUND,
        GENERIC_WRITE,
        0);
  } else {
    err = duplicate_std_handle(loop, STD_ERROR_HANDLE, &child_stdio[2]);
  }
  if (err) {
    goto done;
  }

  startup.cb = sizeof(startup);
  startup.lpReserved = NULL;
  startup.lpDesktop = NULL;
  startup.lpTitle = NULL;
  startup.dwFlags = STARTF_USESTDHANDLES;
  startup.cbReserved2 = 0;
  startup.lpReserved2 = NULL;
  startup.hStdInput = child_stdio[0];
  startup.hStdOutput = child_stdio[1];
  startup.hStdError = child_stdio[2];

  if (CreateProcessW(application_path,
                     arguments,
                     NULL,
                     NULL,
                     1,
                     CREATE_UNICODE_ENVIRONMENT,
                     env,
                     cwd,
                     &startup,
                     &info)) {
    /* Spawn succeeded */
    process->process_handle = info.hProcess;
    process->pid = info.dwProcessId;

    if (options.stdin_stream &&
        options.stdin_stream->ipc) {
      options.stdin_stream->ipc_pid = info.dwProcessId;
    }

    /* Setup notifications for when the child process exits. */
    result = RegisterWaitForSingleObject(&process->wait_handle,
        process->process_handle, exit_wait_callback, (void*)process, INFINITE,
        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
    if (!result) {
      uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
    }

    CloseHandle(info.hThread);

  } else {
    /* CreateProcessW failed, but this failure should be delivered */
    /* asynchronously to retain unix compatibility. So pretent spawn */
    /* succeeded, and start a thread instead that prints an error */
    /* to the child's intended stderr. */
    process->spawn_errno = GetLastError();
    keep_child_stdio_open = 1;
    if (!QueueUserWorkItem(spawn_failure, process, WT_EXECUTEDEFAULT)) {
      uv_fatal_error(GetLastError(), "QueueUserWorkItem");
    }
  }

done:
  free(application);
  if (application_path != application) {
    free(application_path);
  }
  free(arguments);
  free(cwd);
  free(env);
  free(path);

  /* Under normal circumstances we should close the stdio handles now - */
  /* the child now has its own duplicates, or something went horribly wrong. */
  /* The only exception is when CreateProcess has failed, then we actually */
  /* need to keep the stdio handles to report the error asynchronously. */
  if (!keep_child_stdio_open) {
    close_child_stdio(process);
  } else {
    /* We're keeping the handles open, the thread pool is going to have */
    /* it's way with them. But at least make them noninheritable. */
    int i;
    for (i = 0; i < COUNTOF(process->child_stdio); i++) {
      SetHandleInformation(child_stdio[i], HANDLE_FLAG_INHERIT, 0);
    }
  }

  if (err) {
    if (process->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(process->wait_handle);
      process->wait_handle = INVALID_HANDLE_VALUE;
    }

    if (process->process_handle != INVALID_HANDLE_VALUE) {
      CloseHandle(process->process_handle);
      process->process_handle = INVALID_HANDLE_VALUE;
    }
  }

  return err;
}
Пример #24
0
int uv_spawn(uv_process_t* process, uv_process_options_t options) {
  int err = 0, i;
  wchar_t* path;
  int size;
  wchar_t* application_path, *application, *arguments, *env, *cwd;
  STARTUPINFOW startup;
  PROCESS_INFORMATION info;

  uv_process_init(process);

  process->exit_cb = options.exit_cb;
  UTF8_TO_UTF16(options.file, application);
  arguments = options.args ? make_program_args(options.args, options.windows_verbatim_arguments) : NULL;
  env = options.env ? make_program_env(options.env) : NULL;

  if (options.cwd) {
    UTF8_TO_UTF16(options.cwd, cwd);
  } else {
    size  = GetCurrentDirectoryW(0, NULL) * sizeof(wchar_t);
    if (size) {
      cwd = (wchar_t*)malloc(size);
      if (!cwd) {
        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
      }
      GetCurrentDirectoryW(size, cwd);
    } else {
      uv_set_sys_error(GetLastError());
      err = -1;
      goto done;
    }
  }

  /* Get PATH env. variable. */
  size = GetEnvironmentVariableW(L"PATH", NULL, 0) + 1;
  path = (wchar_t*)malloc(size * sizeof(wchar_t));
  if (!path) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }
  GetEnvironmentVariableW(L"PATH", path, size * sizeof(wchar_t));
  path[size - 1] = L'\0';

  application_path = search_path(application,
                                 cwd,
                                 path,
                                 DEFAULT_PATH_EXT);

  if (!application_path) {
    /* CreateProcess will fail, but this allows us to pass this error to */
    /* the user asynchronously. */
    application_path = application;
  }

  /* Create stdio pipes. */
  if (options.stdin_stream) {
    err = uv_create_stdio_pipe_pair(options.stdin_stream, &process->stdio_pipes[0].child_pipe, PIPE_ACCESS_OUTBOUND, GENERIC_READ | FILE_WRITE_ATTRIBUTES);
    if (err) {
      goto done;
    }

    process->stdio_pipes[0].server_pipe = options.stdin_stream;
  }

  if (options.stdout_stream) {
    err = uv_create_stdio_pipe_pair(options.stdout_stream, &process->stdio_pipes[1].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
    if (err) {
      goto done;
    }

    process->stdio_pipes[1].server_pipe = options.stdout_stream;
  }

  if (options.stderr_stream) {
    err = uv_create_stdio_pipe_pair(options.stderr_stream, &process->stdio_pipes[2].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
    if (err) {
      goto done;
    }

    process->stdio_pipes[2].server_pipe = options.stderr_stream;
  }

  startup.cb = sizeof(startup);
  startup.lpReserved = NULL;
  startup.lpDesktop = NULL;
  startup.lpTitle = NULL;
  startup.dwFlags = STARTF_USESTDHANDLES;
  startup.cbReserved2 = 0;
  startup.lpReserved2 = NULL;
  startup.hStdInput = process->stdio_pipes[0].child_pipe;
  startup.hStdOutput = process->stdio_pipes[1].child_pipe;
  startup.hStdError = process->stdio_pipes[2].child_pipe;

  if (CreateProcessW(application_path,
                     arguments,
                     NULL,
                     NULL,
                     1,
                     CREATE_UNICODE_ENVIRONMENT,
                     env,
                     cwd,
                     &startup,
                     &info)) {
    /* Spawn succeeded */
    process->process_handle = info.hProcess;
    process->pid = info.dwProcessId;

    /* Setup notifications for when the child process exits. */
    if (!RegisterWaitForSingleObject(&process->wait_handle, process->process_handle,
        exit_wait_callback, (void*)process, INFINITE,
        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
      uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
    }

    CloseHandle(info.hThread);

  } else {
    /* CreateProcessW failed, but this failure should be delivered */
    /* asynchronously to retain unix compatibility. So pretent spawn */
    /* succeeded, and start a thread instead that prints an error */
    /* to the child's intended stderr. */
    process->spawn_errno = GetLastError();
    if (!QueueUserWorkItem(spawn_failure, process, WT_EXECUTEDEFAULT)) {
      uv_fatal_error(GetLastError(), "QueueUserWorkItem");
    }
  }

done:
  free(application);
  if (application_path != application) {
    free(application_path);
  }
  free(arguments);
  free(cwd);
  free(env);
  free(path);

  if (err) {
    for (i = 0; i < COUNTOF(process->stdio_pipes); i++) {
      if (process->stdio_pipes[i].child_pipe != INVALID_HANDLE_VALUE) {
        CloseHandle(process->stdio_pipes[i].child_pipe);
        process->stdio_pipes[i].child_pipe = INVALID_HANDLE_VALUE;
      }
    }

    if (process->wait_handle != INVALID_HANDLE_VALUE) {
      UnregisterWait(process->wait_handle);
      process->wait_handle = INVALID_HANDLE_VALUE;
    }

    if (process->process_handle != INVALID_HANDLE_VALUE) {
      CloseHandle(process->process_handle);
      process->process_handle = INVALID_HANDLE_VALUE;
    }
  }

  return err;
}
Пример #25
0
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
  int err;
  unsigned int i;
  uv_tcp_accept_t* req;

  if (handle->flags & UV_HANDLE_CONNECTION &&
      handle->stream.conn.shutdown_req != NULL &&
      handle->stream.conn.write_reqs_pending == 0) {

    UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);

    err = 0;
    if (handle->flags & UV_HANDLE_CLOSING) {
      err = ERROR_OPERATION_ABORTED;
    } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) {
      err = WSAGetLastError();
    }

    if (handle->stream.conn.shutdown_req->cb) {
      handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req,
                               uv_translate_sys_error(err));
    }

    handle->stream.conn.shutdown_req = NULL;
    DECREASE_PENDING_REQ_COUNT(handle);
    return;
  }

  if (handle->flags & UV_HANDLE_CLOSING &&
      handle->reqs_pending == 0) {
    assert(!(handle->flags & UV_HANDLE_CLOSED));

    if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
      closesocket(handle->socket);
      handle->socket = INVALID_SOCKET;
      handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
    }

    if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
        for (i = 0; i < uv_simultaneous_server_accepts; i++) {
          req = &handle->tcp.serv.accept_reqs[i];
          if (req->wait_handle != INVALID_HANDLE_VALUE) {
            UnregisterWait(req->wait_handle);
            req->wait_handle = INVALID_HANDLE_VALUE;
          }
          if (req->event_handle) {
            CloseHandle(req->event_handle);
            req->event_handle = NULL;
          }
        }
      }

      uv__free(handle->tcp.serv.accept_reqs);
      handle->tcp.serv.accept_reqs = NULL;
    }

    if (handle->flags & UV_HANDLE_CONNECTION &&
        handle->flags & UV_HANDLE_EMULATE_IOCP) {
      if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
        UnregisterWait(handle->read_req.wait_handle);
        handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
      }
      if (handle->read_req.event_handle) {
        CloseHandle(handle->read_req.event_handle);
        handle->read_req.event_handle = NULL;
      }
    }

    uv__handle_close(handle);
    loop->active_tcp_streams--;
  }
}