Fsbii (5) iocp

Source: Internet
Author: User
/********************************************************************created:2003/02/14file base:IOBufferfile ext:hauthor:liupengpurpose:Header file for CIOBuffer class*********************************************************************/#ifndef __INCLUDE_IOBUFFER_H__#define __INCLUDE_IOBUFFER_H__#if defined (_MSC_VER) && (_MSC_VER >= 1020)#pragma once#endif#ifndef _WINDOWS_#define WIN32_LEAN_AND_MEAN#include <windows.h>#undef WIN32_LEAN_AND_MEAN#endif/* * Identifier was truncated to '255' characters  * in the debug information */#pragma warning(disable : 4786)                               #include <winsock2.h>#include "CriticalSection.h" #include "tstring.h"#include "NodeList.h"#include "OpaqueUserData.h"#include "Macro.h"#include <map>/* * Nonstandard extension used : zero-sized array in struct/union */#pragma warning(disable: 4200)/* * namespace OnlineGameLib::Win32 */namespace OnlineGameLib {namespace Win32 {/* * CIOBuffer */class CIOBuffer : public OVERLAPPED, public CNodeList::Node, public COpaqueUserData{public:class Allocator;friend class Allocator;class InOrderBufferList;WSABUF *GetWSABUF() const { return const_cast< WSABUF * >( &m_wsabuf ); };size_t GetUsed() const { return m_used; };size_t GetSize() const { return m_size; };const BYTE *GetBuffer() const { return m_buffer_ptr; };void SetupZeroByteRead();void SetupRead();void SetupWrite();void AddData( const char * const pData, size_t dataLength );void AddData( const BYTE * const pData, size_t dataLength );void AddData( BYTE data );void Use( size_t dataUsed ) { m_used += dataUsed; };CIOBuffer *SplitBuffer( size_t bytesToRemove );void RemoveBuffer( size_t bytesToRemove );CIOBuffer *AllocateNewBuffer() const;void ConsumeAndRemove( size_t bytesToRemove );void Empty();void AddRef() { ::InterlockedIncrement( &m_ref ); };void Release();size_t GetOperation() const { return m_operation; };void SetOperation( size_t operation ) { m_operation = operation; };size_t GetSequenceNumber() const { return m_sequenceNumber; };void SetSequenceNumber( size_t sequenceNumber ) { m_sequenceNumber = sequenceNumber; };private:size_t m_operation;size_t m_sequenceNumber;WSABUF m_wsabuf;Allocator &m_allocator;long m_ref;const size_t m_size;size_t m_used;/* * Start of the actual buffer, must remain the last * data member in the class. */BYTE *m_buffer_ptr;// four bytes aligned//BYTE m_buffer_base_addr[0];private:static void *operator new( size_t objSize, size_t bufferSize );static void operator delete( void *pObj, size_t bufferSize );CIOBuffer( Allocator &m_allocator, size_t size );~CIOBuffer();/*     * No copies do not implement     */CIOBuffer( const CIOBuffer &rhs );CIOBuffer &operator=( const CIOBuffer &rhs );};/* * CIOBuffer::Allocator */class CIOBuffer::Allocator{public:      friend class CIOBuffer;      explicit Allocator( size_t bufferSize, size_t maxFreeBuffers );      virtual ~Allocator();      CIOBuffer *Allocate();      size_t GetBufferSize() const { return m_bufferSize; };protected:      void Flush();private:      void Release( CIOBuffer *pBuffer );      virtual void OnBufferCreated() {}      virtual void OnBufferAllocated() {}      virtual void OnBufferReleased() {}      void DestroyBuffer( CIOBuffer *pBuffer );      const size_t m_bufferSize;      typedef TNodeList< CIOBuffer > BufferList;            BufferList m_freeList;      BufferList m_activeList;            const size_t m_maxFreeBuffers;      CCriticalSection m_criticalSection;      /*   * No copies do not implement   */      Allocator( const Allocator &rhs );      Allocator &operator=( const Allocator &rhs );};/* * CIOBuffer::InOrderBufferList */class CIOBuffer::InOrderBufferList{public:      explicit InOrderBufferList( CCriticalSection &lock );      void AddBuffer( CIOBuffer *pBuffer );      void ProcessBuffer();      CIOBuffer *ProcessAndGetNext();      CIOBuffer *GetNext();      CIOBuffer *GetNext( CIOBuffer *pBuffer );      void Reset();      bool Empty() const { return m_list.empty(); };private:      size_t m_next;         typedef std::map< size_t, CIOBuffer * > BufferSequence;      BufferSequence m_list;      CCriticalSection &m_criticalSection;};inline void CIOBuffer::ConsumeAndRemove( size_t bytesToRemove ){m_used -= bytesToRemove;memmove( m_buffer_ptr, m_buffer_ptr + bytesToRemove, m_used );}inline void CIOBuffer::SetupZeroByteRead(){m_wsabuf.buf = reinterpret_cast< char * >( m_buffer_ptr );m_wsabuf.len = 0; }inline void CIOBuffer::SetupRead(){if ( m_used == 0 ){m_wsabuf.buf = reinterpret_cast< char * >( m_buffer_ptr );m_wsabuf.len = m_size; }else{m_wsabuf.buf = reinterpret_cast< char * >( m_buffer_ptr ) + m_used;m_wsabuf.len = m_size - m_used;   }}inline void CIOBuffer::SetupWrite(){m_wsabuf.buf = reinterpret_cast< char * >( m_buffer_ptr );m_wsabuf.len = m_used;m_used = 0;}} // End of namespace OnlineGameLib} // End of namespace Win32#endif //__INCLUDE_IOBUFFER_H__
#include "stdafx.h"#include "KWin32.h"#include "IOBuffer.h"#include "Exception.h"#include "Utils.h"/* * namespace OnlineGameLib::Win32 */namespace OnlineGameLib {namespace Win32 {CIOBuffer::CIOBuffer( Allocator &allocator, size_t size ):  m_operation( 0 )      , m_sequenceNumber( 0 )      , m_allocator( allocator )      , m_ref( 1 )      , m_size( size )      , m_used( 0 ){//( ( BYTE * )( ( DWORD )( pMemory + 3 ) & ( ~3 ) ) )m_buffer_ptr = ::new BYTE[ size ];memset( this, 0, sizeof( OVERLAPPED ) );Empty();}CIOBuffer::~CIOBuffer(){    if (m_buffer_ptr)    {        ::delete []m_buffer_ptr;        m_buffer_ptr = NULL;    }}void CIOBuffer::Empty(){m_wsabuf.buf = reinterpret_cast< char * >( m_buffer_ptr );m_wsabuf.len = m_size;m_used = 0;}void *CIOBuffer::operator new( size_t objectSize, size_t /* bufferSize */ ){/* * ASSERT( sizeof( DWORD ) == 4 ); * * For four bytes aligned base on win32 system */void *pMem = ::new char[ objectSize ]; // + bufferSize + 4 ];return pMem;}void CIOBuffer::operator delete( void *pObject, size_t /* bufferSize*/ ){    if (pObject)    {        ::delete [](char *)pObject;        pObject = NULL;    }}CIOBuffer *CIOBuffer::SplitBuffer( size_t bytesToRemove ){CIOBuffer *pNewBuffer = m_allocator.Allocate();pNewBuffer->AddData( m_buffer_ptr, bytesToRemove );m_used -= bytesToRemove;memmove( m_buffer_ptr, m_buffer_ptr + bytesToRemove, m_used );return pNewBuffer;}VOID CIOBuffer::RemoveBuffer( size_t bytesToRemove ){if ( m_used < bytesToRemove )return;m_used -= bytesToRemove;memmove( m_buffer_ptr, m_buffer_ptr + bytesToRemove, m_used );}CIOBuffer *CIOBuffer::AllocateNewBuffer() const{return m_allocator.Allocate();}void CIOBuffer::AddData( const char * const pData, size_t dataLength ){if (dataLength > m_size - m_used){DEBUG_ONLY( Message( "CIOBuffer::AddData - Not enough space in buffer!" ) );throw CException( _T("CIOBuffer::AddData"), _T("Not enough space in buffer") );}memcpy( m_buffer_ptr + m_used, pData, dataLength );m_used += dataLength;}void CIOBuffer::AddData( const BYTE * const pData, size_t dataLength ){AddData( reinterpret_cast< const char * >( pData ), dataLength );}void CIOBuffer::AddData( BYTE data ){AddData( &data, 1 );}void CIOBuffer::Release(){if (m_ref == 0){/* * Error! double release */throw CException( _T("CIOBuffer::Release()"), _T("m_ref is already zero") );}if ( 0 == ::InterlockedDecrement( &m_ref ) ){m_sequenceNumber = 0;m_operation = 0;m_used = 0;m_allocator.Release( this );}}/* * CIOBuffer::Allocator */CIOBuffer::Allocator::Allocator( size_t bufferSize, size_t maxFreeBuffers )   :  m_bufferSize( bufferSize ),      m_maxFreeBuffers( maxFreeBuffers ){}CIOBuffer::Allocator::~Allocator(){try{Flush();}catch(...){TRACE( "CIOBuffer::Allocator::~Allocator exception!" );}}CIOBuffer *CIOBuffer::Allocator::Allocate(){CCriticalSection::Owner lock( m_criticalSection );CIOBuffer *pBuffer = 0;if ( !m_freeList.Empty() ){pBuffer = m_freeList.PopNode();pBuffer->AddRef();}else{pBuffer = new( m_bufferSize )CIOBuffer( *this, m_bufferSize );if ( !pBuffer ){throw CException( _T("CIOBuffer::Allocator::Allocate()"), _T("Out of memory") );}OnBufferCreated();}m_activeList.PushNode( pBuffer );OnBufferAllocated();return pBuffer;}void CIOBuffer::Allocator::Release( CIOBuffer *pBuffer ){if ( !pBuffer ){throw CException( _T("CIOBuffer::Allocator::Release()"), _T("pBuffer is null") );}CCriticalSection::Owner lock( m_criticalSection );OnBufferReleased();/* * unlink from the in use list */pBuffer->RemoveFromList();if ( m_maxFreeBuffers == 0 || m_freeList.Count() < m_maxFreeBuffers ){pBuffer->Empty();           /* * add to the free list */m_freeList.PushNode( pBuffer );}else{DestroyBuffer( pBuffer );}}void CIOBuffer::Allocator::DestroyBuffer( CIOBuffer *pBuffer ){SAFE_DELETE( pBuffer );}void CIOBuffer::Allocator::Flush(){CCriticalSection::Owner lock( m_criticalSection );while ( !m_activeList.Empty() ){OnBufferReleased();DestroyBuffer( m_activeList.PopNode() );}while ( !m_freeList.Empty() ){DestroyBuffer( m_freeList.PopNode() );}}/* * CIOBuffer::InOrderBufferList */CIOBuffer::InOrderBufferList::InOrderBufferList(CCriticalSection &criticalSection):   m_next(0),m_criticalSection( criticalSection ){}void CIOBuffer::InOrderBufferList::AddBuffer( CIOBuffer *pBuffer ){CCriticalSection::Owner lock( m_criticalSection );std::pair< BufferSequence::iterator, bool > result = m_list.insert( BufferSequence::value_type( pBuffer->GetSequenceNumber(), pBuffer ) );if ( !result.second ){DEBUG_ONLY( Output( _T("UNEXPECTED! element already in map!") ) );}}CIOBuffer *CIOBuffer::InOrderBufferList::ProcessAndGetNext(){CCriticalSection::Owner lock( m_criticalSection );m_next ++;CIOBuffer *pNext = 0;BufferSequence::iterator it;it = m_list.begin();if ( it != m_list.end() ){if ( it->first == m_next ){pNext = it->second;m_list.erase( it );}else{DEBUG_ONLY( Output( ToString( this ) +_T(" Got buffer : ") + ToString( it->first ) +_T("Want buffer : ") +ToString( m_next ) ) );}}return pNext;}CIOBuffer *CIOBuffer::InOrderBufferList::GetNext(){CCriticalSection::Owner lock( m_criticalSection );CIOBuffer *pNext = 0;BufferSequence::iterator it;it = m_list.begin();if ( it != m_list.end() ){if ( it->first == m_next ){pNext = it->second;m_list.erase(it);}else{DEBUG_ONLY( Output( ToString( this ) + _T(" Got buffer  : ") + ToString( it->first ) + _T("Want buffer : ") + ToString( m_next ) ) );}}return pNext;}CIOBuffer *CIOBuffer::InOrderBufferList::GetNext( CIOBuffer *pBuffer ){CCriticalSection::Owner lock( m_criticalSection );if ( m_next == pBuffer->GetSequenceNumber() ){return pBuffer;}std::pair< BufferSequence::iterator, bool > result = m_list.insert( BufferSequence::value_type( pBuffer->GetSequenceNumber(), pBuffer ) );if ( !result.second ){DEBUG_ONLY( Output( _T("UNEXPECTED! element already in map!") ) );}CIOBuffer *pNext = 0;BufferSequence::iterator it;it = m_list.begin();if (it != m_list.end()) {if (it->first == m_next){pNext = it->second;m_list.erase(it);}else{DEBUG_ONLY( Output( ToString( this ) +_T(" Got buffer  : ") + ToString( it->first ) + _T("Want buffer : ") + ToString( m_next ) ) );}}return pNext;}void CIOBuffer::InOrderBufferList::ProcessBuffer(){CCriticalSection::Owner lock( m_criticalSection );DEBUG_ONLY( Output( ToString( this ) +_T(" Processed : ") + ToString( m_next ) ) );m_next ++;}void CIOBuffer::InOrderBufferList::Reset(){m_next = 0;if ( !m_list.empty() ){DEBUG_ONLY( Output( _T("List not empty when reset !") ) );}}} // End of namespace Win32} // End of namespace OnlineGameLib 

