A.23 thread_pool.pl -- Resource bounded thread management

See also
http_handler/3 and http_spawn/2.

The module library(thread_pool) manages threads in pools. A pool defines properties of its member threads and the maximum number of threads that can coexist in the pool. The call thread_create_in_pool/4 allocates a thread in the pool, just like thread_create/3. If the pool is fully allocated it can be asked to wait or raise an error.

The library has been designed to deal with server application that recieve a variety of requests, such as HTTP servers. Simply starting a thread for each request is a bit too simple minded for such servers:

Using this library, one can define a pool for each set of tasks with comparable characteristics and create threads in this pool. Unlike the worker-pool model, threads are not started immediately. Depending on the design, both approaches can be attractive.

The library is implemented by means of a manager thread with the fixed thread id __thread_pool_manager. All state is maintained in this manager thread, which receives and processes requests to create and destroy pools, create threads in a pool and handle messages from terminated threads. Thread pools are not saved in a saved state and must therefore be recreated using the initialization/1 directive or otherwise during startup of the application.

[det]thread_pool_create(+Pool, +Size, +Options)
Create a pool of threads. A pool of threads is a declaration for creating threads with shared properties (stack sizes) and a limited number of threads. Threads are created using thread_create_in_pool/4. If all threads in the pool are in use, the behaviour depends on the wait option of thread_create_in_pool/4 and the backlog option described below. Options are passed to thread_create/3, except for
backlog(+MaxBackLog)
Maximum number of requests that can be suspended. Default is infinite. Otherwise it must be a non-negative integer. Using backlog(0) will never delay thread creation for this pool.

The pooling mechanism does not interact with the detached state of a thread. Threads can be created but detached and normal and must be joined using thread_join/2 if they are not detached.

bug
The thread creation option at_exit is reserved for internal use by this library.
[det]thread_pool_destroy(+Name)
Destroy the thread pool named Name.
Errors
existence_error(thread_pool, Name).
[nondet]current_thread_pool(?Name)
True if Name refers to a defined thread pool.
[nondet]thread_pool_property(?Name, ?Property)
True if Property is a property of thread pool Name. Defined properties are:
options(Options)
Thread creation options for this pool
free(Size)
Number of free slots on this pool
backlog(Size)
Number of delayed thread creations on this pool
[det]thread_create_in_pool(+Pool, :Goal, -Id, +Options)
Create a thread in Pool. Options overrule default thread creation options associated to the pool. In addition, the following option is defined:
wait(+Boolean)
If true (default) and the pool is full, wait until a member of the pool completes. If false, throw a resource_error.
Errors
resource_error(threads_in_pool(Pool)) is raised if wait is false or the backlog limit has been reached.