Copyright (C) Internet Systems Consortium, Inc. ("ISC")

See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.

Changes I made last week to the task code simplified the task shutdown
and termination model.  Here's how things now work:

When a task is shutdown:

	Any "on shutdown" events for the task are posted

	The "shutting down" attribute of the task is set

	Any attempts to add shutdown events with isc_task_onshutdown()
	will fail, since the task is already shutting down

Task shutdown can be initiated explicity, via a call to isc_task_shutdown(),
or implicitly, when the following conditions occur:

	The "shutting down" attribute of the task is not set

	The task has no references

	The task has an empty event queue


Task termination occurs when:

	The "shutting down" attribute of the task is set

	The task has no references

	The task has an empty event queue

Notes from the task/event discussion led by Bob Halley on 13 March 2000:

A task is an event queue.

     (task) --V
            (event)-->(event)-->(event)

      (runnable queue)--V
                      (task)-->(task)-->(task)

Normally only one task manager in an application.

Task becomes runnable if it has a non-empty event queue.

One or more worker threads run tasks.

Event routines should be relatively short.

Only one runnable queue that all workers share.

Events for a task are always posted serially.  Multiple worker threads
will not be working on multiple events for one task at the same time.

isc_event_send, posting an event, can't fail.  It just adds an event
to the task queue.

Event action (callback) rules:
  * no locks held on your behald when entering a callback.
  * not allowed to block, except when aquiring a lock.
  * not allowed to hold a lock when exiting the callback.


TIMERS?

OMAPI -- need taskmgr to omapi_lib_init
  -- one task per client connection