/********************************************************************created:2003/02/14file base:IOCompletionPortfile ext:hauthor:liupengpurpose:Header file for CIOCompletionPort routines*********************************************************************/#ifndef __INCLUDE_IOCOMPLETIONPORT_H__#define __INCLUDE_IOCOMPLETIONPORT_H__#ifndef _WINDOWS_#define WIN32_LEAN_AND_MEAN#include <windows.h>#undef WIN32_LEAN_AND_MEAN#endif#include "Macro.h"/* * namespace OnlineGameLib::Win32 */namespace OnlineGameLib {namespace Win32 {/* * CIOCompletionPort */class CIOCompletionPort{public:   explicit CIOCompletionPort( size_t maxConcurrency );~CIOCompletionPort();void AssociateDevice( HANDLE hDevice, ULONG_PTR completionKey );void PostStatus( ULONG_PTR completionKey, DWORD dwNumBytes = 0, OVERLAPPED *pOverlapped = 0 );DWORD GetStatus( ULONG_PTR *pCompletionKey, PDWORD pdwNumBytes,OVERLAPPED **ppOverlapped );DWORD GetStatus( ULONG_PTR *pCompletionKey, PDWORD pdwNumBytes,OVERLAPPED **ppOverlapped, DWORD dwMilliseconds );private:      HANDLE m_iocp;/* * No copies do not implement */CIOCompletionPort( const CIOCompletionPort &rhs );CIOCompletionPort &operator=( const CIOCompletionPort &rhs );};} // End of namespace OnlineGameLib} // End of namespace Win32#endif //__INCLUDE_IOCOMPLETIONPORT_H__

