어제 오늘 삽질하는 거 기록을 해본다.
지난번에 구현했던, Generic IOCP 구조를 바탕으로 Behavior 들을 잘 돌리고 있는데,
클라이언트 쪽에서 몇몇 부분이, worker thread 에서 사용하고 있을 인스턴스를 제거해 버릴 수 있는 코드가 발견되었다.
맵이 바뀐다던지 존이 바뀐다던지 그럴 때, 리소스를 제거하면서 이와 같은 증상이 생길 수 있었다.
이 문제가 생길 수 있는 게, 이 multi thread behavior 를 설계할 때 lock 을 최대한 쓰지 않게끔 구현해서, (실제로 avatar 에 대한 lock 은 걸지 않는다.)
resource 에 연결된 어떤 instance 들이 삭제되더라도 알아챌 방법이 없었던 것이였다.
resource 에 연결된 어떤 instance 들이 삭제되더라도 알아챌 방법이 없었던 것이였다.
그래서 어떻게 처리를 할까 살펴보았는데, 사실 IOCP 를 쓰지 않고 그냥 자체적인 Queue 를 쓴다면,
리소스를 제거하기 전에 Queue 를 비워버리고 현재 worker thread 가 일을 끝마치기를 기다리기만 하면 깔끔하게 해결되는데,
일단, 문제는 IOCP Queue 를 비울 방법이 없고...
완전 Generic 한 Dispatcher 구조다 보니 따로 Flush 를 처리하는 게 여간 번거로운 일이 아닐 수 없게 되었다.
그리고, 대충 만들어서 슥슥 넣게 되면 서로 간섭하지 않게 구조를 설계했었던 방향에 완전히 어긋나 버리게 되기 때문에
어제 몇시간을 이래저래 머리 굴리다가 해결을 못 보고 토요일인 오늘 늦으막하니 출근해서
다시 안돌아가는 머리를 요리조리 굴려서 어느정도 타협할 수 있을 만한 코드를 만들어냈다.
이거하면서 또 애로사항이 그동안 우리 코드에 condition 이나 event 같은 wait object 가 전혀 없어서 이것도 구현해줬고..
멀티플랫폼을 지향하기 때문에 양쪽에 해당하는 거 모두 만들어줘야 하는데,
사실 boost 의 barrier 를 쓰면 되긴 하지만, 이상하게도 thread 동기화에서는 boost 꺼를 쓰고 싶지가 않아서...
이런 동기화들은 각 os 에 특화된 걸 쓰는 게 맞다고 생각하기 때문에...
또한 vista 이상에서는 user mode condition wait 를 쓸 수가 있는데 이것도 구현할까 말까 한참을 고민했었다.
결국엔 그냥 event 로 처리. 물론 wrapper 클래스는 generic 하게.
현재 작업 완료하고 테스트 중인데, 이 상황을 강제로 만들어 내는 게 또 번거롭기 그지없다.
그래도 내가 이부분을 재밌어 하기 때문인지 삽질을 이리 하면서도 별다른 짜증 없이 하고 있다.
어차피 잉여이기 때문에 주말에 약속이 없다는 점도 큰 이점. 응(?)
No comments:
Post a Comment