Restructure repository to include all source folders

Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
#include "stdafx.h"
#include "CompletionHandler.h"
CCompletionHandler::CCompletionHandler()
: m_hIOCP(INVALID_HANDLE_VALUE), m_nThread(0), m_nTimeOutMS(0)
{
}
CCompletionHandler::~CCompletionHandler()
{
Destroy();
}
bool CCompletionHandler::Initialize(unsigned long nThread, unsigned long nTimeOutMS)
{
if(INVALID_HANDLE_VALUE != m_hIOCP)
{
return false;
}
m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, nThread);
if(0 == m_hIOCP)
{
return false;
}
m_nThread = nThread;
m_nTimeOutMS = nTimeOutMS;
return true;
}
bool CCompletionHandler::Destroy()
{
if(INVALID_HANDLE_VALUE != m_hIOCP)
{
if(!CloseHandle(m_hIOCP))
{
return false;
}
}
m_hIOCP = INVALID_HANDLE_VALUE;
return true;
}

View File

@@ -0,0 +1,59 @@
#ifndef _CCOMPLETIONHANDLER_H_
#define _CCOMPLETIONHANDLER_H_
#include <winsock2.h>
#include <windows.h>
//-----------------------------------------------------------------------------
// CCompletionHandler Class
//-----------------------------------------------------------------------------
class CCompletionHandler
{
private:
HANDLE m_hIOCP;
unsigned long m_nThread;
unsigned long m_nTimeOutMS;
public:
CCompletionHandler();
virtual ~CCompletionHandler();
bool Initialize(unsigned long nThread = 0, unsigned long nTimeOutMS = INFINITE); // Completion Handler를 초기화한다.
bool Destroy(); // Completion Hander를 소멸시킨다.
bool AttachToHander(HANDLE hAttach, ULONG_PTR pCompletionKey); // Completion Handler에 새 핸들을 추가한다.
BOOL GetHanderStatus(LPDWORD lpNumOfBytes,
PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped); // 작업이 끝난 핸들을 얻어 온다. 그동안은 block된다.
BOOL PostToHandler(unsigned long dwNumOfBytesTransfered,
ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped); // Handler에 작업을 강제로 추가한다.
};
//-----------------------------------------------------------------------------
// Inline Implementation ------------------------------------------------------
inline bool CCompletionHandler::AttachToHander(HANDLE hAttach, ULONG_PTR pCompletionKey)
{
return (0 != CreateIoCompletionPort(hAttach, m_hIOCP, pCompletionKey, m_nThread));
}
inline BOOL CCompletionHandler::GetHanderStatus(LPDWORD lpNumOfBytes,
PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped)
{
return GetQueuedCompletionStatus(m_hIOCP, lpNumOfBytes, lpCompletionKey, lpOverlapped, m_nTimeOutMS);
}
inline BOOL CCompletionHandler::PostToHandler(unsigned long dwNumOfBytesTransfered,
ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
{
return PostQueuedCompletionStatus(m_hIOCP, dwNumOfBytesTransfered, dwCompletionKey, lpOverlapped);
}
#endif

View File

@@ -0,0 +1,354 @@
#include "stdafx.h"
#include "IOCPNet.h"
#include "IOWorker.h"
#include "CompletionHandler.h"
#include "../../Thread/ThreadMgr.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include "../Session/Session.h"
#include "../Session/SessionMgr.h"
#include "../Listener/Listener.h"
#include "../Dispatch/Dispatch.h"
#include "../Winsock/SocketFactory.h"
#include "../../Utility/Resource/EnsureCleanup.h"
#include "../../Utility/Debug/DebugUtils.h"
#include "../../Log/ServerLog.h"
#include <mmsystem.h>
enum IOCPInternalFlag
{
INITIALIZED_IOCP = (1 << 0),
DESTROYED_IOCP = (1 << 1)
};
unsigned long GetOptimalThreadNum()
{
unsigned long dwThreadCount;
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
dwThreadCount = systemInfo.dwNumberOfProcessors * 2;
return dwThreadCount;
}
CIOCPNet::CIOCPNet()
: m_dwFlags(0),
m_lpSocketHandler(new (std::nothrow) CCompletionHandler),
m_lpThreadMgr(new (std::nothrow) CThreadMgr),
m_lpSessionMgr(new (std::nothrow) CSessionMgr)
{
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
}
CIOCPNet::~CIOCPNet()
{
Destroy();
WSACleanup();
}
// Desc : 초기화 및 스레드 생성.
bool CIOCPNet::Initialize()
{
{
SessionLock::Syncronize sync(m_IOCPLock);
// 초기화는 한번만 할 수 있음.
if(INITIALIZED_IOCP & m_dwFlags)
{
return false;
}
m_dwFlags |= INITIALIZED_IOCP;
}
if(0 == m_lpSocketHandler ||
0 == m_lpThreadMgr ||
0 == m_lpSessionMgr ||
!m_lpSocketHandler->Initialize())
{
return false;
}
// IOCP 스레드 생성.
unsigned long dwThreadNum = GetOptimalThreadNum();
while(0 != dwThreadNum--)
{
if(!m_lpThreadMgr->RegisterAndRun(
new (std::nothrow) CIOWorker(*m_lpSocketHandler)))
{
return false;
}
}
return true;
}
// Desc : Listener를 생성한다.
bool CIOCPNet::AddListener(CSessionPolicy* lpSessionPolicy,
const char* lpListenAddress, unsigned short usPort,
unsigned long dwMaxListenPeding,
CValidateConnection* lpValidateConnection)
{
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid() ||
0 == m_lpSocketHandler || 0 == m_lpSessionMgr)
{
return false;
}
CListener* lpListener = new (std::nothrow) CListener(*m_lpSocketHandler,
*lpSessionPolicy, *m_lpSessionMgr, lpValidateConnection);
if(0 == lpListener)
{
return false;
}
if(!lpListener->Initialize(lpListenAddress, usPort, dwMaxListenPeding))
{
delete lpListener;
return false;
}
lpSessionPolicy->AddRef();
SessionLock::Syncronize sync(m_IOCPLock);
m_ListenerList.push_back(lpListener);
++m_SessionPolicyMap[lpSessionPolicy];
return true;
}
// Desc : 연결 세션을 생성한다.
bool CIOCPNet::Connect(CSessionPolicy* lpSessionPolicy,
const char* lpConnectAddress, unsigned short usPort)
{
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid() ||
0 == m_lpSocketHandler || 0 == m_lpSessionMgr)
{
return false;
}
SOCKET hConnectedSocket = lpSessionPolicy->GetSocketFactory().CreateConnectedSocket(lpConnectAddress, usPort);
if(INVALID_SOCKET == hConnectedSocket)
{
ERRLOG3(g_Log, "Connected socket creation error : %d, destination : %s:%d",
WSAGetLastError(), lpConnectAddress, usPort);
}
else
{
CSession* lpSession = m_lpSessionMgr->CreateSession(*lpSessionPolicy);
if(0 != lpSession)
{
if(m_lpSocketHandler->AttachToHander(
reinterpret_cast<HANDLE>(hConnectedSocket),
reinterpret_cast<ULONG_PTR>(lpSession)))
{
lpSession->Socket(hConnectedSocket);
lpSession->SetAddress(INET_Addr(lpConnectAddress, usPort), INET_Addr());
DETLOG3(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ Connect Success.",
lpSession, lpSession->GetDispatch(), lpConnectAddress);
lpSession->InternalRecv();
m_lpSessionMgr->Add(lpSession);
lpSessionPolicy->AddRef();
SessionLock::Syncronize sync(m_IOCPLock);
++m_SessionPolicyMap[lpSessionPolicy];
return true;
}
m_lpSessionMgr->DeleteSession(lpSession);
}
closesocket(hConnectedSocket);
}
return false;
}
// Desc : Listener에 딸린 세션들과, ConnectedSession의 처리를 한다.
void CIOCPNet::Process()
{
if(0 != m_lpSessionMgr)
{
m_lpSessionMgr->Process();
}
}
// Desc : 모든 Listener와 세션을 종료한다.
bool CIOCPNet::Destroy()
{
m_IOCPLock.Lock();
if(!(m_dwFlags & DESTROYED_IOCP))
{
CThreadMgr* lpThreadMgr = 0;
CCompletionHandler* lpSocketHandler = 0;
CSessionMgr* lpSessionMgr = 0;
SessionPolicyMap tempMap(m_SessionPolicyMap);
m_SessionPolicyMap.clear();
std::swap(m_lpThreadMgr, lpThreadMgr);
std::swap(m_lpSocketHandler, lpSocketHandler);
std::swap(m_lpSessionMgr, lpSessionMgr);
m_dwFlags |= DESTROYED_IOCP;
m_IOCPLock.Unlock();
DestroyListener();
delete lpSessionMgr;
delete lpThreadMgr;
delete lpSocketHandler;
SessionPolicyMap::iterator pos = tempMap.begin();
SessionPolicyMap::iterator end = tempMap.end();
for(; pos != end; ++pos)
{
for(unsigned int nReleaseCount = pos->second;
0 != nReleaseCount; --nReleaseCount)
{
pos->first->Release();
}
}
return true;
}
m_IOCPLock.Unlock();
return false;
}
void CIOCPNet::DestroyListener()
{
ListenerList deleteList;
{
SessionLock::Syncronize sync(m_IOCPLock);
deleteList.splice(deleteList.end(), m_ListenerList);
}
ListenerList::iterator pos = deleteList.begin();
ListenerList::iterator end = deleteList.end();
for(; pos != end; ++pos)
{
delete (*pos);
}
}
// Desc : 현재 Accept를 pending하고 있는 세션의 수를 리턴.
unsigned long CIOCPNet::GetAcceptPendingNum()
{
unsigned long dwPendingNum = 0;
SessionLock::Syncronize sync(m_IOCPLock);
for(ListenerList::iterator itr = m_ListenerList.begin();
itr != m_ListenerList.end(); ++itr)
{
dwPendingNum += (*itr)->GetPendingAcceptNum();
}
return dwPendingNum;
}
unsigned long CIOCPNet::GetSessionNum()
{
if(0 != m_lpSessionMgr)
{
return m_lpSessionMgr->GetSessionNum();
}
return 0;
}
/*
void CIOCPNet::LogListeners()
{
SessionLock::Syncronize sync(m_IOCPLock);
std::for_each(m_ListenerList.begin(), m_ListenerList.end(),
std::mem_fun(CListener::LogListenerStatus));
}
void CIOCPNet::LogConnected()
{
using namespace std;
unsigned int nStateNum[CSession::MAX_SESSION_STATE];
std::fill_n(nStateNum, unsigned int(CSession::MAX_SESSION_STATE), 0);
const char* szDelimiter = "// ------------------------------------------------------------------------------- ";
char szProgramName[MAX_PATH];
char szFileName[MAX_PATH];
char szTime[MAX_PATH];
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
DbgUtils::SetProgramName(szProgramName, MAX_PATH);
_snprintf(szTime, MAX_PATH, "%04d%02d%02d-%02d%02d%02d",
systemTime.wYear, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
_snprintf(szFileName, MAX_PATH, "%s/ConnectedLog-%s.txt", szProgramName, szTime);
fstream logfile(szFileName, ios::out | ios::app);
fstream::char_type endline = logfile.widen('\n');
logfile << szDelimiter << endline;
m_IOCPLock.Lock();
unsigned int nConnectedNum = 0;
ConnectedArray::iterator first = m_ConnectedArray.begin();
ConnectedArray::iterator last = m_ConnectedArray.end();
for(; first != last; ++first)
{
logfile << **first << endline;
++nStateNum[(*first)->m_cCurrentStatus];
++nConnectedNum;
}
m_IOCPLock.Unlock();
logfile << endline << szDelimiter << endline
<< "Time : " << szTime << endline << endline
<< "nUNINITIALIZED : " << nStateNum[CSession::UNINITIALIZED] << endline
<< "ACCEPT_PENDING : " << nStateNum[CSession::ACCEPT_PENDING] << endline
<< "CONNECTED : " << nStateNum[CSession::CONNECTED] << endline
<< "DISCONNECTED : " << nStateNum[CSession::DISCONNECTED] << endline
<< "Total : " << nConnectedNum << endl;
}
*/