#include "stdafx.h"#include "IOCompletionPort.h"#include "Win32Exception.h"#include "Macro.h"/* * namespace OnlineGameLib::Win32 */namespace OnlineGameLib {namespace Win32 {CIOCompletionPort::CIOCompletionPort( size_t maxConcurrency ): m_iocp( ::CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, maxConcurrency ) ){if ( m_iocp == 0 ){throw CWin32Exception( _T("CIOCompletionPort::CIOCompletionPort() - CreateIoCompletionPort"), ::GetLastError() );}}CIOCompletionPort::~CIOCompletionPort() {SAFE_CLOSEHANDLE( m_iocp );}void CIOCompletionPort::AssociateDevice( HANDLE hDevice, ULONG_PTR completionKey ){if ( m_iocp != ::CreateIoCompletionPort( hDevice,m_iocp, completionKey, 0 ) ){throw CWin32Exception( _T("CIOCompletionPort::AssociateDevice() - CreateIoCompletionPort"), ::GetLastError() );}}void CIOCompletionPort::PostStatus( ULONG_PTR completionKey, DWORD dwNumBytes /* = 0 */, OVERLAPPED *pOverlapped /* = 0 */) {if ( 0 == ::PostQueuedCompletionStatus( m_iocp, dwNumBytes, completionKey, pOverlapped ) ){throw CWin32Exception( _T("CIOCompletionPort::PostStatus() - PostQueuedCompletionStatus"), ::GetLastError() );}}DWORD CIOCompletionPort::GetStatus( ULONG_PTR *pCompletionKey, PDWORD pdwNumBytes,OVERLAPPED **ppOverlapped ){if ( 0 == ::GetQueuedCompletionStatus( m_iocp, pdwNumBytes, pCompletionKey, ppOverlapped, INFINITE ) ){return ::GetLastError();}return S_OK;}DWORD CIOCompletionPort::GetStatus( ULONG_PTR *pCompletionKey, PDWORD pdwNumBytes,OVERLAPPED **ppOverlapped, DWORD dwMilliseconds){if ( 0 == ::GetQueuedCompletionStatus( m_iocp, pdwNumBytes, pCompletionKey, ppOverlapped, dwMilliseconds ) ){DWORD lastError = ::GetLastError();if ( lastError != WAIT_TIMEOUT ){return lastError;}return S_FALSE;}return S_OK;}} // End of namespace OnlineGameLib} // End of namespace Win32

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.