JNetLibray
로딩중...
검색중...
일치하는것 없음
jnet::JNetCore 클래스 참조abstract

클라이언트 TCP 세션의 생명 주기를 'JNetSession'을 통해 관리하며, 하위 클래스 객체의 세션 접근(송신, 수신 처리 및 연결 종료)에 대한 thread-safe 성을 보장함
등록된 세션의 소켓 장치를 IOCP 객체에 등록되면, 비동기 I/O 완료 처리를 IOCP 작업자 스레드를 통해 수행
클라이언트로부터의 패킷 수신 완료 및 연결 종료를 이벤트 함수(OnRecvCompletion, OnSessionLeave)를 통해 콜백하며, 패킷 송신 및 연결 종료 기능 함수(SendPacket, Disconnect)를 제공함
더 자세히 ...

#include <JNetCore.h>

jnet::JNetCore에 대한 상속 다이어그램 :
jnet::JNetClient jnet::JNetServer jnet::JNetOdbcServer jnet::jgroup::JNetGroupServer

클래스

struct  JNetSession
 JNetCore에서 관리되는 세션 구조체
세션의 연결 소켓 및 수신 링-버퍼와 송신 락-프리 큐 버퍼를 멤버로 갖으며, 세션 ID와 참조 카운트 필드를 바탕으로 thread-safe한 세션 초기화 및 해제 기능을 제공
더 자세히 ...
 

Public 멤버 함수

 JNetCore (uint16 maximumOfSessions, uint32 numOfIocpConcurrentThrd, uint16 numOfIocpWorkerThrd, size_t tlsMemPoolUnitCnt, size_t tlsMemPoolUnitCapacity, uint32 memPoolBuffAllocSize, uint32 sessionRecvBuffSize, bool calcTpsThread)
 
 ~JNetCore ()
 
bool Start ()
 
void Stop ()
 
uint16 GetCurrentSessions ()
 
int64 GetCurrentAllocatedMemUnitCnt ()
 
int GetSessionCount ()
 
UINT GetAcceptTPS ()
 
UINT GetRecvTPS ()
 
UINT GetSendTPS ()
 
UINT64 GetTotalAcceptTransaction ()
 
UINT64 GetTotalRecvTransaction ()
 
UINT64 GetTotalSendTransaction ()
 
void IncrementRecvTransactions (bool threadSafe, UINT incre)
 
void IncrementSendTransactions (bool threadSafe, UINT incre)
 
void IncrementAcceptTransactions (bool threadSafe=false, UINT incre=1)
 

Protected 멤버 함수

void PrintLibraryInfoOnConsole ()
 
JNetSessionCreateNewSession (SOCKET sock)
 하위 클래스에서 세션 객체 생성 요청을 위해 호출하는 함수
 
bool RegistSessionToIOCP (JNetSession *session)
 하위 클래스에서 세션 객체를 IOCP 등록을 위해 호출하는 함수
 
bool DeleteSession (SessionID64 sessionID)
 세션 제거 요청 함수
 
void Disconnect (SessionID64 sessionID)
 
bool SendPacket (SessionID64 sessionID, JBuffer *sendPktPtr, bool postToWorker=false)
 패킷 송신 요청 함수
 
bool SendPacketBlocking (SessionID64 sessionID, JBuffer *sendPktPtr)
 동기식 송신 요청 함수
 
bool BufferSendPacket (SessionID64 sessionID, JBuffer *sendPktPtr)
 세션 송신 버퍼 큐에 버퍼링(삽입만 진행)
 
bool SendBufferedPacket (SessionID64 sessionID, bool postToWorker=false)
 세션 송신 버퍼 큐 내 송신 패킷 직렬화 버퍼에 대한 일괄 송신 작업 수행
 
DWORD AllocTlsMemPool ()
 직렬화 패킷 버퍼 Tls 풀 할당 함수
 
JBuffer * AllocSerialBuff ()
 직렬화 패킷 버퍼 할당 요청 wrapper
 
void FreeSerialBuff (JBuffer *buff)
 직렬화 패킷 버퍼 반환 wrapper
 
void AddRefSerialBuff (JBuffer *buff)
 직렬화 패킷 버퍼 참조 카운트 증가 wrapper
 
virtual bool OnWorkerThreadCreate (HANDLE thHnd)
 Start() 함수 내 IOCP 작업자 스레드 생성(CREATE_SUSPENDED) 후 호출되는 이벤트 함수
 
virtual void OnAllWorkerThreadCreate ()
 Start() 함수 내 요청된 수 만큼 IOCP 작업자 스레드를 생성한 후 함수를 빠져나오기 전 호출되는 이벤트 함수
 
virtual void OnWorkerThreadStart ()
 개별 IOCP 작업자 스레드의 수행 흐름 초입부(WorkerThreadFunc 함수 초입부)에 호출되는 이벤트 함수, 개별 작업자 스레드의 초기화를 독립적으로 수행하도록 재정의 가능
 
virtual void OnWorkerThreadEnd ()
 개별 IOCP 작업자 스레드가 종료(작업자 함수 return) 전 호출되는 이벤트 함수
 
virtual void OnRecvCompletion (SessionID64 sessionID, JBuffer &recvRingBuffer)=0
 IOCP 작업자 스레드의 수신 완료 시 대상 세션의 수신 버퍼의 enqueue 오프셋 제어 후 호출되는 이벤트 함수
 
virtual void OnSessionLeave (SessionID64 sessionID)
 JNetCore 단 세션이 제거된 후 호출되는 이벤트 함수
 
virtual void OnError ()
 

Protected 속성

bool m_CalcTpsFlag
 

Private 타입

enum  enTransaction { ACCEPT_TRANSACTION , RECV_TRANSACTION , SEND_TRANSACTION , SEND_REQ_TRANSACTION }
 

Private 멤버 함수

JNetSessionAcquireSession (SessionID64 sessionID)
 Multi IOCP 작업자 스레드 간 thread-safe 하지 않은 세션에 대해 세션 접근 전 호출하는 함수
 
void ReturnSession (JNetSession *session)
 AcquireSession을 통해 획득한 세션 객체 소유권 반납
 
void SendPost (SessionID64 sessionID, bool onSendFlag=false)
 SendPacket 계열 함수 내부에서 호출되는 실질적 송신 요청 함수
 
void SendPostRequest (SessionID64 sessionID)
 SendPost() 함수의 작업을 IOCP 작업자 스레드의 흐름에서 수행되도록 강제화를 요청하는 함수
 
void FreeBufferedSendPacket (LockFreeQueue< JBuffer * > &sendBufferQueue, queue< JBuffer * > &sendPostedQueue)
 세션 제거 시 송신 버퍼 정리
 
void Proc_DeleteSession (JNetSession *session)
 IOCP 작업자 스레드의 세션 삭제 요청 처리 함수
 
void Proc_SendPostRequest (JNetSession *session)
 IOCP 작업자 스레드의 송신 요청 시 처리 함수(SendPacket 계열 함수의 postToWorker 요청)
 
void Proc_RecvCompletion (JNetSession *session, DWORD transferred)
 IOCP 작업자 스레드의 수신 완료 통지 시 처리 함수
 
void Proc_SendCompletion (JNetSession *session)
 IOCP 작업자 스레드의 송신 완료 통지 시 처리 함수
 
void IncrementTransactions (BYTE type, bool threadSafe=false, UINT incre=1)
 
LONG GetTransactionsPerSecond (BYTE type)
 
UINT64 GetTotalTransactions (BYTE type)
 

정적 Private 멤버 함수

static UINT __stdcall WorkerThreadFunc (void *arg)
 IOCP 작업자 스레드의 수행 함수
 
static UINT __stdcall CalcTpsThreadFunc (void *arg)
 

Private 속성

std::vector< JNetSession * > m_Sessions
 세션 관리 벡터
 
uint16 m_MaximumOfSessions
 수용 가능한 최대 세션 수
 
