Wait Abandoned

Posted Wednesday, September 14, 2005 12:05 AM by andy

The other day I answered a question in a programming forum about how to tell that an operation on a worker thread completed.  I answered that you need to create an event to signal that the operation was complete.  Others suggested that you can just wait on the thread.  I really didn’t like the answer but at the time, I didn’t have a good response other then it being a waste of resources.  Thread pools are better since threads have a decent amount of overhead.

Raymond Chen brought up some really good points with his blog about the WAIT_ABANDONED return value of WaitForSingleObject.  When a thread exits you don’t know why it exited.  That’s the real problem with just waiting for a thread, you won’t know what the actual state is when you wake up.  You have to check the results of your worker thread because it could have exited for any reason.

This was one of the biggest headaches I had to deal with when I wrote a connection pool for piccolo objects.  Piccolo is an API for connecting to server processes on a Tandem mainframe.  One of my tasks was hooking a web front end up to a Tandem and querying what were massive databases at the time.  The connection objects had a strange threading model.  They could be shared on multiple threads, but they had to be closed by the thread that created them or havoc would ensue. 

To manage that I created a single constructor/destructor thread whose only responsibility was creating and destroying these connections.  Every call to construct an object had to signal a create event and then wait for a created event to read the new connection handle.  It all worked fine except when you took errors into account.  The requesting thread always had to wait on the creator thread and the event.  It also had to check to see if any exceptions were passed back instead of a valid handle.  A lot more code was written to deal with marshalling all the error conditions then actually handling the connection.

I’d like to see a threading framework that does a better job of managing this type of state.  A call similar to a try catch which only exits after another named block on another thread completes, either through an early exit or the code actually completing.

WorkerThread:

   block TaskItemBlock
   {
       //Do something
   }

Main Thread

   onComplete TaskItemBlock
   {
        //Use results of something
   }
   blockCatch(Exception ex)
   {
     //if TaskItemBlock throws an exception it is caught here.
   }
   invalidExit
   {
     //In an unmanaged world this is possible
   }

A worker thread or a thread pool is a strange construct because it is running something for somebody else, so every result of the code should be able to be bundled up and sent to another thread.  I’ll have to look around and see what varous languages do to deal with this situation.

Filed under:

Comments

No Comments