목표: IOCP(Windows) 서버를 IOCP + epoll(Linux) 크로스플랫폼으로 전환
| 항목 | 선택 | 이유 |
|---|---|---|
| 리눅스 환경 | WSL2 | Win10에서 무료·즉시 빌드/실행, 마찰 최소 |
| 빌드 시스템 | CMake 완전 이전 | 양 플랫폼 단일 빌드. MSVC .vcxproj는 리눅스 빌드 불가 |
| 네트워크 추상화 | NetIoModel 컴파일타임 별칭(using) |
게임로직이 OS를 모름 · vtable 비용 0 · 플랫폼 선택을 한 곳에 격리 |
| 백엔드 선택 방식 | CMake가 플랫폼별 소스 컴파일 | 반대편 코드는 바이너리에 아예 미포함(런타임 분기·비용 0) |
| 모델 가시성 | 부팅 로그 I/O model: X |
실행 시 어느 모델인지 한눈에 확인 |
A. CMake 이전 → B. 코어/네트워크 분리(탈Windows화) → C. 코어 리눅스 빌드 → D. epoll 백엔드 구현 → E. 수렴·문서화
(Windows IOCP 서버는 전 과정 동작 유지)
<aside> 🌿
아래 ✅/🔵 완료 항목은 브랜치 feat/cmake-netiomodel 산출물이다. main에는 미병합(CMakeLists·Platform.h·CIniFile 부재) — main 대조로는 확인되지 않으니 브랜치 기준으로 볼 것.
| 단계 | 상태 |
|---|---|
| A. CMake 이전 | ✅ 완료 |
| B. 탈Windows화 (코어/네트워크 분리) | 🔵 거의 완료 (LockFree만 남음) |
| C. 코어 리눅스 빌드 | ⬜ 대기 |
| D. epoll 백엔드 구현 | ⬜ 대기 |
| E. 수렴·문서화 | ⬜ 대기 |
각 단계마다 Windows Release 빌드로 동작 불변을 검증하며 진행.
소켓/IOCP층은 이미 CIOCPServer 뒤로 격리돼 있어 epoll이 교체. 진짜 작업은 전 파일에 새어있던 비-소켓 Windows 의존을 걷어내는 것.
| 항목 | 방식 | 핵심 |
|---|---|---|
Platform seam (Platform.h) |
OS 호출을 얇은 함수로 통합, impl 내부 #ifdef |
타이머·affinity·시그널·exe경로·스레드CPU |
| INI 로더 | GetPrivateProfile* → 자체 파서 CIniFile |
값이 전부 ASCII라 인코딩 무해석 |
| 크래시 덤프 | 원본 SEH+MiniDump를 #ifdef로 보존 + Linux(sigaction+backtrace) |
통합 불가 → 둘 다 살림 |
| CPU 측정 | GetThreadTimes → Platform::ThreadCpuHandle |
Win=핸들+GetThreadTimes / Linux=clock_gettime |
| affinity·종료시그널 | SetProcessAffinityMask·SetConsoleCtrlHandler → Platform | Linux=sched_setaffinity·sigaction |
| 타이머·로거·DB | Sleep→sleep_for / localtime_r / winsock #ifdef |
자명 치환 |
| Interlocked→std::atomic | 통계=Counter(relaxed) · refcount=atomic(seq_cst) | ↓ 아래 T1/T2/T3 |
| 모니터·SerialBuffer | LONG64→int64_t · WriteCounter by-value · refcount atomic | Windows 타입 제거 |
#ifdef(원본 보존)판단 기준: 양 OS에서 도는 포터블 코드 하나로 쓸 수 있나?
#ifdef _WIN32로 둘 다 소스에 공존 — IOCP↔epoll, 크래시덤프크고 검증된 백엔드는 병렬 파일(NetIoModel)로 원본 0-diff 보존. 자잘한 공유코드만 인플레이스 치환.
| 티어 | 대상 | 위험 | 포팅 |
|---|---|---|---|
| T1 통계 카운터 (~70) | 패킷수·구간시간 등 지표 | 낮음 (동기화 무관) | atomic • relaxed |
| T2 세션 상태 (~28) | _ioCount·refcount·_sending |
높음 (동시성 정합) | atomic • seq_cst |
| T3 LockFree DCAS (~19) | InterlockedCompareExchange128 |
최난이도 | 뮤텍스 폴백(회피) |
std::atomic 기본값(seq_cst) = Interlocked와 동일한 full barrier → 드롭인이면 correct.LOCK 접두 명령이라 memory_order와 무관하게 이미 full barrier → 완화해도 같은 기계어 → 이득 0. 그래서 T2는 고민 없이 seq_cst (공짜인데 안전). 완화 이득은 ARM weak model에서만.Counter 래퍼로: relaxed 중앙화, 읽기는 암시변환(표시 코드 불변).operator= 의도적 삭제 → 평문 대입이 전부 컴파일 에러로 잡혀 누락 0._monitor 한정 → 세션상태 T2 자동 제외), 나머지는 컴파일러가 색출.| # | 작업 | 비고 |
|---|---|---|
| B 잔여 | T3 LockFree (DCAS) | SerialBuffer·TimingWheel의 마지막 Linux 관문. 뮤텍스 폴백 |
| B 잔여 | SerialBuffer 타입 (BYTE/WORD/DWORD) | T3 후. DWORD→uint32_t 오버로드 주의 |
| C | 코어 리눅스 빌드 (WSL2 + CMake) | A·B 후 실빌드 검증 |
| D | epoll 백엔드 | EpollServer 신규. 세션상태 atomics(_ioCount 등) 여기서 해소. byte order도 |
USE_RIO 플래그 뒤. Linux 포팅과 별개 트랙이라 서로 안 밟음.EpollServer)관례(운영): 새 소스는 UTF-8 BOM + LF · 변경 검증은 Release 빌드 먼저 · 커밋 메시지 한글은
-F 파일(셸-m잘림) · 통계=Counter(relaxed) / 세션상태=atomic(seq_cst).
</aside>