View File

@@ -0,0 +1,61 @@
#ifndef _CIOCPMGR_H_
#define _CIOCPMGR_H_
#include <map>
#include <list>
#include "../../Thread/Lock.h"
// Àü¹æ ÂüÁ¶
class CListener;
class CSession;
class CSessionPolicy;
class CCompletionHandler;
class CThreadMgr;
class CSessionMgr;
class CValidateConnection;
class CIOCPNet
{
public:
CIOCPNet();
~CIOCPNet();
bool Initialize();
bool Destroy();
bool AddListener(CSessionPolicy* lpSessionPolicy,
const char* lpListenAddress, unsigned short usPort,
unsigned long dwMaxListenPeding = 10,
CValidateConnection* lpValidateConnection = 0);
bool Connect(CSessionPolicy* lpSessionPolicy,
const char* lpConnectAddress, unsigned short usPort);
void Process();
unsigned long GetAcceptPendingNum();
unsigned long GetSessionNum();
private:
void DestroyListener();
typedef std::list<CListener*> ListenerList;
typedef std::map<CSessionPolicy*, unsigned int> SessionPolicyMap;
typedef CCSLock SessionLock;
SessionLock m_IOCPLock;
CACHE_PAD(SessionLockPad, sizeof(SessionLock));
CCompletionHandler* m_lpSocketHandler;
CThreadMgr* m_lpThreadMgr;
CSessionMgr* m_lpSessionMgr;
ListenerList m_ListenerList;
SessionPolicyMap m_SessionPolicyMap;
unsigned long m_dwFlags;
};
#endif

