예제 #1
0
int _tmain(int argc, _TCHAR *argv[])
{
    int i;

    for (i = 0; i < 10; ++i)
    {
        if (!QueueUserWorkItem(ThreadProc, (LPVOID)i, WT_EXECUTEDEFAULT))
            _ftprintf(stderr, _T("Failed to queue user worker item %d.\n"), i);
    }

    _putts(_T("Done!"));

    Sleep(1000);

    _putts(_T("-------------------------------------------------------------------------------"));

    for (i = 10; i < 20; ++i)
    {
        if (!QueueUserWorkItem(ThreadProc, (LPVOID)i, WT_EXECUTEDEFAULT))
            _ftprintf(stderr, _T("Failed to queue user worker item %d.\n"), i);
    }
    
    _tsystem(_T("pause"));

    return 0;
}
예제 #2
0
void CTextTraceFile::Load(QWORD nStop)
{
	if (m_bLoading)
	{
		return;
	}

	if (m_bReverse)
	{
		ATLASSERT(false);
	}
	else
	{
		if (nStop > m_FileSize.QuadPart)
		{
			nStop = (QWORD) m_FileSize.QuadPart;
		}

		if (m_nStop > nStop)
		{
			return;
		}
	}

	m_nStop = nStop;
	m_bLoading = true;

	QueueUserWorkItem((LPTHREAD_START_ROUTINE) LoadThreadInit, this, 0);
}
예제 #3
0
/*
 * Send a message to all connected listeners.
 *
 * XXX: The write blocks the current thread. Because RRAS threads
 * never enter alertable wait state, we can't use WriteFileEx().
 * We must either block or do the additional accounting for overlapped
 * WriteFile().
 * This has a very important consequence: our thread blocks until the
 * client thread reads its data or the pipe is disconnected.
 */
