작성
·
354
0
안녕하세요 Session#1 강의를 듣다가 질문드립니다.
1. Session의 생명주기를 정리해봤는데 선생님께서 의도하신 세션 생명주기와 일치하는지 질문드립니다.
2. RegisterRecv() 하여 REFCOUNT= 4; 가 되었을 때 다음 동작으로
bool IocpCore::Distpatch(uint32 timeoutMs) or void Listener::RegisterAccept(AcceptEvent * acceptEvent)
둘 중 어느 함수가 먼저 호출될지 상황마다 다른건지 궁금합니다.
Dispatch 함수가 먼저 호출될 경우는 REFCOUNT =5 가 되었다가 RegisterAccept에서 세션 교체에 의해 다시 4가 될것이고 RegisterAccept 먼저 호출시에는 REFCOUNT가 3으로 먼저 깎일 수 있기 때문입니다.
3. 디버깅 해보니 AcceptEx나 WSARecv에서 Overlapped 인자로 이벤트 인자를 넘기는데, 이 이벤트 객체의 Reference 카운트가 GetQueuedCompletionStatus 함수에서 꺼내올 때 그대로 유지되는거 같은데 GetQueuedCompletionStatus 전에 누가 Reference 카운트를 1감소 시키면 1감소된 만큼 GetQueuedCompletionStatus 에서 복원될까요?
-----------------------------------------------------------------------------------------
Listener::RegisterAccept() 함수
SessionRef session = _service->CreateSession(); //+1
REFCOUNT = 1
acceptEvent->session = session; //+1
REFCOUNT = 2
SessionRef session = _service->CreateSession(); Register Accept 리턴시 session 지역변수 소멸, -1
REFCOUNT = 1
-----------------------------------------------------------------------------------------
Listener::ProcessAccept() 함수
SessionRef session = acceptEvent->session; //+1
REFCOUNT = 2
-----------------------------------------------------------------------------------------
void Session::ProcessConnect() 함수
GetService()->AddSession(GetSessionRef()); // +1
REFCOUNT = 3
-----------------------------------------------------------------------------------------
void Session::RegisterRecv() 함수
_recvEvent.owner = shared_from_this(); // ADD_REF //+1
REFCOUNT = 4;
-----------------------------------------------------------------------------------------
void Listener::RegisterAccept(AcceptEvent* acceptEvent)
acceptEvent->session = session; // 세션 교체
REFCOUNT = 3;
-----------------------------------------------------------------------------------------
Listener::ProcessAccept() 함수
SessionRef session = acceptEvent->session; // ProcessAccept 함수 소멸시 session 지역변수 소멸,-1
REFCOUNT = 2
-----------------------------------------------------------------------------------------
bool IocpCore::Dispatch(uint32 timeoutMs)
IocpObjectRef iocpObject = iocpEvent->owner; // RegisterRecv IOCP 값으로 owner 가 session 일 경우 +1
REFCOUNT = 3
-----------------------------------------------------------------------------------------
void Session::ProcessRecv(int32 numOfBytes)
_recvEvent.owner = nullptr; // RELEASE_REF ,-1
REFCOUNT = 2
if (numOfBytes == 0) 일경우
GetService()->ReleaseSession(GetSessionRef()); //-1
REFCOUNT = 1
-----------------------------------------------------------------------------------------
bool IocpCore::Dispatch(uint32 timeoutMs)
IocpObjectRef iocpObject = iocpEvent->owner; // Dispatch 리턴시 iocpObject 지역 변수 소멸, -1
REFCOUNT = 0
답변 1
1
RefCount는 관리되고 있다는 사실이 중요하지,
누가 어떻게 어느 순서로 줄이고 늘이는지는 관심을 둘 필요 없습니다.
나중에 가면 Session또한 컨텐츠 코드에서 (SessionManager 등)
들고 있기 때문에 더 늘어날 수도 있습니다.
3. 디버깅 해보니 AcceptEx나 WSARecv에서 Overlapped 인자로 이벤트 인자를 넘기는데, 이 이벤트 객체의 Reference 카운트가 GetQueuedCompletionStatus 함수에서 꺼내올 때 그대로 유지되는거 같은데 GetQueuedCompletionStatus 전에 누가 Reference 카운트를 1감소 시키면 1감소된 만큼 GetQueuedCompletionStatus 에서 복원될까요?
GQCS에 넘겨준건 단순히 주소일 뿐이고,
여기에다 우리가 무엇을 해준 것은 아니기에
'당연히' GQCS 이후 외부에서 누가 건드리지 않는다면, RefCount는 그대로 유지됩니다.
GQCS 전에 누가 RefCount를 조작하면, 최종 결과 수치를 가진 객체로 복원됩니다.