View File

@@ -0,0 +1,64 @@
#include "stdafx.h"
#include "IOWorker.h"
#include "Overlapped.h"
#include "../IOCP/CompletionHandler.h"
#include "../Session/Session.h"
#include "../Listener/Listener.h"
#include <Log/ServerLog.h>
CIOWorker::CIOWorker(CCompletionHandler& SocketHandler)
: m_SocketHandler(SocketHandler)
{
}
CIOWorker::~CIOWorker()
{
}
unsigned int CIOWorker::Run()
{
COverlapped* lpOverlapped = 0;
while(true)
{
unsigned long dwProcessedBytes = 0;
ULONG_PTR lpSessionKey = 0;
OVERLAPPED* lpOverlappedStruct = 0;
BOOL bResult = m_SocketHandler.GetHanderStatus(&dwProcessedBytes,
&lpSessionKey, &lpOverlappedStruct);
if(0 == lpSessionKey)
{
DETLOG4(g_SessionLog, "SP:0x%p/lpOverlapped:0x%p/bResult:%s/Thread 0x%p Completed",
lpSessionKey, lpOverlappedStruct, bResult ? "T" : "F", GetCurrentThreadId());
break;
}
if(!bResult && 0 == lpOverlappedStruct)
{
// 알 수 없는 에러, 혹은 타임아웃.
DETLOG4(g_SessionLog, "SP:0x%p/lpOverlapped:0x%p/bResult:%s/GetQueuedCompletionStatus error : %u",
lpSessionKey, lpOverlappedStruct, bResult ? "T" : "F", WSAGetLastError());
}
else
{
// Recv, Send, Accept를 함.
lpOverlapped = static_cast<COverlapped*>(lpOverlappedStruct);
lpOverlapped->Dispatch(bResult, lpSessionKey, dwProcessedBytes);
}
}
return 0;
}
BOOL CIOWorker::End()
{
m_SocketHandler.PostToHandler(0, 0, 0);
return true;
}

