I found a threading bug in code I was writing for the hockey management sim I’ve been working on. Or at least, I thought it was a threading bug. I mean, threading is hard, right?
As the player plays this game, a new match will periodically appear in a popup window. The user can click ‘Start’ to watch or ‘Finish’ (at any time) to skip to the end. The window should disappear and then a summary window will appear in its place.
Sometimes (frequently) this would not happen. The match window would not disappear (or at very least a duplicate window would take its place), and the summary window would not show. Because match windows are run in their own thread and the behaviour was intermittent, I assumed that this was a threading problem.
After a few head-scratching days, I found an explanation. The match window was in fact not disappearing. There was no duplicate window. Only on the second click of ‘Finish’ would the window disappear. When someone clicks Finish, the last step is to call the WindowManager and tell it to remove the top window.
Remove the top window. Not the match window, but the top window. There’s the bug. I wasn’t explicit enough in what I was trying to accomplish. I wanted to get rid of the match window, but I said ‘top window’, assuming it would always be on top. It wasn’t always on top if the summary window got added to the WindowManager. (Remember, it’s multithreaded.)
So it kind of is a threading bug, but the fix has nothing to do with threading. To fix this problem, I added a new remove method to WindowManager so I could tell it exactly what I wanted to remove. Then it wouldn’t matter where the summary window thread was.
The moral of the story? Stop making assumptions. Be expressive and explicit!