void
broadcast_pipe_message(void *msg, int msgsize)
{
    pipe_instance_t *pp;
    int i;
    int result;
    int nbytes;

    for (i = 0; i < PIPE_INSTANCES; i++) {
	pp = g_ce.pipes[i];
	if (pp != NULL && pp->state == PIPE_STATE_CONNECTED) {
	    result = WriteFile(pp->pipe, msg, msgsize, &nbytes, NULL);
	    if (result == 0) {
		result = GetLastError();
		TRACE1(NETWORK, "broadcast: write error %d", result);
		if (result == ERROR_PIPE_NOT_CONNECTED ||
		    result == ERROR_NO_DATA ||
		    result == ERROR_BROKEN_PIPE) {
		    TRACE1(NETWORK,
			   "broadcast: pipe %p disconnected; reconnecting.", pp->pipe);
		    /*
		     * We may be called by a reader thread. To avoid
		     * introducing loops, we schedule the listen
		     * operation on another thread.
		     */
		    ResetEvent(pp->revent);
		    QueueUserWorkItem(
			(LPTHREAD_START_ROUTINE)pipe_relisten_cb, (PVOID)pp, WT_EXECUTEINIOTHREAD);
		}
	    }
	}
    }
}
예제 #4
0
파일: srv.cpp 프로젝트: gclxry/awd
BOOL CServer::GetTextFileContents(HANDLE hEvent, 
                                  PWSTR pszFileName, 
                                  PSTR pBuffer, 
                                  DWORD dwBufferLen)
{
    BOOL bRet=FALSE;

    if(hEvent!=NULL && pszFileName!=NULL && pBuffer!=NULL && dwBufferLen!=0)
    {
        WorkerData* pWorkerData=new WorkerData;
        if(pWorkerData!= NULL)
        {
            pWorkerData->dwBufferLen=dwBufferLen;
            pWorkerData->pBuffer=pBuffer;
            pWorkerData->pszFileName=pszFileName;
            pWorkerData->hCompletionHandle=hEvent;
            
            bRet=QueueUserWorkItem(RequestWorker, 
                                   (LPVOID) pWorkerData, 
                                   WT_EXECUTELONGFUNCTION);
            if(!bRet)
            {
                delete pWorkerData;
            }
        }
    }

    return bRet;
}
예제 #5
0
파일: poll.c 프로젝트: ntoshev/node
static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
    uv_req_t* req;

    /* Find a yet unsubmitted req to submit. */
    if (handle->submitted_events_1 == 0) {
        req = &handle->poll_req_1;
        handle->submitted_events_1 = handle->events;
        handle->mask_events_1 = 0;
        handle->mask_events_2 = handle->events;
    } else if (handle->submitted_events_2 == 0) {
        req = &handle->poll_req_2;
        handle->submitted_events_2 = handle->events;
        handle->mask_events_1 = handle->events;
        handle->mask_events_2 = 0;
    } else {
        assert(0);
    }

    if (!QueueUserWorkItem(uv__slow_poll_thread_proc,
                           (void*) req,
                           WT_EXECUTELONGFUNCTION)) {
        /* Make this req pending, reporting an error. */
        SET_REQ_ERROR(req, GetLastError());
        uv_insert_pending_req(loop, req);
    }
}
예제 #6
0
static void uv_queue_non_overlapped_write(uv_pipe_t* handle) {
  uv_write_t* req = uv_remove_non_overlapped_write_req(handle);
  if (req) {
    if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc,
                           req,
                           WT_EXECUTELONGFUNCTION)) {
      uv_fatal_error(GetLastError(), "QueueUserWorkItem");
    }
  }
}
예제 #7
0
파일: NetFrame.cpp 프로젝트: Andrew90/def
void NetLink::Send(Frame *f)
{
	if(NULL != f->proc)
	{		
		QueueUserWorkItem(NetLink_Send, f, WT_EXECUTEINIOTHREAD);
	}
	else
	{
		closesocket(f->socket);
		Frame::Drop(f);
	}
}
예제 #8
0
파일: NetFrame.cpp 프로젝트: Andrew90/def
void NetLink::Recv(Frame *f)
{
	if(NULL != f->proc)
	{
		QueueUserWorkItem(NetLink_Recv, (LPVOID)f, WT_EXECUTEINIOTHREAD);
	}
	else
	{
		closesocket(f->socket);
		Frame::Drop(f);
	}
}
예제 #9
0
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
    uv_after_work_cb after_work_cb) {
  uv_work_req_init(loop, req, work_cb, after_work_cb);

  if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  uv_ref(loop);
  return 0;
}
예제 #10
0
파일: console.cpp 프로젝트: BattleNWar/YDWE
bool read_post()
{
    if (!reading.try_lock()) return false;
    console::read_req_t* req = new console::read_req_t;
    req->handle = ::GetStdHandle(STD_INPUT_HANDLE);
    bool suc = !!QueueUserWorkItem(async_read_thread, (void*)req, WT_EXECUTELONGFUNCTION);
    if (!suc)
    {
        delete req;
        reading.unlock();
    }
    return suc;
}
예제 #11
0
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
                  uv_after_work_cb after_work_cb) {
  if (work_cb == NULL) return uv__set_artificial_error(loop, UV_EINVAL);

  uv_work_req_init(loop, req, work_cb, after_work_cb);

  if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
    uv__set_sys_error(loop, GetLastError());
    return -1;
  }

  uv__req_register(loop, req);
  return 0;
}
예제 #12
0
DWORD
CM_StopProtocol ()
{
    DWORD dwErr         = NO_ERROR;
    BOOL  bSuccess      = FALSE;
    ULONG ulThreadCount = 0;

    /* XXX: no need to use ENTER_XORPRTM_API()/LEAVE_XORPRTM_API() */

    ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));

    do {
        /* cannot stop if already stopped */
        if (g_ce.iscStatus != XORPRTM_STATUS_RUNNING)
	    {
		TRACE0(CONFIGURATION, "Error ip sample already stopped");
		dwErr = ERROR_CAN_NOT_COMPLETE;

		break;
	    }

	/*
	 * Set XORPRTM's status to STOPPING; this prevents any more work
	 * items from being queued, and it prevents the ones already
	 * queued from executing.
	 */
        g_ce.iscStatus = XORPRTM_STATUS_STOPPING;

	/*
         * find out how many threads are either queued or active in XORPRTM;
         * we will have to wait for this many threads to exit before we
         * clean up XORPRTM's resources.
	 */
        ulThreadCount = g_ce.ulActivityCount;
        TRACE2(CONFIGURATION, "%u threads are active in %s", ulThreadCount,
	       XORPRTM_LOGNAME);
    } while (FALSE);

    RELEASE_WRITE_LOCK(&(g_ce.rwlLock));

    if (dwErr == NO_ERROR) {
        bSuccess = QueueUserWorkItem(
            (LPTHREAD_START_ROUTINE)CM_WorkerFinishStopProtocol,
            (PVOID) ulThreadCount,
            0); /* no flags */
        dwErr = (bSuccess) ? ERROR_PROTOCOL_STOP_PENDING : GetLastError();
    }

    return dwErr;
}
예제 #13
0
static void
lookup_service_async (GResolver           *resolver,
                      const char          *rrname,
		      GCancellable        *cancellable,
                      GAsyncReadyCallback  callback,
		      gpointer             user_data)
{
  GWin32ResolverRequest *req;

  req = g_win32_resolver_request_new (resolver, free_lookup_service,
                                      cancellable, callback, user_data,
                                      lookup_service_async);
  req->u.service.rrname = g_strdup (rrname);

  QueueUserWorkItem (lookup_service_in_thread, req, 0);
}
예제 #14
0
void NWNMSClient::RequestServerList(int roomId)
{
	fprintf(logFile, "Creating thread...\n");
	fflush(logFile);

	this->currentRoom = roomId;

	// params is virusman's struct for tracking client object and roomid :)
	// imo I would of thought malloc is better but I guess MS is smart enough enough not to delete 
	// at end of function when using their QueueUserWorkItem (a ref to the allocated memory)
	RequestThreadParams *params = new RequestThreadParams;
	params->client = this;
	params->roomId = roomId;
	// that last NULL parameter is the same as WT_EXECUTEDEFAULT... good grief..
	QueueUserWorkItem((LPTHREAD_START_ROUTINE) NWNMSClient::RequestThread, params, NULL);
}
예제 #15
0
void 
CDismountAllDialog::QueueEjectWorkItemCallback(WORK_ITEM_PARAM& WiParam)
{
	int itemIndex = m_deviceListView.GetItemCount();

	m_deviceListView.InsertItem(itemIndex, _T("Dismounting"));
	m_deviceListView.AddItem(itemIndex, 1, WiParam.DisplayName);

	BOOL success = QueueUserWorkItem(WorkItemStart, &WiParam, WT_EXECUTEDEFAULT);
	if (!success)
	{
		ATLTRACE("QueueUserWorkItem failed, error=0x%X\n", GetLastError());
		--m_workItemCount;
		ATLASSERT(FALSE && "QueueUserWorkItem failed");
	}
}
예제 #16
0
static void HTTPProxy_OutputFrom_InputTo(HTTPProxy *proxy)
{
	AMessage *msg = proxy->openmsg;
	proxy->openmsg = NULL;

	aobject_addref(&proxy->object);
	QueueUserWorkItem(HTTPProxy_OutputTo_InputFrom, &proxy->object, 0);

	amsg_init(&proxy->inmsg, AMsgType_Unknown, proxy->indata, sizeof(proxy->indata));
	amsg_copy(&proxy->inmsg, msg->type, msg->data, msg->size);

	proxy->inmsg.data[proxy->inmsg.size] = '\0';
	OutputDebugStringA(proxy->inmsg.data);

	aobject_addref(&proxy->object);
	HTTPProxyOutputFrom(&proxy->inmsg, 1);
}
예제 #17
0
int iocp::iocp_open(int thread_count)
{
	m_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
	if(!m_iocp)
	{
		m_error = GetLastError();
		printf("iocp initialize failed!\n");
		return 0;
	}
	m_thread_count = thread_count;
	for(int i = 0; i < m_thread_count; ++i)
	{
		QueueUserWorkItem(iocp_threaad_pro, this, WT_EXECUTELONGFUNCTION);
	}
	CreateSemaphore(NULL, 0, m_thread_count, NULL);
	return 1;
}
예제 #18
0
파일: tty.c 프로젝트: hghazal/node
static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
  uv_req_t* req;
  BOOL r;

  assert(handle->flags & UV_HANDLE_READING);
  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
  assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);

  req = &handle->read_req;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  handle->read_line_buffer = handle->alloc_cb((uv_handle_t*) handle, 8192);
  assert(handle->read_line_buffer.base != NULL);
  assert(handle->read_line_buffer.len > 0);

  /* Duplicate the console handle, so if we want to cancel the read, we can */
  /* just close this handle duplicate. */
  if (handle->read_line_handle == NULL) {
    HANDLE this_process = GetCurrentProcess();
    r = DuplicateHandle(this_process,
                        handle->handle,
                        this_process,
                        &handle->read_line_handle,
                        0,
                        0,
                        DUPLICATE_SAME_ACCESS);
    if (!r) {
      handle->read_line_handle = NULL;
      SET_REQ_ERROR(req, GetLastError());
      uv_insert_pending_req(loop, req);
      goto out;
    }
  }

  r = QueueUserWorkItem(uv_tty_line_read_thread,
                        (void*) req,
                        WT_EXECUTELONGFUNCTION);
  if (!r) {
    SET_REQ_ERROR(req, GetLastError());
    uv_insert_pending_req(loop, req);
  }

 out:
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
}
예제 #19
0
static void
lookup_by_address_async (GResolver           *resolver,
                         GInetAddress        *address,
                         GCancellable        *cancellable,
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
{
  GWin32ResolverRequest *req;

  req = g_win32_resolver_request_new (resolver, free_lookup_by_address,
                                      cancellable, callback, user_data,
                                      lookup_by_address_async);

  req->u.address.iaddr = g_object_ref (address);
  _g_resolver_address_to_sockaddr (address, &req->u.address.addr,
                                   &req->u.address.addrlen);
  req->u.address.namebuf = g_malloc (NI_MAXHOST);

  QueueUserWorkItem (lookup_by_addresses_in_thread, req, 0);
}
예제 #20
0
int _tmain(int argc, _TCHAR* argv[])
{
	printf("代理服务器正在启动\n");
	printf("初始化...\n");
	if (!InitSocket())
	{
		printf("socket初始化失败\n");
		return -1;
	}
	printf("代理服务器正在运行,监听端口 %d\n", ProxyPort);

	SOCKET acceptSocket = INVALID_SOCKET;
	ProxyParam *lpProxyParam;
	//HANDLE hThread;
	//DWORD dwThreadID;

	//代理服务器不断监听
	while (true)
	{
		acceptSocket = accept(ProxyServer, NULL, NULL);
		lpProxyParam = new ProxyParam;
		if (lpProxyParam == NULL)
		{
			continue;
		}
		lpProxyParam->clientSocket = acceptSocket;

		//hThread = (HANDLE)_beginthreadex(NULL, 0, &ProxyThread, (LPVOID)lpProxyParam, 0, 0);

		QueueUserWorkItem((LPTHREAD_START_ROUTINE)ProxyThread, (LPVOID)lpProxyParam, WT_EXECUTEINLONGTHREAD);

		//CloseHandle(hThread);

		Sleep(200);
	}

	closesocket(ProxyServer);
	WSACleanup();
	//system("pause");
	return 0;
}
예제 #21
0
void CDismountDialog::OnCmdRetry(UINT NotifyCode, int ID, HWND hWndCtl)
{
	ATLASSERT(WAIT_OBJECT_0 == WaitForSingleObject(m_WorkItemFinished, 0));

	//
	// Start the work item
	//

	m_cancelButton.ShowWindow(SW_HIDE);
	m_retryButton.ShowWindow(SW_HIDE);
	m_progressBarCtl.SetMarquee(TRUE, 50);
	m_progressBarCtl.ShowWindow(SW_SHOW);
	m_messageText.SetWindowText(m_staticMessage);

	ResetEvent(m_WorkItemFinished);
	BOOL success = QueueUserWorkItem(WorkItemStart, this, WT_EXECUTEDEFAULT);
	if (!success)
	{
		ATLTRACE("QueueUserWorkItem failed, error=0x%X\n", GetLastError());
		EndDialog(IDCANCEL);
	}
}
예제 #22
0
bool
CNdasService::Impl::StartWorkItems(DWORD& nStarted)
{
	nStarted = 0;
	if (!QueueUserWorkItem(m_wiHeartbeatListener, m_cHeartbeatListener)) 
	{
		return false;
	}
	++nStarted;
	if (!QueueUserWorkItem(m_wiAutoRegProcess, m_cAutoRegProcessor)) 
	{
		return false;
	}
	++nStarted;
	if (!QueueUserWorkItem(m_wiIXBCaster, m_cIXBCaster)) 
	{
		return false;
	} 
	++nStarted;
	if (!QueueUserWorkItem(m_wiIXServer, m_cIXServer)) 
	{
		return false;
	}
	++nStarted;
	if (!QueueUserWorkItem(m_wiHIXServer, m_cHIXServer)) 
	{
		return false;
	} 
	++nStarted;
	if (!QueueUserWorkItem(m_wiEventMonitor, m_cEventMonitor)) 
	{
		return false;
	}
	++nStarted;
	if (!QueueUserWorkItem(m_wiEventPublisher, m_cEventPublisher)) 
	{
		return false;
	}
	++nStarted;
	return true;
}
예제 #23
0
/*
* Entry point for getnameinfo
* return 0 if a callback will be made
* return error code if validation fails
*/
int uv_getnameinfo(uv_loop_t* loop,
                   uv_getnameinfo_t* req,
                   uv_getnameinfo_cb getnameinfo_cb,
                   const struct sockaddr* addr,
                   int flags) {
  if (req == NULL || getnameinfo_cb == NULL || addr == NULL)
    return UV_EINVAL;

  if (addr->sa_family == AF_INET) {
    memcpy(&req->storage,
           addr,
           sizeof(struct sockaddr_in));
  } else if (addr->sa_family == AF_INET6) {
    memcpy(&req->storage,
           addr,
           sizeof(struct sockaddr_in6));
  } else {
    return UV_EINVAL;
  }

  uv_req_init(loop, (uv_req_t*)req);

  req->getnameinfo_cb = getnameinfo_cb;
  req->flags = flags;
  req->type = UV_GETNAMEINFO;
  req->loop = loop;

  /* Ask thread to run. Treat this as a long operation. */
  if (QueueUserWorkItem(&getnameinfo_thread_proc,
                        req,
                        WT_EXECUTELONGFUNCTION) == 0) {
    return uv_translate_sys_error(GetLastError());
  }

  uv__req_register(loop, req);

  return 0;
}
예제 #24
0
LRESULT 
CDismountDialog::OnInitDialog(HWND hWnd, LPARAM lParam)
{
	m_closeQueued = FALSE;
	m_WorkItemFinished = CreateEvent(NULL, TRUE, TRUE, FALSE);
	ATLASSERT(NULL != m_WorkItemFinished);

	m_pLogDevice = *reinterpret_cast<ndas::LogicalDevicePtr*>(lParam);
	CenterWindow();

	m_messageText.Attach(GetDlgItem(IDC_WAIT_UNMOUNT_MESSAGE));
	m_messageText.GetWindowText(m_staticMessage, 256);

	// m_progressBarCtl.Attach(GetDlgItem(IDC_PROGRESS1));
	m_progressBarCtl.SubclassWindow(GetDlgItem(IDC_PROGRESS1));
	m_cancelButton.Attach(GetDlgItem(IDCANCEL));
	m_retryButton.Attach(GetDlgItem(IDRETRY));

	m_hWaitCursor = LoadCursor(NULL, IDC_WAIT);

	//
	// Start the work item
	//
	m_progressBarCtl.SetMarquee(TRUE, 50);
	m_cancelButton.ShowWindow(SW_HIDE);
	m_retryButton.ShowWindow(SW_HIDE);

	ATLVERIFY( ResetEvent(m_WorkItemFinished) );
	BOOL success = QueueUserWorkItem(WorkItemStart, this, WT_EXECUTEDEFAULT);
	if (!success)
	{
		ATLTRACE("QueueUserWorkItem failed, error=0x%X\n", GetLastError());
		EndDialog(IDCANCEL);
		return TRUE;
	}

	return TRUE;
}
void
CNdasDevicePropGeneralPage::_UpdateUnitDeviceData(
	ndas::UnitDevicePtr pUnitDevice)
{
	pUnitDevice->UpdateStatus();
	pUnitDevice->UpdateInfo();

	m_hCursor = AtlLoadSysCursor(IDC_APPSTARTING);
	SetCursor(m_hCursor);

	int index = pUnitDevice->GetUnitNo();

	UpdateThreadParam* param = new UpdateThreadParam();
	if (NULL == param)
	{
		return;
	}
	param->Instance = this;
	param->UnitIndex = index;

	m_ThreadCount++;

	BOOL success = QueueUserWorkItem(
		spUpdateThreadStart, 
		param, 
		WT_EXECUTEDEFAULT);

	if (!success)
	{
		delete param;

		ATLVERIFY(PostMessage(
			WM_THREADED_WORK_COMPLETED, 0, static_cast<LPARAM>(index)));

		return;
	}
}
예제 #26
0
LRESULT
CounterHintOnInitDialog(
	IN HWND hWnd,
	IN UINT uMsg,
	IN WPARAM wp,
	IN LPARAM lp
	)
{
	HWND hWndBar;
    PDIALOG_OBJECT Object;
	WCHAR Buffer[MAX_PATH];
	PCOUNTERHINT_CONTEXT Context;

	hWndBar = GetDlgItem(hWnd, IDC_PROGRESS);
	SendMessage(hWndBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
	SendMessage(hWndBar, PBM_SETSTEP, 10, 0); 
	
	SetWindowText(hWnd, L"D Probe");

    Object = (PDIALOG_OBJECT)SdkGetObject(hWnd);
	Context = (PCOUNTERHINT_CONTEXT)Object->Context;
	Context->NumberToScan = MspGetRecordCount(Context->DtlObject);
	Context->ScannedNumber = 0;

	QueueUserWorkItem(CounterScanWorkItem, Context, 
		              WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION);

	StringCchPrintf(Buffer, MAX_PATH, L"Scanning %u records ...", 
		            Context->NumberToScan);

	SetDlgItemText(hWnd, IDC_STATIC, Buffer);
	
    SetTimer(hWnd, 1, 1000, NULL);
	SdkCenterWindow(hWnd);
	return 0;
}
예제 #27
0
/*
 * Entry point for getaddrinfo
 * we convert the UTF-8 strings to UNICODE
 * and save the UNICODE string pointers in the handle
 * We also copy hints so that caller does not need to keep memory until the
 * callback.
 * return UV_OK if a callback will be made
 * return error code if validation fails
 *
 * To minimize allocation we calculate total size required,
 * and copy all structs and referenced strings into the one block.
 * Each size calculation is adjusted to avoid unaligned pointers.
 */
int uv_getaddrinfo(uv_loop_t* loop,
                   uv_getaddrinfo_t* handle,
                   uv_getaddrinfo_cb getaddrinfo_cb,
                   const char* node,
                   const char* service,
                   const struct addrinfo* hints) {
  int nodesize = 0;
  int servicesize = 0;
  int hintssize = 0;
  char* alloc_ptr = NULL;

  if (handle == NULL || getaddrinfo_cb == NULL ||
     (node == NULL && service == NULL)) {
    uv__set_sys_error(loop, WSAEINVAL);
    goto error;
  }

  uv_req_init(loop, (uv_req_t*)handle);

  handle->getaddrinfo_cb = getaddrinfo_cb;
  handle->res = NULL;
  handle->type = UV_GETADDRINFO;
  handle->loop = loop;

  /* calculate required memory size for all input values */
  if (node != NULL) {
    nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
    if (nodesize == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
  }

  if (service != NULL) {
    servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
                               sizeof(wchar_t));
    if (servicesize == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
  }
  if (hints != NULL) {
    hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
  }

  /* allocate memory for inputs, and partition it as needed */
  alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
  if (!alloc_ptr) {
    uv__set_sys_error(loop, WSAENOBUFS);
    goto error;
  }

  /* save alloc_ptr now so we can free if error */
  handle->alloc = (void*)alloc_ptr;

  /* convert node string to UTF16 into allocated memory and save pointer in */
  /* handle */
  if (node != NULL) {
    handle->node = (wchar_t*)alloc_ptr;
    if (uv_utf8_to_utf16(node,
                         (wchar_t*) alloc_ptr,
                         nodesize / sizeof(wchar_t)) == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
    alloc_ptr += nodesize;
  } else {
    handle->node = NULL;
  }

  /* convert service string to UTF16 into allocated memory and save pointer */
  /* in handle */
  if (service != NULL) {
    handle->service = (wchar_t*)alloc_ptr;
    if (uv_utf8_to_utf16(service,
                         (wchar_t*) alloc_ptr,
                         servicesize / sizeof(wchar_t)) == 0) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
    alloc_ptr += servicesize;
  } else {
    handle->service = NULL;
  }

  /* copy hints to allocated memory and save pointer in handle */
  if (hints != NULL) {
    handle->hints = (struct addrinfoW*)alloc_ptr;
    handle->hints->ai_family = hints->ai_family;
    handle->hints->ai_socktype = hints->ai_socktype;
    handle->hints->ai_protocol = hints->ai_protocol;
    handle->hints->ai_flags = hints->ai_flags;
    handle->hints->ai_addrlen = 0;
    handle->hints->ai_canonname = NULL;
    handle->hints->ai_addr = NULL;
    handle->hints->ai_next = NULL;
  } else {
    handle->hints = NULL;
  }

  /* init request for Post handling */
  uv_req_init(loop, &handle->getadddrinfo_req);
  handle->getadddrinfo_req.data = handle;
  handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ;

  /* Ask thread to run. Treat this as a long operation */
  if (QueueUserWorkItem(&getaddrinfo_thread_proc,
                        handle,
                        WT_EXECUTELONGFUNCTION) == 0) {
    uv__set_sys_error(loop, GetLastError());
    goto error;
  }

  uv_ref(loop);

  return 0;

error:
  if (handle != NULL && handle->alloc != NULL) {
    free(handle->alloc);
  }
  return -1;
}
예제 #28
0
static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
  uv_read_t* req;
  int result;

  assert(handle->flags & UV_HANDLE_READING);
  assert(!(handle->flags & UV_HANDLE_READ_PENDING));

  assert(handle->handle != INVALID_HANDLE_VALUE);

  req = &handle->read_req;

  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
    if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
                           req,
                           WT_EXECUTELONGFUNCTION)) {
      /* Make this req pending reporting an error. */
      SET_REQ_ERROR(req, GetLastError());
      goto error;
    }
  } else {
    memset(&req->overlapped, 0, sizeof(req->overlapped));
    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
    }

    /* Do 0-read */
    result = ReadFile(handle->handle,
                      &uv_zero_,
                      0,
                      NULL,
                      &req->overlapped);

    if (!result && GetLastError() != ERROR_IO_PENDING) {
      /* Make this req pending reporting an error. */
      SET_REQ_ERROR(req, GetLastError());
      goto error;
    }

    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      if (!req->event_handle) {
        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
        if (!req->event_handle) {
          uv_fatal_error(GetLastError(), "CreateEvent");
        }
      }
      if (req->wait_handle == INVALID_HANDLE_VALUE) {
        if (!RegisterWaitForSingleObject(&req->wait_handle,
            req->overlapped.hEvent, post_completion_read_wait, (void*) req,
            INFINITE, WT_EXECUTEINWAITTHREAD)) {
          SET_REQ_ERROR(req, GetLastError());
          goto error;
        }
      }
    }
  }

  /* Start the eof timer if there is one */
  eof_timer_start(handle);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
  return;

error:
  uv_insert_pending_req(loop, (uv_req_t*)req);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
}
예제 #29
0
void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int errorno, nameSize;
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  DWORD duplex_flags;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
  handle->name = (WCHAR*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
    errorno = GetLastError();
    goto error;
  }

  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
  if (pipeHandle == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
                             req,
                             WT_EXECUTELONGFUNCTION)) {
        errorno = GetLastError();
        goto error;
      }

      REGISTER_HANDLE_REQ(loop, handle, req);
      handle->reqs_pending++;

      return;
    }

    errorno = GetLastError();
    goto error;
  }

  assert(pipeHandle != INVALID_HANDLE_VALUE);

  if (uv_set_pipe_handle(loop,
                         (uv_pipe_t*) req->handle,
                         pipeHandle,
                         duplex_flags)) {
    errorno = GetLastError();
    goto error;
  }

  SET_REQ_SUCCESS(req);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }

  /* Make this req pending reporting an error. */
  SET_REQ_ERROR(req, errorno);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;
}
예제 #30
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);
  }
}