View File

@@ -0,0 +1,27 @@
#ifndef _IO_WORKER_H_
#define _IO_WORKER_H_
#include "../../Thread/Thread.h"
// Àü¹æ ÂüÁ¶
class CCompletionHandler;
class CIOWorker : public CThread
{
public:
CIOWorker(CCompletionHandler& SocketHandler);
virtual ~CIOWorker();
private:
virtual unsigned int Run();
virtual BOOL End();
CCompletionHandler& m_SocketHandler;
};
#endif

View File

@@ -0,0 +1,284 @@
#include "stdafx.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "Overlapped.h"
#include "../Session/Session.h"
#include "../Listener/Listener.h"
#include "../../Stream/Buffer/Buffer.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include <boost/pool/pool.hpp>
COverlapped::COverlapped(COverlappedFactory& ovlFactory, CBuffer* lpBuffer)
: m_lpBuffer(lpBuffer), m_ovlFactory(ovlFactory)
{
Internal = InternalHigh = Offset = OffsetHigh = 0;
hEvent = 0;
}
COverlapped::~COverlapped()
{
SAFE_RELEASE_BUFFER(m_lpBuffer);
}
void COverlapped::Release()
{
m_ovlFactory.DeleteOverlapped(this);
}
class CSendOverlapped : public COverlapped
{
public:
CSendOverlapped(COverlappedFactory& ovlFactory, CBuffer* lpSendBuffer)
: COverlapped(ovlFactory, lpSendBuffer) { }
virtual ~CSendOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
Session.SendCompleted(bResult, dwProcessedBytes);
m_ovlFactory.DeleteOverlapped(this);
}
};
class CStreamRecvOverlapped : public COverlapped
{
public:
CStreamRecvOverlapped(COverlappedFactory& ovlFactory) : COverlapped(ovlFactory, 0) { }
virtual ~CStreamRecvOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
if(Session.Dispatch(dwProcessedBytes))
{
Session.Recv();
}
m_ovlFactory.DeleteOverlapped(this);
}
};
class CDatagramRecvOverlapped : public COverlapped
{
public:
CDatagramRecvOverlapped(COverlappedFactory& ovlFactory) : COverlapped(ovlFactory, 0) { }
virtual ~CDatagramRecvOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
if(Session.Dispatch(dwProcessedBytes))
{
Session.RecvFrom();
}
m_ovlFactory.DeleteOverlapped(this);
}
};
class CAcceptOverlapped : public COverlapped
{
public:
CAcceptOverlapped(COverlappedFactory& ovlFactory, CListener& Listener, SOCKET hSocket, CBuffer* lpAddrBuffer)
: COverlapped(ovlFactory, lpAddrBuffer), m_Listener(Listener), m_hSocket(hSocket)
{
}
virtual ~CAcceptOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CListener& Listener = *reinterpret_cast<CListener*>(lpSessionKey);
Listener.ProcessAccept(bResult, m_hSocket, m_lpBuffer, dwProcessedBytes);
m_ovlFactory.DeleteOverlapped(this);
}
private:
CListener& m_Listener;
SOCKET m_hSocket;
};
// ----------------------------------------------------------------------
// StreamOverlapped
CStreamOverlappedFactory::CStreamOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
size_t nMaxPoolSize = std::max(sizeof(CAcceptOverlapped),
std::max(sizeof(CSendOverlapped), sizeof(CStreamRecvOverlapped)));
m_lpOverlappedPool = new (std::nothrow) boost::pool<>(nMaxPoolSize);
}
CStreamOverlappedFactory::~CStreamOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
delete m_lpOverlappedPool;
m_lpOverlappedPool = 0;
}
COverlapped* CStreamOverlappedFactory::CreateSend(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CSendOverlapped(*this, lpMsgBlock);
}
}
return lpOverlapped;
}
COverlapped* CStreamOverlappedFactory::CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CStreamRecvOverlapped(*this);
}
}
return lpOverlapped;
}
COverlapped* CStreamOverlappedFactory::CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpListener && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CAcceptOverlapped(*this, *lpListener, hSocket, lpMsgBlock);
}
}
return lpOverlapped;
}
void CStreamOverlappedFactory::DeleteOverlapped(COverlapped* lpOverlapped)
{
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpOverlapped && 0 != m_lpOverlappedPool)
{
lpOverlapped->~COverlapped();
m_lpOverlappedPool->free(lpOverlapped);
}
}
// ----------------------------------------------------------------------
// DatagramOverlapped
CDatagramOverlappedFactory::CDatagramOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
size_t nMaxPoolSize = std::max(sizeof(CAcceptOverlapped),
std::max(sizeof(CSendOverlapped), sizeof(CDatagramRecvOverlapped)));
m_lpOverlappedPool = new (std::nothrow) boost::pool<>(nMaxPoolSize);
}
CDatagramOverlappedFactory::~CDatagramOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
delete m_lpOverlappedPool;
m_lpOverlappedPool = 0;
}
COverlapped* CDatagramOverlappedFactory::CreateSend(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CSendOverlapped(*this, lpMsgBlock);
}
}
return lpOverlapped;
}
COverlapped* CDatagramOverlappedFactory::CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CDatagramRecvOverlapped(*this);
}
}
return lpOverlapped;
}
void CDatagramOverlappedFactory::DeleteOverlapped(COverlapped* lpOverlapped)
{
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpOverlapped && 0 != m_lpOverlappedPool)
{
lpOverlapped->~COverlapped();
m_lpOverlappedPool->free(lpOverlapped);
}
}

