Archive for June, 2007

Deadlock Avoidance

Developer's Cave, Potential RPG No Comments »

Here’s a hacky technique that is preventing a particular deadlock in the MMORPG client.

Due to Java’s AWT painting rules, the AWT/Swing thread must be used when painting components. Unfortunately, I’ve introduced thread contention between the AWT thread and the world Rendering thread. In the right circumstance, these threads deadlock on each other (each holds a lock the other needs).

The real solution is to resolve the contention. Putting this off for a rainy day, I’ve implemented a quick-and-dirty deadlock avoidance approach. First, note that I’m using the elegant java.util.concurrent.locks API (rather than synchronized keyword). I must acquire a lock within my JPanel’s paintComponent(Graphics g) method. Instead of calling Lock.lock(), call Lock.tryLock(timeout) with some arbitrary (short) timeout. If the Rendering and AWT threads are deadlocked, the AWT thread will soon release its resources and the Rendering can continue.

Leveraging the passive nature of AWT painting, the failed attempt is re-dispatched by calling repaint(clip) (passing the clipping region of the original paint request). Hopefully, the thread contention is cleared up on the subsequent paintComponent. If not, this technique risks forever requesting repaints (more logic could catch this and trigger client failure, or maybe try to restart the Rendering engine).

Debugging shows this happens rarely, but cleans up nicely. There is the potential to leave some graphic artifacts when the AWT paint fails, but this is tolerable for now. In any case, this hacky fix is better than the client locking up.

Correct: No. Elegant: Almost. Clever: Barely. Recommended: Absolutely not.

Intermittent Tinkering

Potential RPG No Comments »

I’ve been intermittently tinkering with the code (darn this nice weather, darn it to heck). As with most of my childhood toys, I’ve been taking code apart and putting it back together, throwing away the inexplicable extra pieces. As a result, you’ll find some things work better, while others are broken in entirely new ways.

For example, client-server connection handling is more stable. However, upon logging in, the world might not paint itself. How are these changes related? They’re not, but timing issues are often flushed out of the brush when other things change.

Brief list of technical fixes:

  • A crashed client should no longer take down the server… (but I’ve made that promise before)
  • Client no longer operates in a busy loop — completely event-triggered (better design, IMnsHO)
  • Client almost shuts down cleanly (pesky AWT thread won’t die); Server stops on a dime

Brief list of technical flaws:

  • Although Server uses java.nio non-blocking channel output, it appears that one slow/dead client may delay packet sending to others (must not allow server output to stall, will use cached thread pool)
  • See issue tracking system for more

I must make the game stable. It’s a moral imperative.

UPDATE: Despite my paltry hours as of late, I believe the client is more stable than ever (which is not saying too much). Primarily, the blank-world bug should be dead (a logic mistake caused initial character position to be ignored in a specific situation).