2018년 8월 6일 월요일

setsockopt SO_RCVTIMEO 윈도우에서 적용하기


이번에 개발하면서 recv 블로킹이 해제될 수 있게 타임아웃이 필요함

소켓 옵션중에
setsockopt so_rcvtimeo
통해서 recv 타임아웃을 설정 할 수 있음

근데 타임아웃이 걸리지 않아 찾아보니

https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-setsockopt
윈도우는 DWORD를 사용해야 함

<윈도우용>
DWORD tv = 1000; //밀리세컨드
setsockopt(c->fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));

<그외>
timeval tv = { 0, 10000 }; //seconds, microseconds
setsockopt(c->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

2018년 3월 28일 수요일

크래시 발생 원인 - 메시지 처리

사용하던 코어 코드 중에 간헐적으로 크래시가 발생하는 경우 발생

메시지 큐 방식으로 여러 메시지큐에 동일한 메시지를 던진 상태에서
아래와 같은 코드형태로 처리가 되는 중이었음

 1: auto count = ::InterlockedDecrement64(&pMsg->wait_count);
 2: if(count)
 3: {
 4:    WaitForSingleObject(pMsg->Handle);
 5: }
 6: else
 7: {
 8:    Process(pMsg);
 9:    SAFE_DELETE(pMsg);
10: }

크래시가 발생하는 구간은 형광색 구간이었는데
count = 1 인 상태였다

왜 죽었을까?

원인은 컨태스트 스위칭이 발생하면서
A, B 스레드가 있다고 할때
A에서 2라인을 체크 if 문 안으로 진입 컨테스트 스위칭 발생
B에서 9라인 처리
pMsg는 파기된 상태. 다시 컨테스트 스위칭
A 4라인에서 pMsg는 뎅글링 포인트가 되면서 크래시가 발생


어떻게보면 가장 기초적인 실수중에 하나인데 이 문제로 엄청난 스트레스와 코어 코드의 신뢰를 잃는 큰 손실을 봤다