View File

@@ -0,0 +1,112 @@
#ifndef _COVERLAPPED_H_
#define _COVERLAPPED_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "../../Thread/Lock.h"
#include <winsock2.h>
#include <windows.h>
#include <boost/pool/poolfwd.hpp>
// 전방 참조
class CBuffer;
class CBufferFactory;
class CSession;
class CListener;
class COverlappedFactory;
class COverlapped : public OVERLAPPED
{
public:
COverlapped(COverlappedFactory& ovlFactory, CBuffer* lpBuffer);
virtual ~COverlapped();
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey,
unsigned long dwProcessedBytes) = 0;
void SetBuffer(CBuffer* lpBuffer) { m_lpBuffer = lpBuffer; }
void Release();
protected:
COverlappedFactory& m_ovlFactory;
CBuffer* m_lpBuffer;
};
// ---------------------------------------------------------------------------
// COverlappedFactory : 인터페이스 팩토리
class COverlappedFactory
{
public:
virtual ~COverlappedFactory() { }
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock) = 0;
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock) = 0;
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock) = 0;
virtual void DeleteOverlapped(COverlapped* lpOverlapped) = 0;
};
// ---------------------------------------------------------------------------
// CStreamOverlappedFactory : TCP, SPX통신에 사용한다.
class CStreamOverlappedFactory : public COverlappedFactory
{
public:
CStreamOverlappedFactory();
virtual ~CStreamOverlappedFactory();
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock);
virtual void DeleteOverlapped(COverlapped* lpOverlapped);
private:
typedef CCSLock FactoryLock;
FactoryLock m_Lock;
CACHE_PAD(FactoryLockPad, sizeof(FactoryLock));
boost::pool<>* m_lpOverlappedPool;
};
// ---------------------------------------------------------------------------
// CDatagramOverlappedFactory : UDP, IPX통신에 사용한다.
class CDatagramOverlappedFactory : public COverlappedFactory
{
public:
CDatagramOverlappedFactory();
virtual ~CDatagramOverlappedFactory();
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock) { return 0; }
virtual void DeleteOverlapped(COverlapped* lpOverlapped);
private:
typedef CCSLock FactoryLock;
FactoryLock m_Lock;
CACHE_PAD(FactoryLockPad, sizeof(FactoryLock));
boost::pool<>* m_lpOverlappedPool;
};
#endif