int IOCP::Create(void) { int iHandle; HANDLE hnd; hnd = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if ( hnd == NULL ) { return -1; } iHandle = UniqueCount :: GetUniqueCount(); iocp.insert( MapWordToPtr::value_type( iHandle, hnd ) ); return iHandle; }
static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) { DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { return -1; } if (CreateIoCompletionPort(pipeHandle, LOOP->iocp, (ULONG_PTR)handle, 0) == NULL) { return -1; } return 0; }
bool IOCP_Manager::Initialize() { SYSTEM_INFO SystemInfo; GetSystemInfo(&SystemInfo); mIoThreadCount = SystemInfo.dwNumberOfProcessors * 2; WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf_s("WSAStartup Error\n"); return false; } mCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, mIoThreadCount); if (mCompletionPort == NULL) { printf_s("Create CompletionPort error\n"); return false; } mListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED); if (mListenSocket == INVALID_SOCKET) { printf_s("Create ListenSocket Error\n"); return false; } int opt = 1; setsockopt(mListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int)); SOCKADDR_IN ServerAddr; int SizeServerAddr = sizeof(SOCKADDR_IN); memset(&ServerAddr, 0, SizeServerAddr); if (WSAStringToAddress(L"127.0.0.1:9001", AF_INET, NULL, (SOCKADDR*)&ServerAddr, &SizeServerAddr) == SOCKET_ERROR) { printf_s("ServerAddress Setting Error\n"); return false; } if (bind(mListenSocket, (SOCKADDR*)&ServerAddr, SizeServerAddr) == SOCKET_ERROR) { printf_s("Bind Error\n"); return false; } return true; }
int SP_IocpLFServer :: run() { int ret = 0; int listenFD = -1; ret = SP_IOUtils::tcpListen( mBindIP, mPort, &listenFD, 0 ); if( 0 == ret ) { mCompletionHandler = mAcceptArg->mHandlerFactory->createCompletionHandler(); SP_IocpMsgQueue * msgQueue = new SP_IocpMsgQueue( mEventArg->getCompletionPort(), SP_IocpEventCallback::eKeyMsgQueue, SP_IocpEventCallback::onResponse, mEventArg ); mEventArg->setResponseQueue( msgQueue ); mEventArg->loadDisconnectEx( listenFD ); mAcceptArg->mAcceptEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); mAcceptArg->mListenSocket = (HANDLE)listenFD; if( NULL == CreateIoCompletionPort( mAcceptArg->mListenSocket, mEventArg->getCompletionPort(), SP_IocpEventCallback::eKeyAccept, 0 ) ) { sp_syslog( LOG_ERR, "CreateIoCompletionPort fail, errno %d", WSAGetLastError() ); return -1; } if( NULL == mAcceptArg->mIOChannelFactory ) { mAcceptArg->mIOChannelFactory = new SP_DefaultIOChannelFactory(); } sp_thread_t thread; ret = sp_thread_create( &thread, NULL, acceptThread, mAcceptArg ); if( 0 == ret ) { sp_syslog( LOG_NOTICE, "Thread #%ld has been created to accept socket", thread ); } else { sp_syslog( LOG_WARNING, "Unable to create a thread to accept socket, %s", strerror( errno ) ); return -1; } mIsRunning = 1; mThreadPool = new SP_ThreadPool( mMaxThreads ); for( int i = 0; i < mMaxThreads; i++ ) { mThreadPool->dispatch( lfHandler, this ); } } return ret; }
static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle, SOCKET socket, int imported) { DWORD yes = 1; assert(handle->socket == INVALID_SOCKET); /* Set the socket to nonblocking mode */ if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { uv__set_sys_error(loop, WSAGetLastError()); return -1; } /* Make the socket non-inheritable */ if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { uv__set_sys_error(loop, GetLastError()); return -1; } /* Associate it with the I/O completion port. */ /* Use uv_handle_t pointer as completion key. */ if (CreateIoCompletionPort((HANDLE)socket, loop->iocp, (ULONG_PTR)socket, 0) == NULL) { if (imported) { handle->flags |= UV_HANDLE_EMULATE_IOCP; } else { uv__set_sys_error(loop, GetLastError()); return -1; } } if (pSetFileCompletionNotificationModes) { if (pSetFileCompletionNotificationModes((HANDLE) socket, FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; } else if (GetLastError() != ERROR_INVALID_FUNCTION) { uv__set_sys_error(loop, GetLastError()); return -1; } } handle->socket = socket; return 0; }
EVQ_API int evq_add (struct event_queue *evq, struct event *ev) { const unsigned int ev_flags = ev->flags; struct win32thr *wth = &evq->head; ev->wth = wth; if (ev_flags & EVENT_SIGNAL) return signal_add(evq, ev); if (ev_flags & EVENT_WINMSG) { evq->win_msg = ev; evq->nevents++; return 0; } if ((ev_flags & (EVENT_SOCKET | EVENT_SOCKET_ACC_CONN)) == EVENT_SOCKET && evq->iocp.h) { if (!CreateIoCompletionPort((HANDLE) ev->fd, evq->iocp.h, 0, 0) && GetLastError() != ERROR_INVALID_PARAMETER) /* already assosiated */ return -1; ev->flags |= EVENT_AIO; evq->iocp.n++; evq->nevents++; if (pSetFileCompletionNotificationModes && pSetFileCompletionNotificationModes((HANDLE) ev->fd, 3)) ev->flags |= EVENT_AIO_SKIP; win32iocp_set(ev, ev_flags); return 0; } while (wth->n >= NEVENT - 1) if (!(wth = wth->next)) break; if (wth) win32thr_sleep(wth); else { wth = win32thr_init(evq); if (!wth) return -1; } return win32thr_add(wth, ev); }
CIOCPManager::CIOCPManager(int IOCPThreadCount /*= 0*/) { SOCKET TmpSock; GUID guidAcceptEx = WSAID_ACCEPTEX; GUID guidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS; DWORD dwBytes; INT i; OutputDebugStr(_T("IOCPManager::IOCPManager\n")); // 使用 2.2版的WS2_32.DLL if (WSAStartup(0x0202, &mwsaData) != 0) { throw exception("WSAStartup Fails"); } // 获取AcceptEx和GetAcceptExSockaddrs的函数指针 TmpSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (TmpSock == INVALID_SOCKET) { throw exception("WSASocket Fails"); } if (SOCKET_ERROR == WSAIoctl(TmpSock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptEx, sizeof(guidAcceptEx), &g_AcceptEx, sizeof(g_AcceptEx), &dwBytes, NULL, NULL)) { throw exception("WSAIoctl WSAID_ACCEPTEX Fails"); } if (SOCKET_ERROR == WSAIoctl(TmpSock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidGetAcceptExSockaddrs, sizeof(guidGetAcceptExSockaddrs), &g_GetAcceptExSockaddrs, sizeof(g_GetAcceptExSockaddrs), &dwBytes, NULL, NULL)) { throw exception("WSAIoctl WSAID_GETACCEPTEXSOCKADDRS Fails"); } closesocket(TmpSock); // 初始化临界区 InitializeCriticalSection(&mSockListCS); InitializeCriticalSection(&mOverLappedListCS); // 初始化IOCP完成端口 mCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); if (IOCPThreadCount <= 0) { SYSTEM_INFO SysInfo; GetSystemInfo(&SysInfo); IOCPThreadCount = SysInfo.dwNumberOfProcessors + 2; } mIocpWorkThreadCount = IOCPThreadCount; mIocpWorkThreads = new HANDLE[mIocpWorkThreadCount]; // 创建IOCP工作线程 for (i = 0; i < mIocpWorkThreadCount; i++) { mIocpWorkThreads[i] = (HANDLE)_beginthreadex(NULL, 0, IocpWorkThread, (PVOID)mCompletionPort, 0, NULL); if (mIocpWorkThreads[i] == NULL) { throw exception("CreateThread FIocpWorkThreads Fails"); } } }
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; }
void mpk_import_add_named_pipe_instance(common_vars *common_vars) { HANDLE named_pipe_handle = CreateNamedPipeA("\\\\.\\pipe\\" m_mpk_import_named_pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, nullptr); if (!named_pipe_handle) { m_last_error_str(err); m_die("cannot create mpk import named pipe instance, call to \"CreateNamedPipeA\" failed\nerr: %s", err); } HANDLE io_completion_port = CreateIoCompletionPort(named_pipe_handle, common_vars->io_completion_port, mpk_import_named_pipe_event, 0); if (!io_completion_port) { m_last_error_str(err_str); m_die("cannot connect mpk import named pipe to io completion port, call to \"CreateIoCompletionPort\" failed\nerr: %s", err_str); } mpk_import_named_pipe_instance *new_named_pipe_instance = (mpk_import_named_pipe_instance *)memory_pool_allocate(&common_vars->mpk_import_named_pipe_instance_memory_pool); *new_named_pipe_instance = {}; new_named_pipe_instance->handle = named_pipe_handle; sllist_push(&common_vars->mpk_import_named_pipe_instance_list, new_named_pipe_instance); ConnectNamedPipe(named_pipe_handle, &new_named_pipe_instance->overlapped); }
bool ClientSession::PostConnect() { CRASH_ASSERT( LThreadType == THREAD_MAIN ); HANDLE handle = CreateIoCompletionPort( (HANDLE)mSocket, GIocpManager->GetComletionPort(), ( ULONG_PTR )this, 0 ); if ( handle != GIocpManager->GetComletionPort() ) { printf_s( "[DEBUG] CreateIoCompletionPort error: %d\n", GetLastError() ); return false; } OverlappedConnectContext* connectContext = new OverlappedConnectContext( this ); DWORD bytes = 0; connectContext->mWsaBuf.len = 0; connectContext->mWsaBuf.buf = nullptr; if ( SERVER_PORT <= 4000 || SERVER_PORT > 10000 ) { SERVER_PORT = 9001; } if ( HOST_NAME.length() == 0 ) { HOST_NAME = "127.0.0.1"; } sockaddr_in addr; ZeroMemory( &addr, sizeof( addr ) ); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr( HOST_NAME.c_str() ); addr.sin_port = htons( SERVER_PORT ); if ( FALSE == IocpManager::ConnectEx( mSocket, (SOCKADDR*)&addr, sizeof( addr ), GIocpManager->mConnectBuf, 0, &bytes, (LPOVERLAPPED)connectContext ) ) { if ( WSAGetLastError() != WSA_IO_PENDING ) { DeleteIoContext( connectContext ); printf_s( "ConnectEx Error : %d\n", GetLastError() ); return false; } } return true; }
VOID Acceptor::Init( IoHandler *pIoHandler, DWORD dwNumberOfThreads ) { assert( dwNumberOfThreads <= MAX_ACCEPT_THREAD ); m_pIoHandler = pIoHandler; m_numThreads = dwNumberOfThreads; // Accept 创建IOCP m_hIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0 ); // 遍历, 创建线程 unsigned threadID; for( DWORD i = 0; i < m_numThreads; ++i ) { m_hThread[i] = (HANDLE)_beginthreadex( NULL, 0, accept_thread, (LPVOID)this, 0/*CREATE_SUSPENDED*/, &threadID ); } }
bool ClientSession::OnConnect(SOCKADDR_IN* addr) { //TODO: 이 영역 lock으로 보호 할 것 FastSpinlockGuard tempLock(mLock); CRASH_ASSERT(LThreadType == THREAD_MAIN_ACCEPT); /// make socket non-blocking u_long arg = 1 ; ioctlsocket(mSocket, FIONBIO, &arg) ; /// turn off nagle int opt = 1 ; setsockopt(mSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(int)) ; opt = 0; if (SOCKET_ERROR == setsockopt(mSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(int)) ) { printf_s("[DEBUG] SO_RCVBUF change error: %d\n", GetLastError()) ; return false; } HANDLE handle = CreateIoCompletionPort( (HANDLE)mSocket, GIocpManager->GetCompletionPort(), (ULONG_PTR)this, 0 ); //TODO: 여기에서 CreateIoCompletionPort((HANDLE)mSocket, ...);사용하여 연결할 것 if (handle != GIocpManager->GetCompletionPort()) { printf_s("[DEBUG] CreateIoCompletionPort error: %d\n", GetLastError()); return false; } memcpy(&mClientAddr, addr, sizeof(SOCKADDR_IN)); mConnected = true ; printf_s("[DEBUG] Client Connected: IP=%s, PORT=%d\n", inet_ntoa(mClientAddr.sin_addr), ntohs(mClientAddr.sin_port)); GSessionManager->IncreaseConnectionCount(); return PostRecv() ; }
struct event_iocp_port * event_iocp_port_launch(void) { struct event_iocp_port *port; int i; if (!extension_fns_initialized) init_extension_functions(&the_extension_fns); if (!(port = mm_calloc(1, sizeof(struct event_iocp_port)))) return NULL; port->n_threads = 2; port->threads = calloc(port->n_threads, sizeof(HANDLE)); if (!port->threads) goto err; port->port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, port->n_threads); port->ms = -1; if (!port->port) goto err; port->shutdownSemaphore = CreateSemaphore(NULL, 0, 1, NULL); if (!port->shutdownSemaphore) goto err; for (i=0; i<port->n_threads; ++i) { uintptr_t th = _beginthread(loop, 0, port); if (th == (uintptr_t)-1) goto err; port->threads[i] = (HANDLE)th; ++port->n_live_threads; } InitializeCriticalSection(&port->lock); return port; err: if (port->port) CloseHandle(port->port); if (port->threads) mm_free(port->threads); if (port->shutdownSemaphore) CloseHandle(port->shutdownSemaphore); mm_free(port); return NULL; }
CConnection* CNetManager::AssociateCompletePort( SOCKET hSocket ) { CConnection *pConnection = CConnectionMgr::GetInstancePtr()->CreateConnection(); pConnection->SetSocket(hSocket); pConnection->SetDataHandler(m_pBufferHandler); if(NULL == CreateIoCompletionPort((HANDLE)hSocket, m_hCompletePort, (ULONG_PTR)pConnection, 0)) { pConnection->Close(FALSE); return NULL; } return pConnection; }
NS_IMETHODIMP NamedPipeService::AddDataObserver(void* aHandle, nsINamedPipeDataObserver* aObserver) { if (!aHandle || aHandle == INVALID_HANDLE_VALUE || !aObserver) { return NS_ERROR_ILLEGAL_VALUE; } nsresult rv; HANDLE h = CreateIoCompletionPort(aHandle, mIocp, reinterpret_cast<ULONG_PTR>(aObserver), 1); if (NS_WARN_IF(!h)) { LOG_NPS_ERROR("CreateIoCompletionPort error (%d)", GetLastError()); return NS_ERROR_FAILURE; } if (NS_WARN_IF(h != mIocp)) { LOG_NPS_ERROR("CreateIoCompletionPort got unexpected value %p (should be %p)", h, mIocp); CloseHandle(h); return NS_ERROR_FAILURE; } { MutexAutoLock lock(mLock); MOZ_ASSERT(!mObservers.Contains(aObserver)); mObservers.AppendElement(aObserver); // start event loop if (mObservers.Length() == 1) { rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL); if (NS_WARN_IF(NS_FAILED(rv))) { LOG_NPS_ERROR("Dispatch to thread failed (%08x)", rv); mObservers.Clear(); return rv; } } } return NS_OK; }
static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle, HANDLE pipeHandle, DWORD duplex_flags) { NTSTATUS nt_status; IO_STATUS_BLOCK io_status; FILE_MODE_INFORMATION mode_info; DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { /* If this returns ERROR_INVALID_PARAMETER we probably opened something */ /* that is not a pipe. */ if (GetLastError() == ERROR_INVALID_PARAMETER) { SetLastError(WSAENOTSOCK); } return -1; } /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */ nt_status = pNtQueryInformationFile(pipeHandle, &io_status, &mode_info, sizeof(mode_info), FileModeInformation); if (nt_status != STATUS_SUCCESS) { return -1; } if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT || mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) { /* Non-overlapped pipe. */ handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE; } else { /* Overlapped pipe. Try to associate with IOCP. */ if (CreateIoCompletionPort(pipeHandle, loop->iocp, (ULONG_PTR)handle, 0) == NULL) { handle->flags |= UV_HANDLE_EMULATE_IOCP; } } handle->handle = pipeHandle; handle->flags |= duplex_flags; return 0; }
void GProcThrd_Create(void) { if(bGProcThrdThreadIsActive) return; DWORD dwNP = GWkrThrd_GetNumberOfProcessors(); if(!dwGProcThrdThreadNumber) dwGProcThrdThreadNumber = dwNP * 2 + 2; if(dwGProcThrdThreadNumber < dwNP) dwGProcThrdThreadNumber = dwNP; hGProcThrdThreadCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, dwGProcThrdThreadNumber); if(NULL == hGProcThrdThreadCompletionPort) { GLog_Write("GProcThrd_Create:完成端口句柄创建失败"); return; } pGProcThrdThreadAddr = (PGTHREAD)GMem_Alloc(dwGProcThrdThreadNumber * sizeof(GTHREAD)); if(!pGProcThrdThreadAddr) { dwGProcThrdThreadNumber = 0; CloseHandle(hGProcThrdThreadCompletionPort); GLog_Write("GProcThrd_Create:从GMem分配工作者内存失败"); return; } DWORD i; PGTHREAD pThread; pThread = pGProcThrdThreadAddr; for(i = 0; i < dwGProcThrdThreadNumber; i++) { GThrd_CreateThread(pThread, GTHREAD_TYPE_IOCP, "处理者", &GProcesserThreadProc); if(!pThread->dwThreadId) { GLog_Write("GProcThrd_Create:创建处理者线程失败"); return; } pThread = pThread + 1; } bGProcThrdThreadIsActive = TRUE; }
DWORD WINAPI AcceptThread(LPVOID lpParameter) { int nLen = sizeof(SOCKADDR_IN); SOCKET Accept; SOCKADDR_IN Address; while (TRUE) { Accept = accept(g_gcSock, (struct sockaddr FAR *)&Address, &nLen); if (g_fTerminated) return 0; CGateInfo* pGateInfo = new CGateInfo; if (pGateInfo) { pGateInfo->sock = Accept; CreateIoCompletionPort((HANDLE)pGateInfo->sock, g_hIOCP, (DWORD)pGateInfo, 0); if (g_xGateList.AddNewNode(pGateInfo)) { int zero = 0; setsockopt(pGateInfo->sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero) ); pGateInfo->Recv(); UpdateStatusBar(TRUE); #ifdef _DEBUG TCHAR szGateIP[256]; wsprintf(szGateIP, _T("%d.%d.%d.%d"), Address.sin_addr.s_net, Address.sin_addr.s_host, Address.sin_addr.s_lh, Address.sin_addr.s_impno); InsertLogMsgParam(IDS_ACCEPT_GATESERVER, szGateIP); #endif } } } return 0; }
//=========================================================================== void NtInitialize () { // ensure initialization only occurs once if (s_running) return; s_running = true; // create a cleanup event s_waitEvent = CreateEvent( (LPSECURITY_ATTRIBUTES) 0, true, // manual reset false, // initial state off (LPCTSTR) nil // name ); if (!s_waitEvent) ErrorAssert(__LINE__, __FILE__, "CreateEvent %#x", GetLastError()); // create IO completion port if (0 == (s_ioPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0))) ErrorAssert(__LINE__, __FILE__, "CreateIoCompletionPort %#x", GetLastError()); // calculate number of IO worker threads to create if (!s_pageSizeMask) { SYSTEM_INFO si; GetSystemInfo(&si); s_pageSizeMask = si.dwPageSize - 1; // Set worker thread count s_ioThreadCount = si.dwNumberOfProcessors * 2; if (s_ioThreadCount > kMaxWorkerThreads) { s_ioThreadCount = kMaxWorkerThreads; LogMsg(kLogError, "kMaxWorkerThreads too small!"); } } // create IO worker threads for (long thread = 0; thread < s_ioThreadCount; thread++) { s_ioThreadHandles[thread] = (HANDLE) AsyncThreadCreate( NtWorkerThreadProc, (void *) thread, L"NtWorkerThread" ); } INtSocketInitialize(); }
HRESULT CFileWatcher::Initialize(IHttpContext* context) { HRESULT hr; ErrorIf(NULL == (this->completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1)), GetLastError()); this->uncFileSharePollingInterval = CModuleConfiguration::GetUNCFileChangesPollingInterval(context); return S_OK; Error: if (NULL != this->completionPort) { CloseHandle(this->completionPort); this->completionPort = NULL; } return hr; }
IOCP::OperationDataPtr IOCP::CreateOperationData(IOCPStreamPtr stream, HANDLE completionPort) { // Begin to process I/O using overlapped I/O // Post one or many WSARecv or WSASend requests to the new socket // Worker thread will serve the I/O request after the I/O request finished. IOCP::OperationData* perIOData = new IOCP::OperationData(); perIOData->stream = stream.get(); // Relate the socket to CompletionPort CreateIoCompletionPort((HANDLE)(perIOData->stream->GetNativeSocket()), completionPort, (ULONG_PTR)perIOData->stream->GetNativeSocket(), 0); ZeroMemory(&(perIOData->overlapped), sizeof(OVERLAPPED)); perIOData->databuff.len = BUFSIZ; perIOData->databuff.buf = perIOData->buffer; perIOData->operationType = IOCP::OperationType::Read; return IOCP::OperationDataPtr(perIOData); }
void IoCompletionPortScheduler::registerDevice( SharedRandomAccessDevice pDevice) { int hFile = pDevice->getHandle(); if (hFile == -1) { return; } if (!CreateIoCompletionPort( HANDLE(hFile), hCompletionPort, 0, threads.size())) { throw SysCallExcn("CreateIoCompletionPort failed for device"); } // REVIEW: is it OK to do nothing for unregister? }
void CIOCPort::CreateClientWorkerThread() { HANDLE hWorkerThread[MAX_USER]; DWORD WorkerId[MAX_USER]; m_hClientIOCPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 10 ); for(int i=0; i<(int)m_dwConcurrency; i++) { hWorkerThread[i] = ::CreateThread( NULL, 0, ClientWorkerThread, (LPVOID)this, 0, &WorkerId[i] ); } }
void EasyIocp::InitIocp() { //创建完成端口 hCompPort_ = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if(!hCompPort_) { ErrorSysMessage("EasyIocp::Construct: CreateIoCompletionPort failed."); } assert(hCompPort_ != NULL); print("EasyIocp::InitIocp: init IOCP successfully."); //设置服务器ip地址 memset(&bindAddr_, 0, sizeof(bindAddr_)); GetDefaultAddr(&bindAddr_); bindAddr_.sin_port = htons(EASYIOCP_DEFAULT_PORT); InitThreadPool(); }
DWORD VmDnsSockWinEventQueueAdd( PVM_SOCK_EVENT_QUEUE pQueue, PVM_SOCKET pSocket ) { DWORD dwError = 0; BOOLEAN bLocked = TRUE; int sockError = 0; HANDLE hTemp = NULL; if (!pQueue || !pSocket || pSocket->hSocket == INVALID_SOCKET) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } hTemp = CreateIoCompletionPort( (HANDLE)pSocket->hSocket, pQueue->hIOCP, 0, 0); if (hTemp != pQueue->hIOCP) { dwError = GetLastError(); BAIL_ON_VMDNS_ERROR(dwError); } sockError = WSAEventSelect( pSocket->hSocket, pQueue->hEventListen, FD_ACCEPT); BAIL_ON_VMDNS_ERROR(dwError); pSocket->pEventQueue = pQueue; cleanup: return dwError; error: goto cleanup; }
static void enable_write(EVENT_KERNEL *ev, ACL_EVENT_FDTABLE *fdp) { const char *myname = "enable_write"; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(fdp->stream); DWORD sendBytes; fdp->flag &= ~EVENT_FDTABLE_FLAG_ADD_WRITE; fdp->flag |= EVENT_FDTABLE_FLAG_WRITE; if (fdp->h_iocp == NULL) { fdp->h_iocp = CreateIoCompletionPort((HANDLE) sockfd, ev->h_iocp, (DWORD) fdp, 0); if (fdp->h_iocp != ev->h_iocp) acl_msg_fatal("%s(%d): CreateIoCompletionPort error(%s)", myname, __LINE__, acl_last_serror()); fdp->flag |= EVENT_FDTABLE_FLAG_IOCP; } if (fdp->event_write == NULL) { fdp->event_write = (IOCP_EVENT*) acl_mymalloc(sizeof(IOCP_EVENT)); fdp->event_write->fdp = fdp; } else if (fdp->event_write->type == IOCP_EVENT_WRITE) { return; } fdp->event_write->type = IOCP_EVENT_WRITE; if ((fdp->stream->flag & ACL_VSTREAM_FLAG_CONNECTING)) { enable_connect(ev, fdp); fdp->stream->flag &= ~ACL_VSTREAM_FLAG_CONNECTING; return; } memset(&fdp->event_write->overlapped, 0, sizeof(fdp->event_write->overlapped)); if (WriteFile((HANDLE) sockfd, NULL, 0, &sendBytes, &fdp->event_write->overlapped) == FALSE && acl_last_error() != ERROR_IO_PENDING) { acl_msg_warn("%s(%d): WriteFile error(%s), sockfd(%d)", myname, __LINE__, acl_last_serror(), sockfd); } }
// AcceptThread Method DWORD cIocpServer::AcceptThread( ) { while ( true ) { PerSocketContext* perSocketContext = NULL; PerIoContext* perIoContext = NULL; SOCKET socket; SOCKADDR_IN addr; int addrlen; addrlen = sizeof( addr ); socket = WSAAccept( mSocket, (sockaddr*)&addr, &addrlen, NULL, 0 ); if ( socket == SOCKET_ERROR ) break; if ( mEndServer == true ) break; perSocketContext = mSocketContextPool->GetPerSocketContext( socket, addr, MAX_TTL ); if ( perSocketContext == NULL ) break; // Accept completion port. if ( CreateIoCompletionPort( (HANDLE)socket, mIocp, (ULONG_PTR)perSocketContext, 0 ) == NULL ) break; if ( AcceptComplete( perSocketContext ) == false ) { // SocketContext . mSocketContextPool->ReleasePerSocketContext( perSocketContext ); continue; } // I/O Context. perIoContext = mIoContextPool->GetIoContext( perSocketContext->socket, IOCP_REQUEST_READ ); if ( RecvPost( perIoContext ) == false ) { GameErrorLog("¹Ø±ÕÌ×½Ó×Ö,%d,%s,%s\n",__LINE__,__FILE__,__FUNCTION__); Close( perSocketContext ); continue; } } return 0; }
CHANNEL accept(ACCEPTOR ap){ channelimpl * ch = pool::objpool<channelimpl>::allocator(1); new (ch)channelimpl(((acceptorimlp*)((handle*)ap))->que, ((acceptorimlp*)((handle*)ap))->sa); setsockopt(ch->s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&((acceptorimlp*)((handle*)ap))->sl, sizeof(((acceptorimlp*)((handle*)ap))->sl)); unsigned long ul = 1; if (ioctlsocket(ch->s, FIONBIO, (unsigned long *)&ul) == SOCKET_ERROR){ } CreateIoCompletionPort((HANDLE)ch->s, ((queueimpl*)((handle*)ch->que))->iocp, 0, 0); { WSABUF * wsabuf = pool::objpool<WSABUF>::allocator(1); wsabuf->buf = ch->buf; wsabuf->len = ch->buflen; DWORD bytes = 0; DWORD flags = 0; overlappedex * ovp = pool::objpool<overlappedex>::allocator(1); new (ovp)overlappedex(); ovp->h = (handle*)ch; ovp->com_type = iocp_type_ipv4_tcp; ovp->event_type = type_recv; OVERLAPPED * ovp_ = static_cast<OVERLAPPED *>(ovp); memset(ovp_, 0, sizeof(OVERLAPPED)); WSARecv(ch->s, wsabuf, 1, &bytes, &flags, ovp_, 0); } { ((acceptorimlp*)((handle*)ap))->sa = socket(AF_INET, SOCK_STREAM, 0); memset(((acceptorimlp*)((handle*)ap))->outbuf, 0, sizeof(((acceptorimlp*)((handle*)ap))->outbuf)); overlappedex * ovlp = pool::objpool<overlappedex>::allocator(1); new (ovlp)overlappedex(); ovlp->h = (handle*)ap; ovlp->com_type = iocp_type_ipv4_tcp; ovlp->event_type = type_accept; OVERLAPPED * ovp_ = static_cast<OVERLAPPED *>(ovlp); memset(ovp_, 0, sizeof(OVERLAPPED)); AcceptEx(((acceptorimlp*)((handle*)ap))->sl, ((acceptorimlp*)((handle*)ap))->sa, ((acceptorimlp*)((handle*)ap))->outbuf, 0, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, 0, ovp_); } return (CHANNEL)((handle*)ch); }
bool CTCPIOCP::Connect(char* ip, int port) { if (m_socket != INVALID_SOCKET || m_lpAcceptData != NULL) { return false; } if (port <= 0 || port > 65535) { return false; } _InitIOCP(); m_isConnector = true; m_socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); ZeroMemory(&m_addr, sizeof(SOCKADDR_IN)); m_addr.sin_family = AF_INET; m_addr.sin_addr.s_addr = inet_addr(ip); m_addr.sin_port = htons(port); if (connect(m_socket, (sockaddr*)&m_addr, sizeof(m_addr)) == SOCKET_ERROR) { OnConnectER(ip, port, GetLastError()); closesocket(m_socket); m_socket = INVALID_SOCKET; return false; } m_lpAcceptData = CreateAcceptData(m_socket, m_addr); m_lpAcceptData->OwnerID = 85643; //关联重叠I/O完成端口。 CreateIoCompletionPort((HANDLE)m_socket, m_completionPort, (DWORD)m_lpAcceptData, 0); OnConnectOK(m_lpAcceptData); _RecvAsync(m_lpAcceptData); return true; }
//클라이언트의ㅡaccept를 담당할 쓰레드 UINT AcceptThread( LPVOID lParam ){ SERVER_INFO* serverInfo = (SERVER_INFO*)lParam; OVERLAPPED ov; while(TRUE) { //SOCKET clientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//이렇게 프로토콜만 결정된상태 SOCKET clientSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); char temp[1024]; DWORD dwRecv; //이건사실안나온다. 억셉트ex는 비동기함수라 바로 밑으로 빠져나간다. 그래서 dwRecv에 값이 들어갈수가없다. 형식적인거. memset(&ov, 0, sizeof(ov)); AcceptEx(*serverInfo->hServSock, clientSocket, temp, 0, sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwRecv, &ov); //첫번째 listensocket, 서버소켓만들고바인드하고리슨까지한거,그다음은 acceptsocket //그럼 이제 시스템이 내부적으로 클라이언트가 connect할때까지 기다린다. //우리는 클라이언트가 커넥트하면 clientSocket가지고 링크드리스트에 집어넣고 이런작업해야한다. //근데 얘는 언제끝날지 모른다. 그래서 WaitForSingleObject((HANDLE)*serverInfo->hServSock, INFINITE); //이렇게 클라이언트가 connect할때까지 기다리는거다. //SOCKADDR_IN의 더블포인터가 필요하다. SOCKADDR_IN * pLocal; SOCKADDR_IN * pAddr; int iLocalLen = sizeof(SOCKADDR_IN); int iRemoteLen = sizeof(SOCKADDR_IN); GetAcceptExSockaddrs(temp, 0, sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, (sockaddr **)&pLocal, &iLocalLen, (sockaddr **)&pAddr, &iRemoteLen); //이 temp에 정보가 다 들어있다. CreateIoCompletionPort((HANDLE)clientSocket, *serverInfo->hComPort, (DWORD)clientSocket, 0); //세번째 파라미터가 RecvFunc에 dwCompKey로 간다. //이렇게 하면 소켓이 아까 만든 껍데기에 등록이 된다. 처음에 한명이 접근해서 하나가 등록이 된다. EnterCriticalSection(&myCS2); //client 등록 serverInfo->mCToonVasServerDlg->AddClient(clientSocket, *pAddr); LeaveCriticalSection(&myCS2); } return 0; }