Package org.jcsp.lang

# Class ProcessManager

java.lang.Object
org.jcsp.lang.ProcessManager

All Implemented Interfaces:
  `CSProcess`

public class ProcessManager extends Object implements CSProcess
This enables a `CSProcess` to be spawned concurrently with the process doing the spawning.

Shortcut to the Constructor and Method Summaries.

## Description

The `ProcessManager` class enables a `CSProcess` to be spawned concurrently with the process doing the spawning. The class provides methods to manage the spawned process: `start`, `join` and `stop`. The spawned process may, of course, be a `Parallel` network of processes to any depth of nesting, in which case the whole network comes under this management.

Spawning processes is not the normal way of creating a network in JCSP - the normal method is to use the `Parallel` class. However, when we need to add processes in response to some run-time event, this capability is very useful.

For completeness, `ProcessManager` is itself a `CSProcess` - `run`ning a `ProcessManager` simply runs the process it is managing.

### Spawning a CSProcess

This example demonstrates that the managed `CSProcess` is executed concurrently with the spawning process and that it dies when its manager terminates. The managed process is `infinite' and just counts and chatters. The managed process is automatically terminated if the main Java thread terminates (as in the case, eventually, below).

     import org.jcsp.lang.*;

     public class ProcessManagerExample1 {

       public static void main (String[] argv) {

         final ProcessManager manager = new ProcessManager (
           new CSProcess () {
             public void run () {
               final CSTimer tim = new CSTimer ();
               long timeout = tim.read ();
               int count = 0;
               while (true) {
                 System.out.println (count + " :-) managed process running ...");
                 count++;
                 timeout += 100;
                 tim.after (timeout);   // every 1/10th of a second ...
               }
             }
           }
         );

         final CSTimer tim = new CSTimer ();
         long timeout = tim.read ();

         System.out.println ("\n\n\t\t\t\t\t
                             *** start the managed process");
         manager.start ();

         for (int i = 0; i invalid input: '<' 10; i++) {
           System.out.println ("\n\n\t\t\t\t\t
                               *** I'm still executing as well");
           timeout += 1000;
           tim.after (timeout);         // every second ...
         }

         System.out.println ("\n\n\t\t\t\t\t
                             *** I'm finishing now!");
       }
     }

### Stopping, Interrupting, Race-Hazards and Poison

Stopping a Java thread releases any locks it (or any sub-process) may be holding, so this reduces the danger of other threads deadlocking through a failure to acquire a needed lock. However, if the stopped process were in the middle of some synchronised transaction, the data update may be incomplete (and, hence, corrupt) depending on the precise moment of the stopping. This is a race-hazard. Further, if some other thread later needed to interact with the stopped thread, it would deadlock.

Instead of stopping a JCSP process, it is much safer to `interrupt` it. This gives the process the chance to notice the interrupt (through an exception handler) and tidy up. If no such handler is provided and the JCSP process attempts any synchronisation afterwards, the process will bomb out with a `ProcessInterruptedException`.

For historical reasons, a `stop()` method is provided below – but it is implemented as `interrupt()` (and deprecated).

If the managed process has gone parallel, managing an interrupt to achieve a clean exit is more tricky. Stopping a network by setting a global `volatile` flag that each process polls from time to time is not safe. For example, a thread blocked on a monitor `wait` will remain blocked if the thread that was going to `notify` it spots the shut-down flag and terminates.

For JCSP processes, there is a general solution to this [`Graceful Termination and Graceful Resetting', P.H.Welch, Proceedings of OUG-10, pp. 310-317, Ed. A.W.P.Bakkers, IOS Press (Amsterdam), ISBN 90 5199 011 1, April, 1989], based on the careful distribution of poison over the network's normal communication channels.

However, JCSP now supports graceful termination of process networks and sub-networks through a notion of poisoning synchoronisation objects (e.g. channels) – see `Poisonable`.

Author:
  P.H. Welch, P.D. Austin
See Also:
  - `CSProcess`
  - `Parallel`
  - `ActiveApplet`
  - `Poisonable`
  - `PoisonException`

## Field Summary

Fields
Modifier and Type
Field
Description
`static final int`
`PRIORITY_MAX`
The maximum priority value for running a process.
`static final int`
`PRIORITY_MIN`
The minimum priority value for running a process.
`static final int`
`PRIORITY_NORM`
The normal priority value for running a process.

## Constructor Summary

Constructors
Constructor
Description
`ProcessManager(CSProcess proc)`

## Method Summary

Modifier and Type
Method
Description
`int`
`getPriority()`
Public accessor for obtaining the `ProcessManager` object's process' priority.
`void`
`interrupt()`
Interrupt the managed process.
`void`
`join()`
Join the managed process (that is wait for it to terminate).
`void`
`run()`
Run the managed process (that is start it and wait for it to terminate).
`void`
`setPriority(int priority)`
Public mutator for setting the `ProcessManager` object's process' priority.
`void`
`start()`
Start the managed process (but keep running ourselves).
`void`
`start(int priority)`
Start the managed process at a specified priority (but keep running ourselves).
`void`
`stop()`
Deprecated.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### PRIORITY_MAX

public static final int PRIORITY_MAX
The maximum priority value for running a process.

See Also:
  - Constant Field Values

### PRIORITY_NORM

public static final int PRIORITY_NORM
The normal priority value for running a process.

See Also:
  - Constant Field Values

### PRIORITY_MIN

public static final int PRIORITY_MIN
The minimum priority value for running a process.

See Also:
  - Constant Field Values

## Constructor Details

### ProcessManager

public ProcessManager(CSProcess proc)

Parameters:
  `proc` - the `CSProcess` to be executed by this ProcessManager

## Method Details

### start

public void start()
Start the managed process (but keep running ourselves).

### start

public void start(int priority)
Start the managed process at a specified priority (but keep running ourselves). The priority of the `ProcessManager` that this is called upon will remain at the specified priority once the process has terminated. The priority should be specified as an `int` between `PRIORITY_MIN`and `PRIORITY_MAX`.````

Parameters:
  `priority` - the priority at which to start the process.

### stop

public void stop()
Deprecated.
Stop (permanently) the managed process. This method now calls interrupt(), which will not always stop the process.

### interrupt

public void interrupt()
Interrupt the managed process. This will usually cause the process to throw a `ProcessInterruptedException`, which will likely halt the process.

### join

public void join()
Join the managed process (that is wait for it to terminate).

### run

public void run()

Run the managed process (that is start it and wait for it to terminate). This will adjust the priority of the calling process to the priority of this `ProcessManager` and then return the priority to the previous value once the managed process has terminated.

The managed process can be run at the caller's priority simply by directly calling the `CSProcess` object's `run()` method.

Specified by:
  `run` in interface `CSProcess`

### setPriority

public void setPriority(int priority)

Public mutator for setting the `ProcessManager` object's process' priority.

The priority should be specified as an `int` between `PRIORITY_MIN`and `PRIORITY_MAX`.````

Parameters:
  `priority` - the priority to use.

### getPriority

public int getPriority()

Public accessor for obtaining the `ProcessManager` object's process' priority.

Returns:
  the priority at which the `ProcessManager` object's process will be run.