Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Threads Module User's Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

3.6 The Server Classes

As explained in Section 3.5.1.2, "Runnable Servers," a runnable server is a threaded runnable that accepts and queues any number of runnable objects and executes them within its own internal thread or threads.

The runnable server classes include:

3.6.1 Constructing a Server

The only way to construct a runnable server is to use one of the static make() functions in the two server handle classes, as shown in Example 23.

Example 23: Constructing a runnable server

Each of these classes also have additional static make() functions that accept other parameters:

3.6.2 Starting a Server

The start() member starts a runnable server instance. When a server pool is started, a sufficient number of runnable servers are started and inserted into the pool before waiting for the first runnable to be enqueued.

3.6.3 Enqueuing Runnables on a Server

You use the enqueue() member to enqueue a runnable for execution. Runnables can only be enqueued between calls to start() and stop(). Any attempt to enqueue a runnable before start() and after stop() produces an exception.


This behavior is different from previous versions of the Threading package. Runnables that were enqueued while the server was not running were simply flushed and ignored prior to version 1.2.

The Threading package allows you to specify a guard functor and a priority value for each runnable instance that you pass to a runnable server. Guard functors are defined in Section 3.5.1.3, "Guard Functors."

The priority value is used to establish the order in which unprocessed runnables should be considered for execution by the server. Runnables with higher priority values are evaluated and retrieved for execution before runnables of lower priority.

The capacity of a server's input queue can be limited both at construction and by calling the setCapacity() member. If the capacity of the input queue is limited and the queue becomes full, then the enqueue operations block the caller until the server is able to process a sufficient number of runnables or until the capacity is increased. Each of the basic enqueue() functions is overloaded to give a form that includes a timeout argument. The timeout argument specifies the maximum amount of time to allow for the enqueue operation to complete.

Several functions in the Threading package accept a timeout value. This value is meant to specify the amount of "wall-clock" time, in milliseconds, that a function waits before timing out.


In some situations, functions that accept a timeout value actually measure duration by the amount of CPU time used, not by the elapsed wall-clock time.

This may result in longer timeout periods than are expected or intended. In these situations, the amount of delay is directly proportional to the percentage of available CPU time granted to the process.

3.6.4 Stopping a Server

The stop() member shuts down a server. This function does not wait for the server to shut down, it merely starts the process. Any thread that needs to know when a server has completed shutdown should use join() to wait for the server thread to exit.

Calling stop() to shut down a server pool causes the server pool thread to attempt to stop and join each of the runnable servers within the pool. Each runnable server only stops after completing execution of any enqueued runnables. Should a runnable server within the pool be deadlocked or running in an infinite loop, then the server pool never completes its shutdown, but still might be canceled by another thread.


A server does not join with the runnables it starts, so threaded runnables passed to a server can continue to execute after the server has been shut down. It is your responsibility to join with any threaded runnables you pass to a runnable server.

3.6.5 Interrupting a Server

An RWRunnableServer services an interrupt request immediately after dequeuing a runnable but before executing it.

An RWServerPool can service an interrupt request at two points:

Once the interrupt is released, both types of server continue normal execution.

3.6.6 Canceling a Server

Canceling an RWRunnableServer instance causes the server to attempt to cancel any current, non-threaded runnable being executed.

Canceling an RWServerPool instance causes the server pool to attempt to cancel all runnable server instances within its pool. Each of these runnable servers in turn attempts to cancel the current runnable, if any, that they are currently executing.

3.6.7 Using Server Pool Thread Attributes

Each runnable server thread in a server pool can be initialized using a thread attributes instance. All threads created following server pool startup have the same attributes because the pool attributes are copied when the server pool is started. Changes to the pool thread attributes do not have any affect until the next time the server pool is started. New runnable server threads added as the result of a resize operation use the thread attribute values as defined when the server pool was started, ignoring any recent changes.

3.6.8 Resizing a Server Pool

Use the resize() member to change the number of runnable servers maintained with a pool. This function does not wait for the server to contract the pool, it merely starts the process.

3.6.8.1 Contracting a Server Pool

Calling resize() to contract a server pool causes the server pool thread to attempt to stop and join with enough runnable servers to shrink the pool down to the new size. Each runnable server being stopped only does so after completing execution of any enqueued runnables. Should a sufficient number of runnable servers within the pool be deadlocked or running in an infinite loop, then the server pool can never complete its contraction of the pool, and so will no longer process enqueued runnables. A server pool in this condition can still be canceled.

3.6.8.2 Creating or Expanding a Server Pool

If the server pool experiences failure while attempting to create or start a new runnable server for the pool, then the server pool attempts to shut down all threads in the pool and exits with an exception. Since the pool expansion is performed by the server pool thread, this type of failure can occur at any time, asynchronous to any call to start() or resize(). To detect this kind of failure, periodically test the completion state of the server pool or register a callback for the RW_THR_EXCEPTION state.



Previous fileTop of DocumentContentsNo linkNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo, and SourcePro, are registered trademarks of Rogue Wave Software. All other trademarks are the property of their respective owners.
Provide feedback to Rogue Wave about its documentation.