overlap.cpp File Reference#include "lspdef.h" #include <stdio.h> #include <stdlib.h>
Include dependency graph for overlap.cpp:
![]() Go to the source code of this file.
Function Documentation
Definition at line 913 of file overlap.cpp. 00916 { 00917 LPWSAOVERLAPPEDPLUS lpWorkerOverlappedPlus = NULL; 00918 00919 if ( NULL == SocketContext ) 00920 { 00921 dbgprint("AllocOverlappedStructure: SocketContext is NULL!"); 00922 return NULL; 00923 } 00924 00925 EnterCriticalSection( &gOverlappedCS ); 00926 00927 AcquireSocketLock( SocketContext ); 00928 00929 // 00930 // We have to keep track of the number of outstanding overlapped requests 00931 // an application has. Otherwise, if the app were to close a socket that 00932 // had oustanding overlapped ops remaining, we'd start leaking structures 00933 // in gOverlappedPool. The idea here is to force the CallerSocket to remain 00934 // open until the lower provider has processed all the overlapped requests. 00935 // If we closed both the lower socket and the caller socket, we would no 00936 // longer be able to correlate completed requests to any apps sockets. 00937 // 00938 (SocketContext->dwOutstandingAsync)++; 00939 00940 if ( IsListEmpty( &gFreeOverlappedPlus ) ) 00941 { 00942 int err; 00943 00944 lpWorkerOverlappedPlus = (WSAOVERLAPPEDPLUS *) LspAlloc( 00945 sizeof(WSAOVERLAPPEDPLUS), 00946 &err 00947 ); 00948 } 00949 else 00950 { 00951 LIST_ENTRY *entry = NULL; 00952 00953 entry = RemoveHeadList( &gFreeOverlappedPlus ); 00954 00955 lpWorkerOverlappedPlus = CONTAINING_RECORD( entry, WSAOVERLAPPEDPLUS, Link ); 00956 } 00957 00958 ReleaseSocketLock( SocketContext ); 00959 00960 LeaveCriticalSection( &gOverlappedCS ); 00961 00962 return lpWorkerOverlappedPlus; 00963 }
Definition at line 1255 of file overlap.cpp. 01258 { 01259 LPOVERLAPPED lpOverlapped; 01260 LPWSAOVERLAPPED_COMPLETION_ROUTINE UserCompletionRoutine; 01261 01262 lpOverlapped = (LPOVERLAPPED) Context; 01263 UserCompletionRoutine = (LPWSAOVERLAPPED_COMPLETION_ROUTINE)lpOverlapped->Internal; 01264 lpOverlapped->Internal = 0; // Remove the WSS_OPERATION_IN_PROGRESS value 01265 01266 UserCompletionRoutine( 01267 (DWORD)lpOverlapped->OffsetHigh, 01268 (DWORD)lpOverlapped->InternalHigh, 01269 lpOverlapped, 01270 (DWORD)lpOverlapped->Offset 01271 ); 01272 return; 01273 }
Definition at line 1285 of file overlap.cpp. 01288 { 01289 SOCK_INFO *SocketContext = NULL; 01290 int Error, 01291 ret; 01292 01293 SocketContext = FindAndRefSocketContext( ol->CallerSocket, &Error ); 01294 if ( NULL == SocketContext ) 01295 { 01296 dbgprint( "CheckForContextCleanup: FindAndRefSocketContext failed!" ); 01297 return; 01298 } 01299 01300 EnterCriticalSection( &gCriticalSection ); 01301 01302 AcquireSocketLock( ol->SockInfo ); 01303 01304 (ol->SockInfo->dwOutstandingAsync)--; 01305 01306 if ( ( TRUE == ol->SockInfo->bClosing ) && 01307 ( 0 == ol->SockInfo->dwOutstandingAsync ) && 01308 ( 1 == ol->SockInfo->RefCount ) 01309 ) 01310 { 01311 // 01312 // If the calling app closed the socket while there were still outstanding 01313 // async operations then all the outstanding operations have completed so 01314 // we can close the apps socket handle. 01315 // 01316 ret = gMainUpCallTable.lpWPUCloseSocketHandle( 01317 ol->CallerSocket, 01318 &ol->Error 01319 ); 01320 if ( SOCKET_ERROR == ret ) 01321 { 01322 dbgprint("CheckForContextClenaup: WPUCloseSocketHandle() failed: %d", ol->Error); 01323 } 01324 01325 ol->SockInfo->LayeredSocket = INVALID_SOCKET; 01326 01327 RemoveSocketInfo( ol->SockInfo->Provider, ol->SockInfo ); 01328 01329 dbgprint("CheckForContxtCleanup: Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]", 01330 ol->CallerSocket, ol->SockInfo->BytesSent, ol->SockInfo->BytesRecv); 01331 01332 ReleaseSocketLock( ol->SockInfo ); 01333 01334 ol->SockInfo = NULL; 01335 01336 FreeSockInfo( SocketContext ); 01337 01338 goto cleanup; 01339 } 01340 01341 ReleaseSocketLock( ol->SockInfo ); 01342 01343 DerefSocketContext( SocketContext, &Error ); 01344 01345 cleanup: 01346 01347 LeaveCriticalSection( &gCriticalSection ); 01348 01349 return; 01350 }
Definition at line 472 of file overlap.cpp. 00474 { 00475 WSAOVERLAPPEDPLUS *op = NULL; 00476 LIST_ENTRY *link = NULL; 00477 00478 EnterCriticalSection( &gOverlappedCS ); 00479 00480 link = RemoveHeadList( &gPendingOperations ); 00481 00482 op = CONTAINING_RECORD( link, WSAOVERLAPPEDPLUS, Link ); 00483 00484 /* 00485 op = gPendingStart; 00486 if ( NULL != gPendingStart ) 00487 { 00488 gPendingStart = op->next; 00489 } 00490 if (op == gPendingEnd) 00491 { 00492 gPendingStart = gPendingEnd = NULL; 00493 } 00494 */ 00495 00496 LeaveCriticalSection( &gOverlappedCS ); 00497 00498 return op; 00499 }
Definition at line 433 of file overlap.cpp. 00436 { 00437 int ret = WSA_IO_PENDING; 00438 00439 EnterCriticalSection( &gOverlappedCS ); 00440 00441 if ( NULL == op ) 00442 { 00443 dbgprint("EnqueueOverlappedOperation: op == NULL!"); 00444 ret = WSAEFAULT; 00445 goto cleanup; 00446 } 00447 00448 InsertTailList( &gPendingOperations, &op->Link ); 00449 00450 // 00451 // Increment the semaphore count. This lets the worker thread 00452 // know that there are pending overlapped operations to execute. 00453 // 00454 ReleaseSemaphore( gWakeupSemaphore, 1, NULL ); 00455 00456 cleanup: 00457 00458 LeaveCriticalSection( &gOverlappedCS ); 00459 00460 return ret; 00461 }
Definition at line 512 of file overlap.cpp. 00516 { 00517 LPWSAOVERLAPPED_COMPLETION_ROUTINE routine = NULL; 00518 PROVIDER *Provider; 00519 DWORD *lpdwFlags = NULL, 00520 *lpdwBytes = NULL; 00521 int ret=SOCKET_ERROR, err=0; 00522 00523 if ( NULL == gIocp) 00524 routine = IntermediateCompletionRoutine; 00525 00526 Provider = ol->Provider; 00527 00528 // 00529 // Reset the event handle if present. The handle is masked with 0xFFFFFFFE in 00530 // order to zero out the last bit. If the last bit is one and the socket is 00531 // associated with a compeltion port then when an overlapped operation is 00532 // called, the operation is not posted to the IO completion port. 00533 // 00534 if ( NULL != ol->lpCallerOverlapped->hEvent ) 00535 { 00536 ULONG_PTR ptr = 1; 00537 00538 ResetEvent( (HANDLE) ( (ULONG_PTR) ol->lpCallerOverlapped->hEvent & ~ptr ) ); 00539 } 00540 00541 switch ( ol->Operation ) 00542 { 00543 case LSP_OP_IOCTL: 00544 lpdwFlags = NULL; 00545 lpdwBytes = &ol->IoctlArgs.cbBytesReturned; 00546 ret = Provider->NextProcTable.lpWSPIoctl( 00547 ol->ProviderSocket, 00548 ol->IoctlArgs.dwIoControlCode, 00549 ol->IoctlArgs.lpvInBuffer, 00550 ol->IoctlArgs.cbInBuffer, 00551 ol->IoctlArgs.lpvOutBuffer, 00552 ol->IoctlArgs.cbOutBuffer, 00553 &ol->IoctlArgs.cbBytesReturned, 00554 &ol->ProviderOverlapped, 00555 routine, 00556 &ol->CallerThreadId, 00557 &err 00558 ); 00559 break; 00560 00561 case LSP_OP_RECV: 00562 lpdwFlags = &ol->RecvArgs.dwFlags; 00563 lpdwBytes = &ol->RecvArgs.dwNumberOfBytesRecvd; 00564 ret = Provider->NextProcTable.lpWSPRecv( 00565 ol->ProviderSocket, 00566 ol->RecvArgs.lpBuffers, 00567 ol->RecvArgs.dwBufferCount, 00568 &ol->RecvArgs.dwNumberOfBytesRecvd, 00569 &ol->RecvArgs.dwFlags, 00570 &ol->ProviderOverlapped, 00571 routine, 00572 &ol->CallerThreadId, 00573 &err 00574 ); 00575 break; 00576 00577 case LSP_OP_RECVFROM: 00578 lpdwFlags = &ol->RecvFromArgs.dwFlags; 00579 lpdwBytes = &ol->RecvFromArgs.dwNumberOfBytesRecvd; 00580 ret = Provider->NextProcTable.lpWSPRecvFrom( 00581 ol->ProviderSocket, 00582 ol->RecvFromArgs.lpBuffers, 00583 ol->RecvFromArgs.dwBufferCount, 00584 &ol->RecvFromArgs.dwNumberOfBytesRecvd, 00585 &ol->RecvFromArgs.dwFlags, 00586 ol->RecvFromArgs.lpFrom, 00587 ol->RecvFromArgs.lpFromLen, 00588 &ol->ProviderOverlapped, 00589 routine, 00590 &ol->CallerThreadId, 00591 &err 00592 ); 00593 break; 00594 00595 case LSP_OP_SEND: 00596 lpdwFlags = &ol->SendArgs.dwFlags; 00597 lpdwBytes = &ol->SendArgs.dwNumberOfBytesSent; 00598 ret = Provider->NextProcTable.lpWSPSend( 00599 ol->ProviderSocket, 00600 ol->SendArgs.lpBuffers, 00601 ol->SendArgs.dwBufferCount, 00602 &ol->SendArgs.dwNumberOfBytesSent, 00603 ol->SendArgs.dwFlags, 00604 &ol->ProviderOverlapped, 00605 routine, 00606 &ol->CallerThreadId, 00607 &err 00608 ); 00609 break; 00610 00611 case LSP_OP_SENDTO: 00612 lpdwFlags = &ol->SendToArgs.dwFlags; 00613 lpdwBytes = &ol->SendToArgs.dwNumberOfBytesSent; 00614 ret = Provider->NextProcTable.lpWSPSendTo( 00615 ol->ProviderSocket, 00616 ol->SendToArgs.lpBuffers, 00617 ol->SendToArgs.dwBufferCount, 00618 &ol->SendToArgs.dwNumberOfBytesSent, 00619 ol->SendToArgs.dwFlags, 00620 (SOCKADDR *)&ol->SendToArgs.To, 00621 ol->SendToArgs.iToLen, 00622 &ol->ProviderOverlapped, 00623 routine, 00624 &ol->CallerThreadId, 00625 &err 00626 ); 00627 break; 00628 00629 case LSP_OP_TRANSMITFILE: 00630 lpdwFlags = &ol->TransmitFileArgs.dwFlags; 00631 lpdwBytes = NULL; 00632 ret = Provider->NextProcTableExt.lpfnTransmitFile( 00633 ol->ProviderSocket, 00634 ol->TransmitFileArgs.hFile, 00635 ol->TransmitFileArgs.nNumberOfBytesToWrite, 00636 ol->TransmitFileArgs.nNumberOfBytesPerSend, 00637 &ol->ProviderOverlapped, 00638 ol->TransmitFileArgs.lpTransmitBuffers, 00639 ol->TransmitFileArgs.dwFlags 00640 ); 00641 if ( FALSE == ret ) 00642 { 00643 ret = SOCKET_ERROR; 00644 err = WSAGetLastError(); 00645 WSASetLastError(err); 00646 } 00647 else 00648 { 00649 ret = NO_ERROR; 00650 } 00651 break; 00652 00653 case LSP_OP_ACCEPTEX: 00654 lpdwFlags = NULL; 00655 lpdwBytes = &ol->AcceptExArgs.dwBytesReceived; 00656 ret = Provider->NextProcTableExt.lpfnAcceptEx( 00657 ol->ProviderSocket, 00658 ol->AcceptExArgs.sProviderAcceptSocket, 00659 ol->AcceptExArgs.lpOutputBuffer, 00660 ol->AcceptExArgs.dwReceiveDataLength, 00661 ol->AcceptExArgs.dwLocalAddressLength, 00662 ol->AcceptExArgs.dwRemoteAddressLength, 00663 &ol->AcceptExArgs.dwBytesReceived, 00664 &ol->ProviderOverlapped 00665 ); 00666 if ( FALSE == ret ) 00667 { 00668 ret = SOCKET_ERROR; 00669 err = WSAGetLastError(); 00670 WSASetLastError(err); 00671 } 00672 else 00673 { 00674 ret = NO_ERROR; 00675 } 00676 break; 00677 00678 case LSP_OP_CONNECTEX: 00679 lpdwFlags = NULL; 00680 lpdwBytes = &ol->ConnectExArgs.dwBytesSent; 00681 ret = Provider->NextProcTableExt.lpfnConnectEx( 00682 ol->ProviderSocket, 00683 (SOCKADDR *)&ol->ConnectExArgs.name, 00684 ol->ConnectExArgs.namelen, 00685 ol->ConnectExArgs.lpSendBuffer, 00686 ol->ConnectExArgs.dwSendDataLength, 00687 &ol->ConnectExArgs.dwBytesSent, 00688 &ol->ProviderOverlapped 00689 ); 00690 if ( FALSE == ret ) 00691 { 00692 ret = SOCKET_ERROR; 00693 err = WSAGetLastError(); 00694 WSASetLastError(err); 00695 } 00696 else 00697 { 00698 ret = NO_ERROR; 00699 } 00700 break; 00701 00702 case LSP_OP_DISCONNECTEX: 00703 lpdwFlags = &ol->DisconnectExArgs.dwFlags; 00704 lpdwBytes = NULL; 00705 ret = Provider->NextProcTableExt.lpfnDisconnectEx( 00706 ol->ProviderSocket, 00707 &ol->ProviderOverlapped, 00708 ol->DisconnectExArgs.dwFlags, 00709 ol->DisconnectExArgs.dwReserved 00710 ); 00711 if ( FALSE == ret ) 00712 { 00713 ret = SOCKET_ERROR; 00714 err = WSAGetLastError(); 00715 WSASetLastError(err); 00716 } 00717 else 00718 { 00719 ret = NO_ERROR; 00720 } 00721 break; 00722 00723 case LSP_OP_TRANSMITPACKETS: 00724 lpdwFlags = &ol->TransmitPacketsArgs.dwFlags; 00725 lpdwBytes = NULL; 00726 ret = Provider->NextProcTableExt.lpfnTransmitPackets( 00727 ol->ProviderSocket, 00728 ol->TransmitPacketsArgs.lpPacketArray, 00729 ol->TransmitPacketsArgs.nElementCount, 00730 ol->TransmitPacketsArgs.nSendSize, 00731 &ol->ProviderOverlapped, 00732 ol->TransmitPacketsArgs.dwFlags 00733 ); 00734 if ( FALSE == ret ) 00735 { 00736 ret = SOCKET_ERROR; 00737 err = WSAGetLastError(); 00738 WSASetLastError(err); 00739 } 00740 else 00741 { 00742 ret = NO_ERROR; 00743 } 00744 break; 00745 00746 case LSP_OP_WSARECVMSG: 00747 lpdwFlags = NULL; 00748 lpdwBytes = &ol->WSARecvMsgArgs.dwNumberOfBytesRecvd; 00749 ret = Provider->NextProcTableExt.lpfnWSARecvMsg( 00750 ol->ProviderSocket, 00751 ol->WSARecvMsgArgs.lpMsg, 00752 &ol->WSARecvMsgArgs.dwNumberOfBytesRecvd, 00753 &ol->ProviderOverlapped, 00754 routine 00755 ); 00756 if ( SOCKET_ERROR == ret ) 00757 { 00758 err = WSAGetLastError(); 00759 WSASetLastError( err ); 00760 } 00761 else 00762 { 00763 ret = NO_ERROR; 00764 } 00765 break; 00766 00767 default: 00768 dbgprint("ExecuteOverlappedOperation: Unknown operation!"); 00769 ret = SOCKET_ERROR; 00770 break; 00771 } 00772 00773 if ( ( NO_ERROR != ret ) && ( WSA_IO_PENDING != err ) ) 00774 { 00775 // 00776 // If the call immediately fails, update the OVERLAPPED info and return 00777 // 00778 ol->lpCallerOverlapped->Offset = (lpdwFlags ? *lpdwFlags : 0); 00779 ol->lpCallerOverlapped->OffsetHigh = err; 00780 ol->lpCallerOverlapped->InternalHigh = (lpdwBytes ? *lpdwBytes : 0); 00781 ol->lpCallerOverlapped->Internal = 0; 00782 00783 dbgprint("Overlap op failed immediately: %d", ol->Error); 00784 00785 CheckForContextCleanup( ol ); 00786 00787 FreeOverlappedStructure( ol ); 00788 } 00789 else if ( ( NO_ERROR == ret ) && ( FALSE == bSynchronous ) ) 00790 { 00791 // 00792 // NOTE: We could return success from here, but if you want to perform 00793 // some post processing on the data buffers before indicating 00794 // success to the upper layer (because once success is returned, the 00795 // upper layer can inspect the buffers). Because of this we return 00796 // pending and in the completion processing (either via IOCP or 00797 // APC), we can do post processing there. 00798 // 00799 err = WSA_IO_PENDING; 00800 ret = SOCKET_ERROR; 00801 } 00802 else if ( ( NO_ERROR == ret ) && ( TRUE == bSynchronous ) ) 00803 { 00804 // The winsock call actually blocked and there will be no completion 00805 // notification on the IOCP. 00806 // 00807 dbgprint("Succeeded without error - synchronous socket though"); 00808 } 00809 00810 return ( ( NO_ERROR == ret ) ? ret : err ); 00811 }
Definition at line 1545 of file overlap.cpp. 01547 { 01548 WSAOVERLAPPEDPLUS *olp = NULL; 01549 LIST_ENTRY *entry = NULL; 01550 01551 EnterCriticalSection( &gOverlappedCS ); 01552 01553 while ( ! IsListEmpty( &gFreeOverlappedPlus ) ) 01554 { 01555 entry = RemoveHeadList( &gFreeOverlappedPlus ); 01556 01557 olp = CONTAINING_RECORD( entry, WSAOVERLAPPEDPLUS, Link ); 01558 01559 LspFree( olp ); 01560 } 01561 01562 LeaveCriticalSection( &gOverlappedCS ); 01563 }
Definition at line 973 of file overlap.cpp. 00976 { 00977 EnterCriticalSection( &gOverlappedCS ); 00978 00979 switch ( olp->Operation ) 00980 { 00981 case LSP_OP_RECV: 00982 FreeWSABuf( olp->RecvArgs.lpBuffers ); 00983 break; 00984 00985 case LSP_OP_RECVFROM: 00986 FreeWSABuf( olp->RecvFromArgs.lpBuffers ); 00987 break; 00988 00989 case LSP_OP_SEND: 00990 FreeWSABuf( olp->SendArgs.lpBuffers ); 00991 break; 00992 00993 case LSP_OP_SENDTO: 00994 FreeWSABuf( olp->SendToArgs.lpBuffers ); 00995 break; 00996 00997 default: 00998 break; 00999 } 01000 01001 memset( olp, 0, sizeof( WSAOVERLAPPEDPLUS ) ); 01002 01003 InsertHeadList( &gFreeOverlappedPlus, &olp->Link ); 01004 01005 LeaveCriticalSection( &gOverlappedCS ); 01006 }
Definition at line 127 of file overlap.cpp. 00129 { 00130 DWORD i; 00131 int ret = NO_ERROR; 00132 00133 EnterCriticalSection( &gOverlappedCS ); 00134 00135 // 00136 // Make sure we're not already initialized -- we'll always have at least 00137 // one worker thread running 00138 // 00139 if ( NULL != gWorkerThread ) 00140 goto cleanup; 00141 00142 InitializeListHead( &gFreeOverlappedPlus ); 00143 InitializeListHead( &gPendingOperations ); 00144 00145 // 00146 // See if we're on NT by trying to create the completion port. If it 00147 // fails then we're on Win9x. 00148 // 00149 gIocp = CreateIoCompletionPort( 00150 INVALID_HANDLE_VALUE, 00151 NULL, 00152 (ULONG_PTR)0, 00153 0 00154 ); 00155 if ( NULL != gIocp ) 00156 { 00157 SYSTEM_INFO sinfo; 00158 00159 // 00160 // We're on NT so figure out how many processors we have 00161 // 00162 GetSystemInfo( &sinfo ); 00163 gThreadCount = sinfo.dwNumberOfProcessors; 00164 } 00165 else 00166 { 00167 // 00168 // We're on Win9x so create a semaphore instead. This is used to 00169 // wake up the worker thread to service overlapped IO calls. 00170 // 00171 gWakeupSemaphore = CreateSemaphore( 00172 NULL, 00173 0, 00174 MAXLONG, 00175 NULL 00176 ); 00177 if ( NULL == gWakeupSemaphore ) 00178 { 00179 dbgprint("InitOverlappedManager: CreateSemaphore() failed: %d", GetLastError()); 00180 ret = WSAEPROVIDERFAILEDINIT; 00181 goto cleanup; 00182 } 00183 00184 // 00185 // This is Win9x, no multiproc support so create just a single thread 00186 // 00187 gThreadCount = 1; 00188 } 00189 00190 dbgprint("Creating %d threads", gThreadCount); 00191 00192 gWorkerThread = (HANDLE *) LspAlloc( 00193 sizeof( HANDLE ) * gThreadCount, 00194 &ret // if fails, ret will be WSAENOBUFS 00195 ); 00196 if ( NULL == gWorkerThread ) 00197 { 00198 goto cleanup; 00199 } 00200 00201 // 00202 // Create our worker threads 00203 // 00204 for(i=0; i < gThreadCount ;i++) 00205 { 00206 gWorkerThread[i] = CreateThread( 00207 NULL, 00208 0, 00209 OverlappedManagerThread, 00210 (LPVOID)gIocp, 00211 0, 00212 NULL 00213 ); 00214 if ( NULL == gWorkerThread[ i ] ) 00215 { 00216 dbgprint("InitOverlappedManager: CreateThread() failed: %d", GetLastError()); 00217 ret = WSAEPROVIDERFAILEDINIT; 00218 goto cleanup; 00219 } 00220 } 00221 00222 cleanup: 00223 00224 LeaveCriticalSection( &gOverlappedCS ); 00225 00226 return ret; 00227 }
Definition at line 1033 of file overlap.cpp. 01039 { 01040 LPWSAOVERLAPPEDPLUS olp = NULL; 01041 SOCK_INFO *SocketContext = NULL, 01042 *AcceptSocketContext = NULL; 01043 int Error, 01044 ret; 01045 01046 if ( NULL == lpOverlapped ) 01047 { 01048 dbgprint("IntermediateCompletionRoutine: lpOverlapped == NULL!"); 01049 goto cleanup; 01050 } 01051 01052 ASSERT( lpOverlapped ); 01053 01054 olp = CONTAINING_RECORD( lpOverlapped, WSAOVERLAPPEDPLUS, ProviderOverlapped ); 01055 01056 // 01057 // We actually already have the socket context for this operation (its in 01058 // the WSAOVERLAPPEDPLUS structure but do this anyway to make sure the 01059 // socket hasn't been closed as well as to increment the ref count while 01060 // we're accessing the SOCK_INFO structure. 01061 // 01062 SocketContext = FindAndRefSocketContext(olp->CallerSocket, &Error); 01063 if ( NULL == SocketContext ) 01064 { 01065 dbgprint( "IntermediateCompletionRoutine: FindAndRefSocketContext failed!" ); 01066 goto cleanup; 01067 } 01068 01069 if ( WSA_IO_PENDING == dwError ) 01070 { 01071 // 01072 // Get the results of the operation 01073 // 01074 01075 ASSERT( olp->Provider ); 01076 ASSERT( olp->Provider->NextProcTable.lpWSPGetOverlappedResult ); 01077 01078 dwError = NO_ERROR; 01079 ret = olp->Provider->NextProcTable.lpWSPGetOverlappedResult( 01080 olp->ProviderSocket, 01081 lpOverlapped, 01082 &cbTransferred, 01083 FALSE, 01084 &dwFlags, 01085 (int *)&dwError 01086 ); 01087 01088 if ( FALSE == ret ) 01089 { 01090 dbgprint("IntermediateCompletionRoutine: WSPGetOverlappedResult failed: %d", dwError); 01091 } 01092 else 01093 { 01094 01095 dbgprint("Bytes transferred on socket 0x%x: %d [op=%d; err=%d]", 01096 olp->CallerSocket, cbTransferred, olp->Operation, dwError); 01097 } 01098 } 01099 01100 olp->lpCallerOverlapped->Offset = dwFlags; 01101 olp->lpCallerOverlapped->OffsetHigh = dwError; 01102 olp->lpCallerOverlapped->InternalHigh = cbTransferred; 01103 01104 SocketContext->LastError = dwError; 01105 01106 if ( 0 == dwError ) 01107 { 01108 AcquireSocketLock( SocketContext ); 01109 01110 // 01111 // NOTE: This is where any post processing should go for overlapped operations. 01112 // For example, if you wanted to inspect the data received, you would do 01113 // that here for any operation that receives data (don't forget AcceptEx!). 01114 // In this sample, all we do is count the bytes sent and received on the 01115 // socket. 01116 // 01117 01118 switch ( olp->Operation ) 01119 { 01120 case LSP_OP_RECV: 01121 SocketContext->BytesRecv += cbTransferred; 01122 FreeWSABuf(olp->RecvArgs.lpBuffers); 01123 break; 01124 01125 case LSP_OP_RECVFROM: 01126 SocketContext->BytesRecv += cbTransferred; 01127 FreeWSABuf(olp->RecvFromArgs.lpBuffers); 01128 break; 01129 01130 case LSP_OP_SEND: 01131 SocketContext->BytesSent += cbTransferred; 01132 FreeWSABuf(olp->SendArgs.lpBuffers); 01133 break; 01134 01135 case LSP_OP_SENDTO: 01136 SocketContext->BytesSent += cbTransferred; 01137 FreeWSABuf(olp->SendToArgs.lpBuffers); 01138 break; 01139 01140 case LSP_OP_TRANSMITFILE: 01141 SocketContext->BytesSent += cbTransferred; 01142 break; 01143 01144 case LSP_OP_TRANSMITPACKETS: 01145 SocketContext->BytesSent += cbTransferred; 01146 break; 01147 01148 case LSP_OP_ACCEPTEX: 01149 01150 ReleaseSocketLock( SocketContext ); 01151 01152 AcceptSocketContext = FindAndRefSocketContext( 01153 olp->AcceptExArgs.sAcceptSocket, 01154 &Error 01155 ); 01156 if (AcceptSocketContext == NULL) 01157 { 01158 dbgprint( "IntermediateCompletionRoutine: FindAndRefSocketContext failed! (LSP_OP_ACCEPTEX)" ); 01159 } 01160 AcquireSocketLock( AcceptSocketContext ); 01161 01162 AcceptSocketContext->BytesRecv += cbTransferred; 01163 01164 ReleaseSocketLock( AcceptSocketContext ); 01165 01166 DerefSocketContext(AcceptSocketContext, &Error); 01167 01168 break; 01169 01170 case LSP_OP_CONNECTEX: 01171 SocketContext->BytesSent += cbTransferred; 01172 break; 01173 01174 case LSP_OP_WSARECVMSG: 01175 SocketContext->BytesRecv += cbTransferred; 01176 break; 01177 01178 default: 01179 break; 01180 } 01181 // Already released for AcceptEx operations 01182 if ( LSP_OP_ACCEPTEX != olp->Operation ) 01183 ReleaseSocketLock( SocketContext ); 01184 } 01185 01186 DerefSocketContext( SocketContext, &Error ); 01187 01188 if ( NULL != olp->lpCallerCompletionRoutine ) 01189 { 01190 // 01191 // If the app supplied a completion routine, queue it up for completion 01192 // 01193 olp->lpCallerOverlapped->Internal = (ULONG_PTR)olp->lpCallerCompletionRoutine; 01194 01195 ret = gMainUpCallTable.lpWPUQueueApc( 01196 &olp->CallerThreadId, 01197 CallUserApcProc, 01198 (DWORD_PTR) olp->lpCallerOverlapped, 01199 &Error 01200 ); 01201 if ( SOCKET_ERROR == ret ) 01202 { 01203 dbgprint("IntermediateCompletionRoutine: WPUQueueApc() failed: %d", Error); 01204 } 01205 } 01206 else 01207 { 01208 // 01209 // Otherwise we signal that the op has completed 01210 // 01211 ret = WPUCompleteOverlappedRequest( 01212 olp->CallerSocket, 01213 olp->lpCallerOverlapped, 01214 dwError, 01215 cbTransferred, 01216 &Error 01217 ); 01218 if ( SOCKET_ERROR == ret ) 01219 { 01220 dbgprint("WPUCompleteOverlappedRequest failed: %d (provider socket 0x%x)", 01221 Error, olp->CallerSocket ); 01222 } 01223 } 01224 01225 if ( ( NULL != olp ) && ( TRUE == olp->CloseThread ) ) 01226 { 01227 ret = gMainUpCallTable.lpWPUCloseThread( &olp->CallerThreadId, &Error ); 01228 if ( SOCKET_ERROR == ret ) 01229 { 01230 dbgprint("WPUCloseThread failed: %d", Error ); 01231 } 01232 olp->CloseThread = FALSE; 01233 } 01234 01235 // 01236 // Cleanup the accounting on the socket 01237 // 01238 CheckForContextCleanup( olp ); 01239 01240 cleanup: 01241 01242 if ( NULL != olp ) 01243 FreeOverlappedStructure( olp ); 01244 01245 return; 01246 }
Definition at line 822 of file overlap.cpp. 00825 { 00826 WSAOVERLAPPEDPLUS *pOverlapPlus = NULL; 00827 WSAOVERLAPPED *pOverlap = NULL; 00828 HANDLE hIocp = (HANDLE)lpParam; 00829 ULONG_PTR key; 00830 DWORD dwBytesXfered; 00831 int ret; 00832 00833 while ( TRUE ) 00834 { 00835 if ( NULL != hIocp ) 00836 { 00837 ret = GetQueuedCompletionStatus( 00838 hIocp, 00839 &dwBytesXfered, 00840 &key, 00841 &pOverlap, 00842 INFINITE 00843 ); 00844 if ( 0 == ret ) 00845 { 00846 // Socket failures could be reported here so we still 00847 // call IntermediateCompletionRoutine 00848 dbgprint("GetQueuedCompletionStatus() failed: %d", GetLastError()); 00849 } 00850 00851 if ( -1 == dwBytesXfered ) 00852 { 00853 // 00854 // StopOverlappedManager will send a completion packet with -1 00855 // bytes transfered to indicate the completion routine 00856 // should exit 00857 // 00858 dbgprint("OverlappedManagerThread: Received exit message"); 00859 goto cleanup; 00860 } 00861 00862 // Handle the IO that completed 00863 IntermediateCompletionRoutine( 00864 WSA_IO_PENDING, 00865 dwBytesXfered, 00866 pOverlap, 00867 0 00868 ); 00869 } 00870 else 00871 { 00872 ret = WaitForSingleObjectEx( 00873 gWakeupSemaphore, 00874 INFINITE, 00875 TRUE 00876 ); 00877 if ( WAIT_IO_COMPLETION == ret ) 00878 { 00879 // An APC fired so keep waiting until semaphore is signaled 00880 continue; 00881 } 00882 else if ( WAIT_OBJECT_0 == ret ) 00883 { 00884 pOverlapPlus = DequeueOverlappedOperation(); 00885 if ( NULL == pOverlapPlus ) 00886 continue; 00887 00888 ExecuteOverlappedOperation( pOverlapPlus, FALSE ); 00889 } 00890 else 00891 { 00892 dbgprint("OverlappedManagerThread: WaitForSingleObjectEx() failed: %d (error = %d)", 00893 ret, GetLastError() ); 00894 goto cleanup; 00895 } 00896 } 00897 } 00898 00899 cleanup: 00900 00901 ExitThread( 0 ); 00902 }
Definition at line 1361 of file overlap.cpp. 01371 { 01372 WSAOVERLAPPEDPLUS *ProviderOverlapped = NULL; 01373 int ret = SOCKET_ERROR, 01374 err = 0; 01375 01376 // Allocate a WSAOVERLAPPEDPLUS structure 01377 ProviderOverlapped = AllocOverlappedStructure( SocketContext ); 01378 if ( NULL == ProviderOverlapped ) 01379 { 01380 *lpErrno = WSAENOBUFS; 01381 goto cleanup; 01382 } 01383 01384 __try 01385 { 01386 // Check for an event and reset if. Also, copy the offsets from the upper 01387 // layer's WSAOVERLAPPED structure. 01388 if ( ( NULL == lpCompletionRoutine ) && 01389 ( NULL != lpOverlapped->hEvent ) ) 01390 { 01391 ULONG_PTR ptr = 1; 01392 01393 ret = ResetEvent( (HANDLE) ( (ULONG_PTR) lpOverlapped->hEvent & ~ptr ) ); 01394 if (ret == 0) 01395 { 01396 *lpErrno = ERROR_INVALID_HANDLE; 01397 ret = SOCKET_ERROR; 01398 goto cleanup; 01399 } 01400 } 01401 01402 // Copy any offset information from the caller's overlapped to ours 01403 CopyOffset( &ProviderOverlapped->ProviderOverlapped, lpOverlapped ); 01404 01405 } 01406 __except(EXCEPTION_EXECUTE_HANDLER) 01407 { 01408 *lpErrno = WSAEFAULT; 01409 goto cleanup; 01410 } 01411 01412 if ( NULL != lpThreadId ) 01413 { 01414 ProviderOverlapped->CallerThreadId = *lpThreadId; 01415 } 01416 else 01417 { 01418 // If thread info wasn't passed to us, we need to open the thread context 01419 ret = gMainUpCallTable.lpWPUOpenCurrentThread( &ProviderOverlapped->CallerThreadId, &err ); 01420 if ( SOCKET_ERROR == ret ) 01421 { 01422 dbgprint("WPUOpenCurrentThread failed: %d", err); 01423 } 01424 else 01425 { 01426 // Need to remember for later to close the context since we opened it 01427 ProviderOverlapped->CloseThread = TRUE; 01428 } 01429 } 01430 01431 // Fill in the remaining fields 01432 ProviderOverlapped->Provider = SocketContext->Provider; 01433 ProviderOverlapped->lpCallerOverlapped = lpOverlapped; 01434 ProviderOverlapped->lpCallerCompletionRoutine = lpCompletionRoutine; 01435 ProviderOverlapped->SockInfo = SocketContext; 01436 ProviderOverlapped->CallerSocket = SocketContext->LayeredSocket; 01437 ProviderOverlapped->ProviderSocket = SocketContext->ProviderSocket; 01438 ProviderOverlapped->Error = NO_ERROR; 01439 ProviderOverlapped->Operation = operation; 01440 01441 if ( ( NULL != lpBuffers) && ( dwBufferCount ) ) 01442 { 01443 // Depending on the underlying operation, copy some parameters specific to it 01444 switch ( operation ) 01445 { 01446 case LSP_OP_RECV: 01447 ProviderOverlapped->RecvArgs.dwBufferCount = dwBufferCount; 01448 ProviderOverlapped->RecvArgs.lpBuffers = CopyWSABuf( 01449 lpBuffers, 01450 dwBufferCount, 01451 lpErrno 01452 ); 01453 if ( NULL == ProviderOverlapped->RecvArgs.lpBuffers ) 01454 goto cleanup; 01455 01456 break; 01457 01458 case LSP_OP_RECVFROM: 01459 ProviderOverlapped->RecvFromArgs.dwBufferCount = dwBufferCount; 01460 ProviderOverlapped->RecvFromArgs.lpBuffers = CopyWSABuf( 01461 lpBuffers, 01462 dwBufferCount, 01463 lpErrno 01464 ); 01465 if ( NULL == ProviderOverlapped->RecvFromArgs.lpBuffers ) 01466 goto cleanup; 01467 01468 break; 01469 01470 case LSP_OP_SEND: 01471 ProviderOverlapped->SendArgs.dwBufferCount = dwBufferCount; 01472 ProviderOverlapped->SendArgs.lpBuffers = CopyWSABuf( 01473 lpBuffers, 01474 dwBufferCount, 01475 lpErrno 01476 ); 01477 if ( NULL == ProviderOverlapped->SendArgs.lpBuffers ) 01478 goto cleanup; 01479 01480 break; 01481 01482 case LSP_OP_SENDTO: 01483 ProviderOverlapped->SendToArgs.dwBufferCount = dwBufferCount; 01484 ProviderOverlapped->SendToArgs.lpBuffers = CopyWSABuf( 01485 lpBuffers, 01486 dwBufferCount, 01487 lpErrno 01488 ); 01489 if ( NULL == ProviderOverlapped->SendToArgs.lpBuffers ) 01490 goto cleanup; 01491 01492 break; 01493 01494 default: 01495 break; 01496 } 01497 } 01498 01499 ret = NO_ERROR; 01500 01501 cleanup: 01502 01503 if ( SOCKET_ERROR == ret ) 01504 { 01505 UndoOverlappedOperation( SocketContext, ProviderOverlapped ); 01506 ProviderOverlapped = NULL; 01507 } 01508 else 01509 { 01510 ASSERT( NO_ERROR == ret ); 01511 } 01512 01513 return ProviderOverlapped; 01514 }
Definition at line 344 of file overlap.cpp. 00348 { 00349 BOOL bSynchronous = FALSE; 00350 int err; 00351 00352 // 00353 // Set the fields of the overlapped to indicate IO is not complete yet 00354 // 00355 00356 __try 00357 { 00358 SetOverlappedInProgress( ol->lpCallerOverlapped ); 00359 } 00360 __except( EXCEPTION_EXECUTE_HANDLER ) 00361 { 00362 return WSAEFAULT; 00363 } 00364 00365 if ( NULL != gIocp ) 00366 { 00367 // 00368 // If we haven't already added the provider socket to the IOCP then 00369 // do it now. 00370 // 00371 AcquireSocketLock( SocketContext ); 00372 00373 if ( NULL == SocketContext->hIocp ) 00374 { 00375 SocketContext->hIocp = CreateIoCompletionPort( 00376 (HANDLE)ol->ProviderSocket, 00377 gIocp, 00378 ol->CallerSocket, 00379 0 00380 ); 00381 if ( NULL == SocketContext->hIocp ) 00382 { 00383 if ( ERROR_INVALID_PARAMETER == (err = GetLastError() ) ) 00384 { 00385 // 00386 // If the socket option SO_SYNCHRONOUS_(NON)ALERT is set then 00387 // no overlapped operation can be performed on that socket and 00388 // tryiing to associate it with a completion port will fail. 00389 // The other bad news is that an LSP cannot trap this setsockopt 00390 // call. In reality we don't have to do anything. If an app sets 00391 // this option and then makes overlapped calls anyway, then they 00392 // shouldn't be expecting any overlapped notifications! This 00393 // statement is put here in case you want to mark the socket 00394 // info structure as synchronous. 00395 // 00396 bSynchronous = TRUE; 00397 } 00398 else 00399 { 00400 dbgprint("QueueOverlappedOperation: CreateIoCompletionPort() " 00401 "failed: %d (Prov %d Iocp 0x%x Caller 0x%x 0)", 00402 err, ol->ProviderSocket, 00403 gIocp, ol->CallerSocket); 00404 } 00405 } 00406 00407 dbgprint("Adding provider handle %X to IOCP", ol->ProviderSocket); 00408 } 00409 00410 ReleaseSocketLock( SocketContext ); 00411 00412 // 00413 // Simply execute the operation 00414 // 00415 return ExecuteOverlappedOperation( ol, bSynchronous ); 00416 } 00417 else 00418 { 00419 // Queue up the operation for the worker thread to initiate 00420 // 00421 return EnqueueOverlappedOperation( ol ); 00422 } 00423 }
Definition at line 238 of file overlap.cpp. 00240 { 00241 DWORD i; 00242 int ret = NO_ERROR; 00243 00244 EnterCriticalSection( &gOverlappedCS ); 00245 00246 // 00247 // Post a completion packet to the IOCP (one for each thread) 00248 // 00249 if ( NULL != gIocp ) 00250 { 00251 for(i=0; i < gThreadCount ;i++) 00252 { 00253 ret = PostQueuedCompletionStatus( 00254 gIocp, 00255 (DWORD)-1, 00256 0, 00257 NULL 00258 ); 00259 if ( 0 == ret ) 00260 { 00261 dbgprint("PostQueuedCompletionStatus() failed: %d", GetLastError()); 00262 } 00263 } 00264 00265 // 00266 // Wait a while for the threads to get the signal and exit - if it fails or 00267 // times out then oh well, we need to clean up anyway 00268 // 00269 } 00270 else 00271 { 00272 // 00273 // On Win9x we closed the semaphore so the worker thread should fail 00274 // when waiting for a signal and break out of the loop. 00275 // 00276 00277 LIST_ENTRY *entry = NULL; 00278 WSAOVERLAPPEDPLUS *olp = NULL; 00279 00280 while ( !IsListEmpty( &gPendingOperations ) ) 00281 { 00282 entry = RemoveHeadList( &gPendingOperations ); 00283 00284 olp = CONTAINING_RECORD( entry, WSAOVERLAPPEDPLUS, Link ); 00285 00286 FreeOverlappedStructure( olp ); 00287 } 00288 } 00289 00290 if ( NULL != gWorkerThread ) 00291 { 00292 ret = WaitForMultipleObjectsEx( gThreadCount, gWorkerThread, TRUE, 5000, TRUE ); 00293 if ( WAIT_TIMEOUT == ret ) 00294 dbgprint("StopOverlappedManager: Timed out waiting for IOCP threads to exit!"); 00295 else if ( WAIT_FAILED == ret ) 00296 dbgprint("StopOverlappedManager: WaitForMultipleObjectsEx failed: %d", 00297 GetLastError()); 00298 else 00299 dbgprint("StopOverlappedManager: All worker threads stopped!"); 00300 00301 for(i=0; i < gThreadCount ;i++) 00302 { 00303 CloseHandle( gWorkerThread[ i ] ); 00304 gWorkerThread[ i ] = NULL; 00305 00306 dbgprint("Closing overlapped thread(s)"); 00307 } 00308 00309 LspFree( gWorkerThread ); 00310 gWorkerThread = NULL; 00311 } 00312 00313 // 00314 // Cleanup remaining handles... 00315 // 00316 if ( NULL != gIocp ) 00317 { 00318 CloseHandle( gIocp ); 00319 gIocp = NULL; 00320 } 00321 00322 if ( NULL != gWakeupSemaphore ) 00323 { 00324 CloseHandle( gWakeupSemaphore ); 00325 gWakeupSemaphore = NULL; 00326 } 00327 00328 LeaveCriticalSection( &gOverlappedCS ); 00329 00330 return ret; 00331 }
Definition at line 1525 of file overlap.cpp. 01529 { 01530 AcquireSocketLock( SocketContext ); 01531 (SocketContext->dwOutstandingAsync)--; 01532 ReleaseSocketLock( SocketContext ); 01533 01534 FreeOverlappedStructure( ProviderOverlapped ); 01535 }
Variable Documentation
Definition at line 47 of file overlap.cpp.
Definition at line 48 of file overlap.cpp.
Definition at line 46 of file overlap.cpp.
Definition at line 45 of file overlap.cpp.
|