LockFreeQueue< uint16m_SessionIndexQueue
 세션 인덱스 할당 큐 (SessionID's index part)
 
uint64 m_SessionIncrement
 세션 증분 (SessionID's increment part)
 
HANDLE m_IOCP
 JNetCore's IOCP 객체
 
uint16 m_NumOfIocpWorkerThrd
 IOCP 작업자 스레드 갯수
 
std::vector< HANDLE > m_IocpWorkerThrdHnds
 IOCP 작업자 스레드 핸들 벡터
 
std::vector< uint32m_IocpWorkerThrdIDs
 IOCP 작업자 스레드's ID 벡터
 
TlsMemPoolManager< JBuffer, true, false > m_TlsMemPoolMgr
 Tls 메모리 풀 관리 (직렬화 패킷 버퍼 풀 할당 및 관리자)
 
size_t m_TlsMemPoolUnitCnt
 
size_t m_TlsMemPoolUnitCapacity
 
uint32 m_MemPoolBuffAllocSize
 
HANDLE m_CalcTpsThread
 
UINT m_Transactions [NUM_OF_TPS_ITEM]
 
UINT m_TransactionsPerSecond [NUM_OF_TPS_ITEM]
 
UINT64 m_TotalTransaction [NUM_OF_TPS_ITEM]
 

정적 Private 속성

static const int NUM_OF_TPS_ITEM = 4
 

상세한 설명

클라이언트 TCP 세션의 생명 주기를 'JNetSession'을 통해 관리하며, 하위 클래스 객체의 세션 접근(송신, 수신 처리 및 연결 종료)에 대한 thread-safe 성을 보장함
등록된 세션의 소켓 장치를 IOCP 객체에 등록되면, 비동기 I/O 완료 처리를 IOCP 작업자 스레드를 통해 수행
클라이언트로부터의 패킷 수신 완료 및 연결 종료를 이벤트 함수(OnRecvCompletion, OnSessionLeave)를 통해 콜백하며, 패킷 송신 및 연결 종료 기능 함수(SendPacket, Disconnect)를 제공함

멤버 열거형 문서화

◆ enTransaction

열거형 멤버
ACCEPT_TRANSACTION 
RECV_TRANSACTION 
SEND_TRANSACTION 
SEND_REQ_TRANSACTION 
234 {
239 };
@ SEND_TRANSACTION
Definition JNetCore.h:237
@ RECV_TRANSACTION
Definition JNetCore.h:236
@ ACCEPT_TRANSACTION
Definition JNetCore.h:235
@ SEND_REQ_TRANSACTION
Definition JNetCore.h:238

생성자 & 소멸자 문서화

◆ JNetCore()

JNetCore::JNetCore ( uint16 maximumOfSessions,
uint32 numOfIocpConcurrentThrd,
uint16 numOfIocpWorkerThrd,
size_t tlsMemPoolUnitCnt,
size_t tlsMemPoolUnitCapacity,
uint32 memPoolBuffAllocSize,
uint32 sessionRecvBuffSize,
bool calcTpsThread )
매개변수
maximumOfSessions수용 가능 최대 세션 수 설정
numOfIocpConcurrentThrdIOCP 'concurrent threads' 설정
numOfIocpWorkerThrdIOCP 작업자 스레드 수 설정
tlsMemPoolUnitCntTls 메모리 풀 객체 초기 할당량 결정(직렬화 패킷 버퍼 수)
tlsMemPoolUnitCapacityTls 메모리 풀 객체 수용량 결정(직렬화 패킷 버퍼 최대 용량)
memPoolBuffAllocSize
sessionRecvBuffSize
calcTpsThread
12 : m_MaximumOfSessions(maximumOfSessions), m_SessionIncrement(0),
13 m_NumOfIocpWorkerThrd(numOfIocpWorkerThrd),
14 m_TlsMemPoolMgr(tlsMemPoolUnitCnt, tlsMemPoolUnitCapacity),
15 m_TlsMemPoolUnitCnt(tlsMemPoolUnitCnt), m_TlsMemPoolUnitCapacity(tlsMemPoolUnitCapacity),
16 m_MemPoolBuffAllocSize(memPoolBuffAllocSize),
17 m_CalcTpsFlag(calcTpsThread)
18{
19 // 1. 윈도우 네트워크 라이브러리 초기화
20 WSAData wsadata;
21 if (InitWindowSocketLib(&wsadata) != 0) {
22 DebugBreak();
23 }
24 cout << "JNetCore::JNetCore(..), Window Network Library Init Done.." << endl;
25
26 // 2. 세션 관리 초기화
27 for (uint16 idx = 1; idx <= m_MaximumOfSessions; idx++) {
28 m_SessionIndexQueue.Enqueue(idx);
29 }
30 m_Sessions.resize(m_MaximumOfSessions + 1, NULL);
31 for (uint16 idx = 1; idx <= m_MaximumOfSessions; idx++) {
32 m_Sessions[idx] = new JNetSession{sessionRecvBuffSize};
33 }
34 cout << "JNetCore::JNetCore(..), Session's Structs Init Done.." << endl;
35
36 // 3. IOCP 객체 초기화
37 m_IOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, numOfIocpConcurrentThrd);
38#if defined(ASSERT)
39 if (m_IOCP == NULL) {
40 DebugBreak();
41 }
42#endif
43 cout << "JNetCore::JNetCore(..), CreateIoCompletionPort Done.." << endl;
44
45 // 4. IOCP 작업자 스레드 관리 초기화
46 if (m_NumOfIocpWorkerThrd == 0) {
47 SYSTEM_INFO si;
48 GetSystemInfo(&si);
49 m_NumOfIocpWorkerThrd = si.dwNumberOfProcessors;
50 }
53 cout << "JNetCore::JNetCore(..), IOCP Worker Threads Init Done.." << endl;
54}
unsigned __int16 uint16
Definition CommTypes.h:9
int InitWindowSocketLib(LPWSADATA)
Definition WinSocketAPI.cpp:3
uint64 m_SessionIncrement
세션 증분 (SessionID's increment part)
Definition JNetCore.h:50
std::vector< JNetSession * > m_Sessions
세션 관리 벡터
Definition JNetCore.h:47
TlsMemPoolManager< JBuffer, true, false > m_TlsMemPoolMgr
Tls 메모리 풀 관리 (직렬화 패킷 버퍼 풀 할당 및 관리자)
Definition JNetCore.h:57
std::vector< HANDLE > m_IocpWorkerThrdHnds
IOCP 작업자 스레드 핸들 벡터
Definition JNetCore.h:54
bool m_CalcTpsFlag
Definition JNetCore.h:230
uint32 m_MemPoolBuffAllocSize
Definition JNetCore.h:61
uint16 m_MaximumOfSessions
수용 가능한 최대 세션 수
Definition JNetCore.h:48
HANDLE m_IOCP
JNetCore's IOCP 객체
Definition JNetCore.h:52
size_t m_TlsMemPoolUnitCnt
Definition JNetCore.h:59
uint16 m_NumOfIocpWorkerThrd
IOCP 작업자 스레드 갯수
Definition JNetCore.h:53
size_t m_TlsMemPoolUnitCapacity
Definition JNetCore.h:60
LockFreeQueue< uint16 > m_SessionIndexQueue
세션 인덱스 할당 큐 (SessionID's index part)
Definition JNetCore.h:49
std::vector< uint32 > m_IocpWorkerThrdIDs
IOCP 작업자 스레드's ID 벡터
Definition JNetCore.h:55

◆ ~JNetCore()

JNetCore::~JNetCore ( )
57{
58 Stop();
59 CloseHandle(m_IOCP);
60 WSACleanup();
61}
void Stop()
Definition JNetCore.cpp:96

멤버 함수 문서화

◆ Start()

bool JNetCore::Start ( )
64{
65 // IOCP 작업자 스레드 생성
66 for (uint16 idx = 0; idx < m_NumOfIocpWorkerThrd; idx++) {
67 uintptr_t ret = _beginthreadex(NULL, 0, JNetCore::WorkerThreadFunc, this, CREATE_SUSPENDED, NULL);
68 m_IocpWorkerThrdHnds[idx] = (HANDLE)ret;
69 if (m_IocpWorkerThrdHnds[idx] == INVALID_HANDLE_VALUE) {
70 DebugBreak();
71 }
72 DWORD thID = GetThreadId(m_IocpWorkerThrdHnds[idx]);
73 m_IocpWorkerThrdIDs[idx] = thID;
74
76 cout << "[Cant't Start Thread] Worker Thread (thID: " << GetThreadId(m_IocpWorkerThrdHnds[idx]) << ")" << endl;
77 TerminateThread(m_IocpWorkerThrdHnds[idx], 0);
78 }
79 else {
80 cout << "[Start Thread] Worker Thread (thID: " << GetThreadId(m_IocpWorkerThrdHnds[idx]) << ")" << endl;
81 ResumeThread(m_IocpWorkerThrdHnds[idx]);
82 }
83 }
84
85 if (m_CalcTpsFlag) {
86 m_CalcTpsThread = (HANDLE)_beginthreadex(NULL, 0, JNetCore::CalcTpsThreadFunc, this, 0, NULL);
87 }
88 cout << "JNetCore::Start(), Create IOCP Worker Threads Done.." << endl;
89
90 // 모든 스레드가 생성된 후 호출, 생성된 스레드는 작업 중...
92
93 return true;
94}
virtual void OnAllWorkerThreadCreate()
Start() 함수 내 요청된 수 만큼 IOCP 작업자 스레드를 생성한 후 함수를 빠져나오기 전 호출되는 이벤트 함수
Definition JNetCore.cpp:243
static UINT __stdcall CalcTpsThreadFunc(void *arg)
Definition JNetCore.cpp:716
static UINT __stdcall WorkerThreadFunc(void *arg)
IOCP 작업자 스레드의 수행 함수
Definition JNetCore.cpp:539
HANDLE m_CalcTpsThread
Definition JNetCore.h:241
virtual bool OnWorkerThreadCreate(HANDLE thHnd)
Start() 함수 내 IOCP 작업자 스레드 생성(CREATE_SUSPENDED) 후 호출되는 이벤트 함수
Definition JNetCore.cpp:241

◆ Stop()

void JNetCore::Stop ( )
97{
98 static bool stopped = false;
99
100 if (!stopped) {
101 if (m_CalcTpsFlag) { TerminateThread(m_CalcTpsThread, 0); }
102
103 // IOCP 작업자 스레드가 스스로 작업 함수에서 반환하도록 종료 메시지를 IOCP 큐에 post
104 for (uint16 i = 0; i < m_NumOfIocpWorkerThrd; i++) {
105 PostQueuedCompletionStatus(m_IOCP, 0, 0, NULL);
106 }
107
108 stopped = true;
109 }
110}

◆ GetCurrentSessions()

uint16 jnet::JNetCore::GetCurrentSessions ( )
inline
85 {
87 }

◆ PrintLibraryInfoOnConsole()

void jnet::JNetCore::PrintLibraryInfoOnConsole ( )
protected
113{
114 cout << "======================== JNetCore ========================" << endl;
115 cout << "JNetCore::Maximum Of Sessions : " << m_MaximumOfSessions << endl;
116 cout << "JNetCore::Current Allive Sessions Count : " << GetCurrentSessions() << endl;
117 cout << "JNetCore::TLS Memory Pool Unit Count(set) : " << m_TlsMemPoolUnitCnt << endl;
118 cout << "JNetCore::TLS Memory Pool Unit Capacity(set): " << m_TlsMemPoolUnitCapacity << endl;
119 cout << "JNetCore::TLS Memory Pool Buffer Alloc Size : " << m_MemPoolBuffAllocSize << endl;
120
121 cout << "TlsMemPool::Total Memory Alloc Count : " << m_TlsMemPoolMgr.GetTotalAllocMemCnt() << endl;
122 cout << "TlsMemPool::Total Memory Free Count : " << m_TlsMemPoolMgr.GetTotalFreeMemCnt() << endl;
123 cout << "TlsMemPool::Current Memory Allocated Count : " << m_TlsMemPoolMgr.GetAllocatedMemUnitCnt() << endl;
124 cout << "TlsMemPool::Memory Malloc Count : " << m_TlsMemPoolMgr.GetMallocCount() << endl;
125
126 std::cout << "----------------------------------------------------------" << std::endl;
127 std::cout << "[Accept] Total Accept Count : " << GetTotalAcceptTransaction() << std::endl;
128 std::cout << "[Accept] Accept TPS : " << GetAcceptTPS() << std::endl;
129 std::cout << "----------------------------------------------------------" << std::endl;
130 std::cout << "[Recv] Total Recv Packet Size : " << GetTotalRecvTransaction() << std::endl;
131 std::cout << "[Recv] Total Recv TPS : " << GetRecvTPS() << std::endl;
132 std::cout << "----------------------------------------------------------" << std::endl;
133 std::cout << "[Send] Total Send Packet Size : " << GetTotalSendTransaction() << std::endl;
134 std::cout << "[Send] Total Send TPS : " << GetSendTPS() << std::endl;
135 std::cout << "----------------------------------------------------------" << std::endl;
136 std::cout << "[Session] Session acceptance limit : " << m_MaximumOfSessions << std::endl;
137 std::cout << "[Session] Current number of sessions : " << GetSessionCount() << std::endl;
138 std::cout << "[Session] Number of Acceptances Available : " << m_SessionIndexQueue.GetSize() << std::endl;
139 std::cout << "----------------------------------------------------------" << std::endl;
140}
int GetSessionCount()
Definition JNetCore.h:157
UINT GetAcceptTPS()
Definition JNetCore.h:248
UINT GetSendTPS()
Definition JNetCore.h:250
UINT64 GetTotalSendTransaction()
Definition JNetCore.h:253
UINT GetRecvTPS()
Definition JNetCore.h:249
UINT64 GetTotalRecvTransaction()
Definition JNetCore.h:252
uint16 GetCurrentSessions()
Definition JNetCore.h:84
UINT64 GetTotalAcceptTransaction()
Definition JNetCore.h:251

◆ CreateNewSession()

JNetCore::JNetSession * JNetCore::CreateNewSession ( SOCKET sock)
protected

하위 클래스에서 세션 객체 생성 요청을 위해 호출하는 함수

매개변수
sock세션과 대응되는 유효한 소켓 핸들
반환값
새로 생성 및 초기화된 세션 객체의 포인터
444{
445 JNetSession* newSession = nullptr;
446
447 uint16 allocIdx;
448 if (m_SessionIndexQueue.Dequeue(allocIdx)) {
449 newSession = m_Sessions[allocIdx];
450 JNetSession::SessionID newSessionID(allocIdx, InterlockedIncrement64(reinterpret_cast<long long*>(&m_SessionIncrement)));
451 newSession->Init(newSessionID, sock);
452 }
453 return newSession;
454}

◆ RegistSessionToIOCP()

bool JNetCore::RegistSessionToIOCP ( JNetSession * session)
protected

하위 클래스에서 세션 객체를 IOCP 등록을 위해 호출하는 함수

매개변수
session등록하고자 하는 세션 객체 포인터
반환값
등록 성공 여부
457{
458 bool ret = true;
459 if (CreateIoCompletionPort((HANDLE)session->m_Sock, m_IOCP, (ULONG_PTR)session, 0) == NULL) {
460#if defined(ASSERT)
461 DebugBreak();
462#else
463 ret = false;
464#endif
465 }
466 else {
467 // IOCP 등록 성공 시 초기 수신 대기 설정
468 // WSARecv
469 WSABUF wsabuf;
470 wsabuf.buf = reinterpret_cast<char*>(session->m_RecvRingBuffer.GetEnqueueBufferPtr());
471 wsabuf.len = session->m_RecvRingBuffer.GetFreeSize();
472
473 DWORD dwFlag = 0;
474 //newSession->ioCnt = 1;
475 // => 세션 Release 관련 수업(24.04.08) 참고
476 // 세션 Init 함수에서 IOCnt를 1로 초기화하는 것이 맞는듯..
477 if (WSARecv(session->m_Sock, &wsabuf, 1, NULL, &dwFlag, &session->m_RecvOverlapped, NULL) == SOCKET_ERROR) {
478 int errcode = WSAGetLastError();
479 if (errcode != WSA_IO_PENDING) {
480 ret = false;
481 }
482 }
483 }
484
485 return ret;
486}

◆ DeleteSession()

bool JNetCore::DeleteSession ( SessionID64 sessionID)
protected

세션 제거 요청 함수

매개변수
sessionID제거하고자하는 세션 아이디
반환값
true 반환 시 세션 제거, false 반환 시 이미 제거되었거나 제거 로직이 다른 스레드를 통해 수행중인 상황을 암시
489{
490 bool ret = false;
491 uint16 idx = (uint16)sessionID;
492 JNetSession* delSession = m_Sessions[idx];
493
494 if (delSession == nullptr) {
495#if defined(ASSERT)
496 DebugBreak();
497#endif
498 return false;
499 }
500
501 if (delSession->TryRelease()) {
502 ret = true;
503#if defined(ASSERT)
504 if (delSession->m_ID != sessionID) {
505 DebugBreak();
506 }
507#endif
508
509 // 세션 삭제
510 uint16 allocatedIdx = delSession->m_ID.idx;
511 SOCKET delSock = m_Sessions[allocatedIdx]->m_Sock;
512 shutdown(delSock, SD_BOTH);
513 closesocket(delSock);
514
515 FreeBufferedSendPacket(delSession->m_SendBufferQueue, delSession->m_SendPostedQueue);
516
517 // 세션 ID 인덱스 반환
518 m_SessionIndexQueue.Enqueue(allocatedIdx);
519 }
520
521 return ret;
522}
void FreeBufferedSendPacket(LockFreeQueue< JBuffer * > &sendBufferQueue, queue< JBuffer * > &sendPostedQueue)
세션 제거 시 송신 버퍼 정리
Definition JNetCore.cpp:524

◆ Disconnect()

void jnet::JNetCore::Disconnect ( SessionID64 sessionID)
protected
143{
144 // refCnt > 0 임을 보장한 상태에서 호출되는 함수이기에 AcquireSession이 필요없음
145 JNetSession::SessionID sessionID(sessionID64);
146 JNetSession* delSession = m_Sessions[sessionID.idx];
147#if defined(ASSERT)
148 if (delSession->m_SessionRef.refCnt < 1) {
149 DebugBreak();
150 }
151#endif
152 PostQueuedCompletionStatus(m_IOCP, 0, (ULONG_PTR)delSession, (LPOVERLAPPED)IOCP_COMPLTED_LPOVERLAPPED_DISCONNECT);
153}
#define IOCP_COMPLTED_LPOVERLAPPED_DISCONNECT
Definition JNetCore.h:20

◆ SendPacket()

bool JNetCore::SendPacket ( SessionID64 sessionID,
JBuffer * sendPktPtr,
bool postToWorker = false )
protected

패킷 송신 요청 함수

매개변수
sessionID송신 대상 세션 아이디
송신직렬화 패킷 버퍼 @postToWorker IOCP 작업자 스레드에 실질적 송신 작업(SendPost) 책임 전가(WSASend 호출 및 커널 모드 전환 처리 전가)
156{
157 bool ret = false;
158 JNetSession* session = AcquireSession(sessionID);
159 if (session != nullptr) {
160
161 session->m_SendBufferQueue.Enqueue(sendPktPtr);
162
163 if (postToWorker) {
164 SendPostRequest(sessionID);
165 }
166 else {
167 SendPost(sessionID);
168 }
169
170 ReturnSession(session);
171 ret = true;
172 }
173
174 return ret;
175}
void SendPost(SessionID64 sessionID, bool onSendFlag=false)
SendPacket 계열 함수 내부에서 호출되는 실질적 송신 요청 함수
Definition JNetCore.cpp:360
JNetSession * AcquireSession(SessionID64 sessionID)
Multi IOCP 작업자 스레드 간 thread-safe 하지 않은 세션에 대해 세션 접근 전 호출하는 함수
Definition JNetCore.cpp:271
void ReturnSession(JNetSession *session)
AcquireSession을 통해 획득한 세션 객체 소유권 반납
Definition JNetCore.cpp:330
void SendPostRequest(SessionID64 sessionID)
SendPost() 함수의 작업을 IOCP 작업자 스레드의 흐름에서 수행되도록 강제화를 요청하는 함수
Definition JNetCore.cpp:432

◆ SendPacketBlocking()

bool JNetCore::SendPacketBlocking ( SessionID64 sessionID,
JBuffer * sendPktPtr )
protected

동기식 송신 요청 함수

매개변수
sessionID송신 대상 세션 아이디
송신직렬화 패킷 버퍼
178{
179 bool ret = false;
180 JNetSession* session = AcquireSession(sessionID);
181 if (session != nullptr) {
182
183 session->m_SendBufferQueue.Enqueue(sendPktPtr);
184
185 int sendDataLen = sendPktPtr->GetUseSize();
186 if (sendDataLen != ::send(session->m_Sock, (const char*)sendPktPtr->GetBeginBufferPtr(), sendDataLen, 0)) {
187#if defined(ASSERT)
188 DebugBreak();
189#else
190 ret = false;
191#endif
192 }
193 FreeSerialBuff(sendPktPtr);
194
195 ReturnSession(session);
196 ret = true;
197 }
198
199 return ret;
200}
void FreeSerialBuff(JBuffer *buff)
직렬화 패킷 버퍼 반환 wrapper
Definition JNetCore.h:144

◆ BufferSendPacket()

bool JNetCore::BufferSendPacket ( SessionID64 sessionID,
JBuffer * sendPktPtr )
protected

세션 송신 버퍼 큐에 버퍼링(삽입만 진행)

매개변수
sessionID송신 대상 세션 아이디
송신직렬화 패킷 버퍼
203{
204 bool ret = false;
205 JNetSession* session = AcquireSession(sessionID);
206 if (session != nullptr) {
207
208 session->m_SendBufferQueue.Enqueue(sendPktPtr);
209
210 ReturnSession(session);
211 ret = true;
212 }
213
214 return ret;
215}

◆ SendBufferedPacket()

bool JNetCore::SendBufferedPacket ( SessionID64 sessionID,
bool postToWorker = false )
protected

세션 송신 버퍼 큐 내 송신 패킷 직렬화 버퍼에 대한 일괄 송신 작업 수행

매개변수
sessionID송신 대상 세션 아이디 @postToWorker IOCP 작업자 스레드에 실질적 송신 작업(SendPost) 책임 전가
218{
219 bool ret = false;
220 JNetSession* session = AcquireSession(sessionID);
221 if (session != NULL) {
222 if (postToWorker) {
223 SendPostRequest(sessionID);
224 }
225 else {
226 SendPost(sessionID);
227 }
228 ReturnSession(session);
229 ret = true;
230 }
231 return ret;
232}

◆ AllocTlsMemPool()

DWORD jnet::JNetCore::AllocTlsMemPool ( )
inlineprotected

직렬화 패킷 버퍼 Tls 풀 할당 함수

◆ AllocSerialBuff()

JBuffer * jnet::JNetCore::AllocSerialBuff ( )
inlineprotected

직렬화 패킷 버퍼 할당 요청 wrapper

137 {
138 JBuffer* msg = m_TlsMemPoolMgr.GetTlsMemPool().AllocMem(1, m_MemPoolBuffAllocSize);
139 msg->ClearBuffer();
140 return msg;
141 }

◆ FreeSerialBuff()

void jnet::JNetCore::FreeSerialBuff ( JBuffer * buff)
inlineprotected

직렬화 패킷 버퍼 반환 wrapper

144 {
145 m_TlsMemPoolMgr.GetTlsMemPool().FreeMem(buff);
146 }

◆ AddRefSerialBuff()

void jnet::JNetCore::AddRefSerialBuff ( JBuffer * buff)
inlineprotected

직렬화 패킷 버퍼 참조 카운트 증가 wrapper

149 {
150 m_TlsMemPoolMgr.GetTlsMemPool().IncrementRefCnt(buff, 1);
151 }

◆ GetCurrentAllocatedMemUnitCnt()

int64 jnet::JNetCore::GetCurrentAllocatedMemUnitCnt ( )
inline
154 {
155 return m_TlsMemPoolMgr.GetAllocatedMemUnitCnt();;
156 }

◆ GetSessionCount()

int jnet::JNetCore::GetSessionCount ( )
inline
157 {
158 return m_MaximumOfSessions - m_SessionIndexQueue.GetSize();
159 }

◆ OnWorkerThreadCreate()

bool JNetCore::OnWorkerThreadCreate ( HANDLE thHnd)
protectedvirtual

Start() 함수 내 IOCP 작업자 스레드 생성(CREATE_SUSPENDED) 후 호출되는 이벤트 함수

매개변수
thHnd생성된 IOCP 작업자 스레드 핸들
반환값
생성된 IOCP 작업자 스레드 수행 여부

재정의를 통해 생성과 동시에 중지 상태인 IOCP 작업자 스레드의 핸들 인수를 통해 필요한 초기화 작업을 수행할 수 있다.
JNetCore에 설정된 IOCP 작업자 스레드 생성 갯수와 별개로 수행되는 작업자 스레드 갯수를 제어할 수 있다.
true 반환 시 중지된 작업자 스레드의 수행이 시작되고, false 반환 시 스레드는 강제 종료된다.

241{ return true; }

◆ OnAllWorkerThreadCreate()

void JNetCore::OnAllWorkerThreadCreate ( )
protectedvirtual

Start() 함수 내 요청된 수 만큼 IOCP 작업자 스레드를 생성한 후 함수를 빠져나오기 전 호출되는 이벤트 함수

243{}

◆ OnWorkerThreadStart()

void JNetCore::OnWorkerThreadStart ( )
protectedvirtual

개별 IOCP 작업자 스레드의 수행 흐름 초입부(WorkerThreadFunc 함수 초입부)에 호출되는 이벤트 함수, 개별 작업자 스레드의 초기화를 독립적으로 수행하도록 재정의 가능

IOCP 작업자 스레드 개별 수행 흐름의 초입에 호출되는 함수로 GetQueuedCompletionStatus 함수가 포함된 작업 루프 이전에 호출된다. 주로 JNetCore 단에서 관리되는 TLS 기반의 메모리 풀을 할당받고, 초기화하는 작업을 수행한다.

250{}

◆ OnWorkerThreadEnd()

void JNetCore::OnWorkerThreadEnd ( )
protectedvirtual

개별 IOCP 작업자 스레드가 종료(작업자 함수 return) 전 호출되는 이벤트 함수

252{ std::cout << "IOCP Worker Thread Exits.."; }

◆ OnRecvCompletion()

virtual void jnet::JNetCore::OnRecvCompletion ( SessionID64 sessionID,
JBuffer & recvRingBuffer )
protectedpure virtual

IOCP 작업자 스레드의 수신 완료 시 대상 세션의 수신 버퍼의 enqueue 오프셋 제어 후 호출되는 이벤트 함수

IOCP 작업자 스레드의 수신 완료 시 대상 세션의 수신 버퍼의 enqueue 오프셋 제어 후 호출되는 함수이다. JNetCore는 순전히 IOCP 작업자 스레드와 세션 관리 및 송수신의 책임만을 제공하기에 수신 이후의 작업을 하위 클래스에서 정의하도록 순수 가상 함수로써 강제하였다. OnRecvCompletion 함수의 반환 이후 해당 세션의 수신 버퍼가 수신 요청되기에 OnRecvCompletion 함수에서는 수신 버퍼에 대한 작업자 스레드 간의 경쟁은 없다. 따라서 단지 수신 버퍼의 참조만을 전달하여 복사 비용 발생을 방지하였다.

매개변수
sessionID세션 아이디(uint64)
recvRingBuffer세션의 수신 버퍼 참조

jnet::JNetClient, jnet::JNetServer에서 구현되었습니다.

◆ OnSessionLeave()

void JNetCore::OnSessionLeave ( SessionID64 sessionID)
protectedvirtual

JNetCore 단 세션이 제거된 후 호출되는 이벤트 함수

매개변수
sessionID세션 아이디(uint64)

관리되는 세션이 제거된 후 호출되는 함수이다. 호출 시점에서 sessionID는 이미 제거된 세션 ID이며, 유효하지 않다. 콘텐츠 서버와 같은 하위 클래스에서 sessionID를 기반으로 한 데이터를 해당 함수 재정의에서 제거하는 등 정리 작업을 수행할 수 있다.

jnet::JNetClient, jnet::JNetServer에서 재구현되었습니다.

259{}

◆ OnError()

void JNetCore::OnError ( )
protectedvirtual
261{};

◆ AcquireSession()

JNetCore::JNetSession * JNetCore::AcquireSession ( SessionID64 sessionID)
private

Multi IOCP 작업자 스레드 간 thread-safe 하지 않은 세션에 대해 세션 접근 전 호출하는 함수

매개변수
접근대상 세션 아이디
반환값
해당 세션 객체 포인터

특정 세션에 대한 접근에 있어 thread-safe를 보장할 수 없다. 따라서 주로 컨텐츠 코드에서 호출되는 SendPacket 계열의 요청 함수에서는 세션 독점 점유가 필요하다.
AcquireSession 함수는 독점적인 점유를 보장한다. 독점적인 점유에 성공한다면 해당 세션 객체의 포인터를 반환하며, 실패 시 nullptr을 반환한다.
하위 클래스에 이벤트 함수 등으로 전달되는 세션 아이디(uin64)는 64비트열을 하나의 정수로 전달하는 간단한 추상화이며, JNetCore 단에서는 16비트의 인덱스 번호와 48비트의 증분 값으로 관리된다.
세션 객체의 참조 카운트와 단일 플래그로 구성된 참조 구조체 멤버를 원자적 연산으로 제어하여 세션 객체에 대한 동기화를 내부적으로 수행한다.

272{
273 uint16 idx = (uint16)sessionID;
274 JNetSession* session = m_Sessions[idx]; // 세션 ID의 인덱스 파트를 통해 세션 획득
275 // AcquireSession을 호출하는 시점에서 찾고자 하였던 세션을 획득하였다는 보장은 할 수 없음
276 if (session == nullptr) {
277 return nullptr;
278 }
279 else {
280 // 세션 참조 카운트(ioCnt) 증가!
281 long ref32 = InterlockedIncrement(reinterpret_cast<long*>(&session->m_SessionRef));
282
283 // 세션 IOCnt를 증가한 시점 이후,
284 // 참조하고자 하였던 본래 세션이든, 또는 같은 인덱스 자리에 재활용된 세션이든 삭제되지 않는 보장을 할 수 있음
285
286 // (1) if(session->sessionRef.releaseFlag == 1)
287 // => 본래 참조하고자 하였던 세션 또는 새로운 세션이 삭제(중)
288 // (2) if(session->sessionRef.releaseFlag == 0 && sessionID != session->uiId)
289 // => 참조하고자 하였던 세션은 이미 삭제되고, 새로운 세션이 동일 인덱스에 생성
290 if (session->m_SessionRef.releaseFlag == 1 || sessionID != session->m_ID) {
291 // 세션 참조 카운트(ioCnt) 감소
292 InterlockedDecrement(reinterpret_cast<long*>(&session->m_SessionRef));
293
294 // 세션 삭제 및 변경 가능 구역
295 // ....
296
297 // case0) ioCnt >= 1, 세션 유효
298 // case1) releaseFlag == 1 유지, 세션 삭제(중)
299 // caas2) releaseFlag == 0, ioCnt == 0
300 // => Disconnect 책임
301
302 JNetSession::SessionRef exgRef(1, 0);
303 int32 orgRef32 = InterlockedCompareExchange(reinterpret_cast<long*>(&session->m_SessionRef), exgRef, 0);
304 JNetSession::SessionRef orgRef = orgRef32;
305
306 // releaseFlag == 0이 된 상태에서 ioCnt == 0이 된 상황
307 // => Disconnect 호출 책임
308 // CAS를 진행하였기에 CAS 이 후부터 세션 삭제는 없음이 보장됨
309 if (orgRef.refCnt == 0 && orgRef.releaseFlag == 0) {
310 Disconnect(session->m_ID);
311 }
312 else if (orgRef.refCnt == 0 && orgRef.releaseFlag == 1) {
313 // 새로운 세션 생성 전
314 // nothing to do..
315 }
316#if defined(ASSERT)
317 else if (orgRef.refCnt < 0) {
318 DebugBreak();
319 }
320#endif
321 return nullptr;
322 }
323 else {
324 // 기존 세션 확정 -> 반환 (ioCnt == 1이라면 ReturnSession에서 처리할 것)
325 return session;
326 }
327 }
328}
__int32 int32
Definition CommTypes.h:6
void Disconnect(SessionID64 sessionID)
Definition JNetCore.cpp:142

◆ ReturnSession()

void JNetCore::ReturnSession ( JNetSession * session)
private

AcquireSession을 통해 획득한 세션 객체 소유권 반납

매개변수
세션객체 포인터
331{
332 if (session->m_SessionRef.refCnt < 1) {
333#if defined(ASSERT)
334 DebugBreak();
335#endif
336 return;
337 }
338
339 uint64 savedSessionID = session->m_ID; // ioCnt와 r
340
341 int32 ref32 = InterlockedDecrement(reinterpret_cast<long*>(&session->m_SessionRef));
342
343 JNetSession::SessionRef exgRef(1, 0);
344 int32 orgRef32 = InterlockedCompareExchange(reinterpret_cast<long*>(&session->m_SessionRef), exgRef, 0);
345 JNetSession::SessionRef orgRef = orgRef32;
346 if (orgRef.refCnt == 0 && orgRef.releaseFlag == 0) {
347 Disconnect(savedSessionID);
348 }
349 else if (orgRef.refCnt == 0 && orgRef.releaseFlag == 1) {
350 // 새로운 세션 생성 전
351 // nothing to do..
352 }
353#if defined(ASSERT)
354 else if (orgRef.refCnt < 0) {
355 DebugBreak();
356 }
357#endif
358}
unsigned __int64 uint64
Definition CommTypes.h:11

◆ SendPost()

void JNetCore::SendPost ( SessionID64 sessionID,
bool onSendFlag = false )
private

SendPacket 계열 함수 내부에서 호출되는 실질적 송신 요청 함수

매개변수
sessionID송신 대상 세션 아이디
onSendFlag
361{
362 uint16 idx = (uint16)sessionID;
363 JNetSession* session = m_Sessions[idx];
364
365 if (session == nullptr) {
366 return;
367 }
368
369 if (onSendFlag || InterlockedExchange(reinterpret_cast<long*>(&session->m_SendFlag), 1) == 0) {
370 memset(&session->m_SendOverlapped, 0, sizeof(WSAOVERLAPPED));
371
372
373 int32 numOfMessages = session->m_SendBufferQueue.GetSize();
374 //WSABUF wsabuffs[WSABUF_ARRAY_DEFAULT_SIZE];
375 vector<WSABUF> wsaBuffVec(numOfMessages);
376
377 if (numOfMessages > 0) {
378 InterlockedIncrement(reinterpret_cast<long*>(&session->m_SessionRef));
379 for (int32 idx = 0; idx < numOfMessages; idx++) {
380 JBuffer* msgPtr;
381 //session->sendBufferQueue.Dequeue(msgPtr);
382 // => single reader 보장
383 if (!session->m_SendBufferQueue.Dequeue(msgPtr, true)) {
384 DebugBreak();
385 }
386
387 //session->sendPostedQueue.push(msgPtr);
388 // => push 오버헤드 제거
389 session->m_SendPostedQueue.push(msgPtr);
390
391 wsaBuffVec[idx].buf = reinterpret_cast<char*>(msgPtr->GetBeginBufferPtr());
392 wsaBuffVec[idx].len = msgPtr->GetUseSize();
393
394 if (wsaBuffVec[idx].buf == NULL || wsaBuffVec[idx].len == 0) {
395#if defined(ASSERT)
396 DebugBreak();
397#endif
398 return;
399 }
400
401 }
402 session->m_SendOverlapped.Offset = numOfMessages; // Offset 멤버를 활용하여 송신한 메시지 갯수를 담도록 한다.
403
404 if (WSASend(session->m_Sock, wsaBuffVec.data(), numOfMessages, NULL, 0, &session->m_SendOverlapped, NULL) == SOCKET_ERROR) {
405 int errcode = WSAGetLastError();
406 if (errcode != WSA_IO_PENDING) {
407 int32 ref32 = InterlockedDecrement(reinterpret_cast<long*>(&session->m_SessionRef));
408 JNetSession::SessionRef ref(ref32);
409#if defined(ASSERT)
410 if (ref.refCnt < 0) {
411 DebugBreak();
412 }
413#endif
414
415 // SendPost는 iocp 워커 스레드에서도 다른 스레드에서도 호출 가능
416 // 따라서 Disconnect 호출 방식으로 세션 삭제 처리
417 JNetSession::SessionRef exgRef(1, 0);
418 int32 orgRef32 = InterlockedCompareExchange(reinterpret_cast<long*>(&session->m_SessionRef), exgRef, 0);
419 JNetSession::SessionRef orgRef = orgRef32;
420 if (orgRef.refCnt == 0 && orgRef.releaseFlag == 0) {
421 Disconnect(session->m_ID);
422 }
423 }
424 }
425 }
426 else {
427 InterlockedExchange(reinterpret_cast<long*>(&session->m_SendFlag), 0);
428 }
429 }
430}

◆ SendPostRequest()

void JNetCore::SendPostRequest ( SessionID64 sessionID)
private

SendPost() 함수의 작업을 IOCP 작업자 스레드의 흐름에서 수행되도록 강제화를 요청하는 함수

매개변수
sessionID송신 대상 세션 아이디
433{
434 uint16 idx = (uint16)sessionID;
435 JNetSession* session = m_Sessions[idx];
436
437 if (InterlockedCompareExchange(reinterpret_cast<long*>(&session->m_SendFlag), 1, 0) == 0) {
438 InterlockedIncrement(reinterpret_cast<long*>(&session->m_SessionRef));
439 PostQueuedCompletionStatus(m_IOCP, 0, (ULONG_PTR)session, (LPOVERLAPPED)IOCP_COMPLTED_LPOVERLAPPED_SENDPOST_REQ);
440 }
441}
#define IOCP_COMPLTED_LPOVERLAPPED_SENDPOST_REQ
Definition JNetCore.h:21

◆ FreeBufferedSendPacket()

void JNetCore::FreeBufferedSendPacket ( LockFreeQueue< JBuffer * > & sendBufferQueue,
queue< JBuffer * > & sendPostedQueue )
private

세션 제거 시 송신 버퍼 정리

525{
526 while (sendBufferQueue.GetSize() > 0) {
527 JBuffer* sendPacket;
528 if (!sendBufferQueue.Dequeue(sendPacket)) {
529 DebugBreak();
530 }
531 FreeSerialBuff(sendPacket);
532 }
533 while (!sendPostedQueue.empty()) {
534 FreeSerialBuff(sendPostedQueue.front());
535 sendPostedQueue.pop();
536 }
537}

◆ WorkerThreadFunc()

UINT __stdcall JNetCore::WorkerThreadFunc ( void * arg)
staticprivate

IOCP 작업자 스레드의 수행 함수

540{
541 JNetCore* jnetcore = reinterpret_cast<JNetCore*>(arg);
542
543 jnetcore->OnWorkerThreadStart();
544 jnetcore->AllocTlsMemPool();
545
546 while (true) {
547 DWORD transferred = 0;
548 ULONG_PTR completionKey;
549 WSAOVERLAPPED* overlappedPtr;
550
551 // I/O Completion Queue's record
552 // - (1) 송수신된 바이트 수
553 // - (2) 장치와 IOCP 연계 시 지정한 '컴플리션 큐'
554 // => '세션' 식별
555 // - (3) 비동기 I/O 작업 요청 시 사용한 OVERLAPPED 구조체 포인터
556 // => 세션's 수신 OVERELAPPED 구조체 포인터, "수신 완료"
557 // => 세션's 송신 OVERLAPPED 구조체 포인터, "송신 완료"
558 // => IOCP_COMPLTED_LPOVERLAPPED_DISCONNECT / IOCP_COMPLTED_LPOVERLAPPED_SENDPOST_REQ 상수, "Disconnect 요청" / "SendPost" 요청
559 GetQueuedCompletionStatus(jnetcore->m_IOCP, &transferred, (PULONG_PTR)&completionKey, &overlappedPtr, INFINITE);
560 if (overlappedPtr != NULL) {
561
562 JNetSession* session = reinterpret_cast<JNetSession*>(completionKey);
563
564 if (overlappedPtr == (LPOVERLAPPED)IOCP_COMPLTED_LPOVERLAPPED_DISCONNECT) {
565 // Disconnect 요청
566 jnetcore->Proc_DeleteSession(session);
567 }
568 else if (overlappedPtr == (LPOVERLAPPED)IOCP_COMPLTED_LPOVERLAPPED_SENDPOST_REQ) {
569 // SendPost 요청
570 jnetcore->Proc_SendPostRequest(session);
571 }
572 else if (transferred == 0) {
573 // 연결 종료
574 jnetcore->Proc_DeleteSession(session);
575 }
576 else {
577 if (overlappedPtr == &session->m_RecvOverlapped) {
578 // 수신 완료
579 jnetcore->Proc_RecvCompletion(session, transferred);
580 }
581 else if(overlappedPtr == &session->m_SendOverlapped){
582 // 송신 완료
583 jnetcore->Proc_SendCompletion(session);
584 }
585 else {
586 DebugBreak();
587 break;
588 }
589 }
590 }
591 else {
592 //DebugBreak();
593 // => Stop 호출 시 PostQueuedCompletionStatus(m_IOCP, 0, 0, NULL); 를 통해 종료
594 break;
595 }
596 }
597
598 jnetcore->OnWorkerThreadEnd();
599
600 return 0;
601}
클라이언트 TCP 세션의 생명 주기를 'JNetSession'을 통해 관리하며, 하위 클래스 객체의 세션 접근(송신, 수신 처리 및 연결 종료)에 대한 thread-safe 성을 보...
Definition JNetCore.h:41
void Proc_SendPostRequest(JNetSession *session)
IOCP 작업자 스레드의 송신 요청 시 처리 함수(SendPacket 계열 함수의 postToWorker 요청)
Definition JNetCore.cpp:624
void Proc_RecvCompletion(JNetSession *session, DWORD transferred)
IOCP 작업자 스레드의 수신 완료 통지 시 처리 함수
Definition JNetCore.cpp:646
void Proc_DeleteSession(JNetSession *session)
IOCP 작업자 스레드의 세션 삭제 요청 처리 함수
Definition JNetCore.cpp:603
virtual void OnWorkerThreadStart()
개별 IOCP 작업자 스레드의 수행 흐름 초입부(WorkerThreadFunc 함수 초입부)에 호출되는 이벤트 함수, 개별 작업자 스레드의 초기화를 독립적으로 수행하도록 재정의 가능
Definition JNetCore.cpp:250
virtual void OnWorkerThreadEnd()
개별 IOCP 작업자 스레드가 종료(작업자 함수 return) 전 호출되는 이벤트 함수
Definition JNetCore.cpp:252
DWORD AllocTlsMemPool()
직렬화 패킷 버퍼 Tls 풀 할당 함수
Definition JNetCore.h:132
void Proc_SendCompletion(JNetSession *session)
IOCP 작업자 스레드의 송신 완료 통지 시 처리 함수
Definition JNetCore.cpp:690

◆ Proc_DeleteSession()

void jnet::JNetCore::Proc_DeleteSession ( JNetSession * session)
private

IOCP 작업자 스레드의 세션 삭제 요청 처리 함수

604{
605 // 연결 종료 판단
606 int32 ref32 = InterlockedDecrement(reinterpret_cast<long*>(&session->m_SessionRef));
607 JNetSession::SessionRef ref(ref32);
608 if (ref.refCnt < 0) {
609#if defined(ASSERT)
610 DebugBreak();
611#else
612 InterlockedIncrement(reinterpret_cast<long*>(&session->m_SessionRef));
613#endif
614 }
615 else if (ref.refCnt == 0) {
616 // 세션 제거...
617 SessionID64 sessionID = session->m_ID;
618 if (DeleteSession(sessionID)) {
619 OnSessionLeave(sessionID);
620 }
621 }
622}
bool DeleteSession(SessionID64 sessionID)
세션 제거 요청 함수
Definition JNetCore.cpp:488
virtual void OnSessionLeave(SessionID64 sessionID)
JNetCore 단 세션이 제거된 후 호출되는 이벤트 함수
Definition JNetCore.cpp:259
uint64 SessionID64
Definition JNetCore.h:28

◆ Proc_SendPostRequest()

void jnet::JNetCore::Proc_SendPostRequest ( JNetSession * session)
private

IOCP 작업자 스레드의 송신 요청 시 처리 함수(SendPacket 계열 함수의 postToWorker 요청)

625{
626 // IOCP 작업자 스레드 측에서 SendPost 호출
627 SendPost(session->m_ID, true);
628 int32 ref32 = InterlockedDecrement((uint32*)&session->m_SessionRef);
629 JNetSession::SessionRef ref(ref32);
630 if (ref.refCnt < 0) {
631#if defined(ASSERT)
632 DebugBreak();
633#else
634 InterlockedIncrement(reinterpret_cast<long*>(&session->m_SessionRef));
635#endif
636 }
637 else if(ref.refCnt == 0) {
638 // 세션 제거...
639 SessionID64 sessionID = session->m_ID;
640 if (DeleteSession(sessionID)) {
641 OnSessionLeave(sessionID);
642 }
643 }
644}
unsigned __int32 uint32
Definition CommTypes.h:10

◆ Proc_RecvCompletion()

void jnet::JNetCore::Proc_RecvCompletion ( JNetSession * session,
DWORD transferred )
private

IOCP 작업자 스레드의 수신 완료 통지 시 처리 함수

647{
648 session->m_RecvRingBuffer.DirectMoveEnqueueOffset(transferred);
649 UINT recvBuffSize = session->m_RecvRingBuffer.GetUseSize();
650 //if (recvBuffSize > m_MaxOfRecvBufferSize) {
651 // m_MaxOfRecvBufferSize = recvBuffSize;
652 //}
653
654 OnRecvCompletion(session->m_ID, session->m_RecvRingBuffer);
655
656 memset(&session->m_RecvOverlapped, 0, sizeof(session->m_RecvOverlapped));
657 WSABUF wsabuf;
658 wsabuf.buf = (CHAR*)session->m_RecvRingBuffer.GetEnqueueBufferPtr();
659 wsabuf.len = session->m_RecvRingBuffer.GetDirectEnqueueSize();
660 DWORD dwflag = 0;
661
662 if (wsabuf.len == 0) {
663#if defined(ASSERT)
664 // 0 바이트 수신 요청이 발생하는지 확인
665 DebugBreak();
666#else
667 // 임시 조치 (불완전)
668 session->m_RecvRingBuffer.ClearBuffer();
669 wsabuf.buf = reinterpret_cast<char*>(session->m_RecvRingBuffer.GetEnqueueBufferPtr());
670 wsabuf.len = session->m_RecvRingBuffer.GetDirectEnqueueSize();
671#endif
672 }
673
674 if (WSARecv(session->m_Sock, &wsabuf, 1, NULL, &dwflag, &session->m_RecvOverlapped, NULL) == SOCKET_ERROR) {
675 int errcode = WSAGetLastError();
676 if (errcode != WSA_IO_PENDING) {
677 int32 ref32 = InterlockedDecrement((uint32*)&session->m_SessionRef);
678 JNetSession::SessionRef ref(ref32);
679 if (ref.refCnt == 0) {
680 // 세션 제거...
681 SessionID64 sessionID = session->m_ID;
682 if (DeleteSession(sessionID)) {
683 OnSessionLeave(sessionID);
684 }
685 }
686 }
687 }
688}
virtual void OnRecvCompletion(SessionID64 sessionID, JBuffer &recvRingBuffer)=0
IOCP 작업자 스레드의 수신 완료 시 대상 세션의 수신 버퍼의 enqueue 오프셋 제어 후 호출되는 이벤트 함수

◆ Proc_SendCompletion()

void jnet::JNetCore::Proc_SendCompletion ( JNetSession * session)
private

IOCP 작업자 스레드의 송신 완료 통지 시 처리 함수

691{
692 for (int i = 0; i < session->m_SendOverlapped.Offset; i++) {
693 JBuffer* sendBuff = session->m_SendPostedQueue.front();
694 //IncrementSendTransactions(true, sendBuff->GetUseSize());
695 FreeSerialBuff(sendBuff);
696 session->m_SendPostedQueue.pop();
697 }
698
699 InterlockedExchange(reinterpret_cast<long*>(&session->m_SendFlag), 0);
700
701 if (session->m_SendBufferQueue.GetSize() > 0) {
702 SendPost(session->m_ID);
703 }
704
705 int32 ref32 = InterlockedDecrement((uint32*)&session->m_SessionRef);
706 JNetSession::SessionRef ref(ref32);
707 if (ref.refCnt == 0) {
708 // 세션 제거...
709 SessionID64 sessionID = session->m_ID;
710 if (DeleteSession(sessionID)) {
711 OnSessionLeave(sessionID);
712 }
713 }
714}

◆ CalcTpsThreadFunc()

UINT __stdcall jnet::JNetCore::CalcTpsThreadFunc ( void * arg)
staticprivate
717{
718 JNetCore* jnetcore = reinterpret_cast<JNetCore*>(arg);
719
720 // Transaction / TPS / Total Transactions 초기화
721 for (int i = 0; i < NUM_OF_TPS_ITEM; i++) {
722 jnetcore->m_Transactions[i] = 0;
723 jnetcore->m_TransactionsPerSecond[i] = 0;
724 jnetcore->m_TotalTransaction[i] = 0;
725 }
726
727 while (true) {
728 // Transaction / TPS / Total Transactions 갱신
729 for (int i = 0; i < NUM_OF_TPS_ITEM; i++) {
730 jnetcore->m_TransactionsPerSecond[i] = jnetcore->m_Transactions[i];
731 jnetcore->m_TotalTransaction[i] += jnetcore->m_Transactions[i];
732 jnetcore->m_Transactions[i] = 0;
733 }
734
735 Sleep(1000);
736 }
737 return 0;
738}
UINT64 m_TotalTransaction[NUM_OF_TPS_ITEM]
Definition JNetCore.h:245
UINT m_TransactionsPerSecond[NUM_OF_TPS_ITEM]
Definition JNetCore.h:244
static const int NUM_OF_TPS_ITEM
Definition JNetCore.h:233
UINT m_Transactions[NUM_OF_TPS_ITEM]
Definition JNetCore.h:243

◆ GetAcceptTPS()

UINT jnet::JNetCore::GetAcceptTPS ( )
inline
LONG GetTransactionsPerSecond(BYTE type)
Definition JNetCore.h:269

◆ GetRecvTPS()

UINT jnet::JNetCore::GetRecvTPS ( )
inline

◆ GetSendTPS()

UINT jnet::JNetCore::GetSendTPS ( )
inline

◆ GetTotalAcceptTransaction()

UINT64 jnet::JNetCore::GetTotalAcceptTransaction ( )
inline
UINT64 GetTotalTransactions(BYTE type)
Definition JNetCore.h:270

◆ GetTotalRecvTransaction()

UINT64 jnet::JNetCore::GetTotalRecvTransaction ( )
inline

◆ GetTotalSendTransaction()

UINT64 jnet::JNetCore::GetTotalSendTransaction ( )
inline

◆ IncrementRecvTransactions()

void jnet::JNetCore::IncrementRecvTransactions ( bool threadSafe,
UINT incre )
inline
255{if (incre > 0) {IncrementTransactions(RECV_TRANSACTION, threadSafe, incre);}}
void IncrementTransactions(BYTE type, bool threadSafe=false, UINT incre=1)
Definition JNetCore.h:260

◆ IncrementSendTransactions()

void jnet::JNetCore::IncrementSendTransactions ( bool threadSafe,
UINT incre )
inline
256{if (incre > 0) {IncrementTransactions(SEND_TRANSACTION, threadSafe, incre);}}

◆ IncrementAcceptTransactions()

void jnet::JNetCore::IncrementAcceptTransactions ( bool threadSafe = false,
UINT incre = 1 )
inline
257{if (incre > 0) {IncrementTransactions(ACCEPT_TRANSACTION, threadSafe, incre);}}

◆ IncrementTransactions()

void jnet::JNetCore::IncrementTransactions ( BYTE type,
bool threadSafe = false,
UINT incre = 1 )
inlineprivate
260 {
261 if (threadSafe) {
262 if (incre == 1) {InterlockedIncrement(&m_Transactions[type]);}
263 else {InterlockedAdd((LONG*)&m_Transactions[type], incre);}
264 }
265 else {
266 m_Transactions[type] += incre;
267 }
268 }

◆ GetTransactionsPerSecond()

LONG jnet::JNetCore::GetTransactionsPerSecond ( BYTE type)
inlineprivate
269{return m_TransactionsPerSecond[type];}

◆ GetTotalTransactions()

UINT64 jnet::JNetCore::GetTotalTransactions ( BYTE type)
inlineprivate
270{return m_TotalTransaction[type];}

멤버 데이터 문서화

◆ m_Sessions

std::vector<JNetSession*> jnet::JNetCore::m_Sessions
private

세션 관리 벡터

◆ m_MaximumOfSessions

uint16 jnet::JNetCore::m_MaximumOfSessions
private

수용 가능한 최대 세션 수

◆ m_SessionIndexQueue

LockFreeQueue<uint16> jnet::JNetCore::m_SessionIndexQueue
private

세션 인덱스 할당 큐 (SessionID's index part)

◆ m_SessionIncrement

uint64 jnet::JNetCore::m_SessionIncrement
private

세션 증분 (SessionID's increment part)

◆ m_IOCP

HANDLE jnet::JNetCore::m_IOCP
private

JNetCore's IOCP 객체

◆ m_NumOfIocpWorkerThrd

uint16 jnet::JNetCore::m_NumOfIocpWorkerThrd
private

IOCP 작업자 스레드 갯수

◆ m_IocpWorkerThrdHnds

std::vector<HANDLE> jnet::JNetCore::m_IocpWorkerThrdHnds
private

IOCP 작업자 스레드 핸들 벡터

◆ m_IocpWorkerThrdIDs

std::vector<uint32> jnet::JNetCore::m_IocpWorkerThrdIDs
private

IOCP 작업자 스레드's ID 벡터

◆ m_TlsMemPoolMgr

TlsMemPoolManager<JBuffer, true, false> jnet::JNetCore::m_TlsMemPoolMgr
private

Tls 메모리 풀 관리 (직렬화 패킷 버퍼 풀 할당 및 관리자)

◆ m_TlsMemPoolUnitCnt

size_t jnet::JNetCore::m_TlsMemPoolUnitCnt
private

◆ m_TlsMemPoolUnitCapacity

size_t jnet::JNetCore::m_TlsMemPoolUnitCapacity
private

◆ m_MemPoolBuffAllocSize

uint32 jnet::JNetCore::m_MemPoolBuffAllocSize
private

◆ m_CalcTpsFlag

bool jnet::JNetCore::m_CalcTpsFlag
protected

◆ NUM_OF_TPS_ITEM

const int jnet::JNetCore::NUM_OF_TPS_ITEM = 4
staticprivate

◆ m_CalcTpsThread

HANDLE jnet::JNetCore::m_CalcTpsThread
private

◆ m_Transactions

UINT jnet::JNetCore::m_Transactions[NUM_OF_TPS_ITEM]
private

◆ m_TransactionsPerSecond

UINT jnet::JNetCore::m_TransactionsPerSecond[NUM_OF_TPS_ITEM]
private

◆ m_TotalTransaction

UINT64 jnet::JNetCore::m_TotalTransaction[NUM_OF_TPS_ITEM]
private

이 클래스에 대한 문서화 페이지는 다음의 파일들로부터 생성되었습니다.: