04WebServer 2を開発していて、稀に発生する謎のバグに遭遇しました。
マルチスレッドに起因するバグで、原因が分かってみれば単純なのですが、なかなか悩みました。
新規接続ごとに内部でIDを振るのですが、リソース管理にバグがあり、タイミングによって同じIDが複数の接続に振られてしまうことが原因でした。
コードは以下のような感じです。
このコードだと、タイミングによっては同じ値のcontextNameが生成される可能性があります。
contextName.Format()終了後に、コンテキストスイッチが発生する可能性があるためです。
以下のように修正しました。
IncCounter()は、インクリメント後の値を返しますので、これで問題ありません。
変な動作をすると思ったら、まさか、こんな単純なミスをしていたとは・・・
マルチスレッドに起因するバグで、原因が分かってみれば単純なのですが、なかなか悩みました。
新規接続ごとに内部でIDを振るのですが、リソース管理にバグがあり、タイミングによって同じIDが複数の接続に振られてしまうことが原因でした。
コードは以下のような感じです。
contextName.Format("Request_%08x", m_contextID); m_contextID.IncCounter();m_contextID.IncCounter()は、排他処理を行うインクリメントです。
このコードだと、タイミングによっては同じ値のcontextNameが生成される可能性があります。
contextName.Format()終了後に、コンテキストスイッチが発生する可能性があるためです。
以下のように修正しました。
IncCounter()は、インクリメント後の値を返しますので、これで問題ありません。
contextName.Format("Request_%08x", m_contextID.IncCounter());マルチスレッドのコードは、気をつけないと単純なミスでハマりますね。
変な動作をすると思ったら、まさか、こんな単純なミスをしていたとは・・・