se.lth.cs.realtime.event
Class RTEventBuffer

java.lang.Object
  extended byse.lth.cs.realtime.event.RTEventBuffer
All Implemented Interfaces:
RTEventBufferInput, RTEventBufferOutput, Synchronized
Direct Known Subclasses:
Buffer, BufferPlain

public abstract class RTEventBuffer
extends java.lang.Object
implements RTEventBufferInput, RTEventBufferOutput, Synchronized

A thread safe basic queue/buffer for RTEvent objects. Essentially a protected bounded buffer with both blocking and non-blocking methods for posting and fetching messages in terms of references to objects.

For the functionality provided by this basic class, the buffer could have been typed to contain EventObjects (the base class of RTEvent), but to permit subclasses of RTEventBuffer to utilize the properties of the RTEvents that class is used here. For instance, one might need a buffer that keeps track of the total delay of data by referring to the time-stamps of the newest and oldest RTEvent.

The methods checking or awaiting buffer full/empty are useful for operation supervision, capturing events until a buffer is filled, mode changes, etc. Do not misuse them for polled (concurrently bad) or busy-wait solutions.

While events are stored in the buffer, the buffer is set to be the owner of the events, see the RTEvent class. Only events owned by the current thread are accepted for posting to the buffer. When events are fetched, the fetching thread is assigned to be the new owner. This is to be ensured also by subclasses, thereby maintaining the detection of event producers keeping references to objects already sent. In some cases, however, it is desirable to resend (typically immutable) objects. Therefore, events with the owner equal to null is always accepted. The concept of owners is from the OSE operating system.

In practice and by default, all methods can be considered being synchronized, even if the methods as such are not declared to be synchronized. Having the methods synchronized would agree with common application programming practice, and together with the fact that most methods are final, those synchronized methods would remain synchronized is subclasses. However, synchronization is performed on an internal lock object for the following reasons:
1) Other object cannot interfere with the internal wait/notify by synchronizing on an instance of this class (by using a synchronized statement).
2) An external object (provided via the constructor) can be used as the lock object, thereby permitting synchronized use of several buffers/object.

If a blocked call is interrupted, an RTInterrupted (subclass of Error, not an exception) is thrown, and that buffer object is most likely not useful anymore.

See Also:
License, RTInterrupted

Nested Class Summary
 
Nested classes inherited from class se.lth.cs.realtime.Synchronized
Synchronized.Lock
 
Field Summary
protected  RTEvent[] buffer
          The actual buffer.
protected  int currSize
          Current queue size.
static int DEFAULT_SIZE
           
protected  int fetchAt
          Position of first element to fetch, if any.
protected  Synchronized.Lock lock
          The lock to this monitor, which can be replaced in constructor.
protected  int maxSize
          Maximal buffer size.
protected  int postAt
          Free position to insert events at (the successor of last element)
 
Constructor Summary
RTEventBuffer()
          Initializes the buffer with a size of DEFAULT_SIZE.
RTEventBuffer(int maxSize)
          Initializes the queue (buffer) with a given maximal size.
RTEventBuffer(int maxSize, Synchronized.Lock lock)
          Initializes the queue (buffer) with a given maximal size, and with a lock object to be used for synchronization.
 
Method Summary
abstract  int currentSize()
          The current size of the buffer.
abstract  RTEvent doFetch()
          Returns the next RTEvent in the queue, blocks if none available.
abstract  void doPost(RTEvent e)
          Adds an RTEvent to the queue, blocks caller if the queue is full.
protected  void error(java.lang.String message)
          Throws RTInterrupted and possibly some logging.
 RTEvent fetch()
          Returns the next event object in the queue, by default by calling doFetch which is synchronized (opposed to this method) via an internal lock.
abstract  RTEvent[] fetchAll()
          Get all buffered events leaving the buffer empty.
abstract  void flush()
          Removes all buffered events.
abstract  int getMaxSize()
          Gets the maximum size of the buffer.
abstract  boolean isEmpty()
          Checks if buffer is empty.
abstract  boolean isFull()
          Checks if buffer is full.
 RTEvent post(RTEvent e)
          Put the supplied event object last in the queue, by default by calling doPost which is synchronized (opposed to this method).
abstract  RTEvent tryFetch()
          Returns the next available RTEvent in the queue, or null if the queue is empty.
abstract  RTEvent tryFetch(long timeout)
          Get the next RTEvent in the queue, or block (up to the specified timeout time) if no event is available.
abstract  RTEvent tryPost(RTEvent e)
          Adds an EventObject to the queue, without blocking if the queue is full.
abstract  RTEvent tryPost(RTEvent e, long timeout)
          Adds an RTEvent to the queue, blocks caller if the queue is full up to the specified timeout time.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

buffer

protected RTEvent[] buffer
The actual buffer.


currSize

protected int currSize
Current queue size. That is, the number of events currently buffered.


DEFAULT_SIZE

public static final int DEFAULT_SIZE

fetchAt

protected int fetchAt
Position of first element to fetch, if any.


lock

protected Synchronized.Lock lock
The lock to this monitor, which can be replaced in constructor.


maxSize

protected int maxSize
Maximal buffer size.


postAt

protected int postAt
Free position to insert events at (the successor of last element)

Constructor Detail

RTEventBuffer

public RTEventBuffer()
Initializes the buffer with a size of DEFAULT_SIZE.


RTEventBuffer

public RTEventBuffer(int maxSize)
Initializes the queue (buffer) with a given maximal size. A size smaller than one results in a buffer with size one.

Parameters:
maxSize - maximum queue size

RTEventBuffer

public RTEventBuffer(int maxSize,
                     Synchronized.Lock lock)
Initializes the queue (buffer) with a given maximal size, and with a lock object to be used for synchronization.

Parameters:
maxSize - maximum queue size
lock - external monitor/object to synchronized with
Method Detail

currentSize

public abstract int currentSize()
The current size of the buffer.

Returns:
the number of objects currently enqueued
See Also:
maxSize

doFetch

public abstract RTEvent doFetch()
Returns the next RTEvent in the queue, blocks if none available.

Specified by:
doFetch in interface RTEventBufferOutput
Returns:
a non-null event.

doPost

public abstract void doPost(RTEvent e)
Adds an RTEvent to the queue, blocks caller if the queue is full.

Specified by:
doPost in interface RTEventBufferInput
Parameters:
e - the event to enqueue

error

protected void error(java.lang.String message)
Throws RTInterrupted and possibly some logging.


fetch

public RTEvent fetch()
Returns the next event object in the queue, by default by calling doFetch which is synchronized (opposed to this method) via an internal lock. Subclasses overriding this method should be very careful to maintain mutual exclusion, normally by simply declaring fetch as synchronized or by synchronizing on the lock attribute.

Specified by:
fetch in interface RTEventBufferOutput
Returns:
the first event in queue.

fetchAll

public abstract RTEvent[] fetchAll()
Get all buffered events leaving the buffer empty. The event that was the next to be fetched is returned as the first element (index 0), followed by the other events in FIFO order with the most recently posted event as the last element.

Returns:
array containing buffered events. An empty array (not null) is returned if the buffer was empty.

flush

public abstract void flush()
Removes all buffered events.


getMaxSize

public abstract int getMaxSize()
Gets the maximum size of the buffer.

Returns:
the maximum number of objects that can be enqueued

isEmpty

public abstract boolean isEmpty()
Checks if buffer is empty.

Returns:
true if the queue is empty, false if it is non-empty

isFull

public abstract boolean isFull()
Checks if buffer is full.

Returns:
true if the queue is full, false if it is non-full

post

public RTEvent post(RTEvent e)
Put the supplied event object last in the queue, by default by calling doPost which is synchronized (opposed to this method). Subclasses overriding this method should be very careful to maintain mutual exclusion, normally by simply declaring post synchronized or by locking some enclosing monitor/resource. The return value is not useful for the base-class implementation since there is nothing to return from calling doPost. Therefore, null is always returned. The intention of the return value/type is to facilitate the use of tryPost or other (for instance GC-saving) subclass implementations.

Specified by:
post in interface RTEventBufferInput
Returns:
null (or possibly some event according to subclass, if any).

tryFetch

public abstract RTEvent tryFetch()
Returns the next available RTEvent in the queue, or null if the queue is empty. In other words, this method always returns immediately, even if the queue is empty (non-blocking).

Specified by:
tryFetch in interface RTEventBufferOutput
Returns:
an RTEvent if any available, null otherwise

tryFetch

public abstract RTEvent tryFetch(long timeout)
Get the next RTEvent in the queue, or block (up to the specified timeout time) if no event is available.

Specified by:
tryFetch in interface RTEventBufferOutput
Parameters:
timeout - the maximum blocking time time in milli-seconds.
Returns:
an RTEvent if any available within the timeout time, null otherwise.

tryPost

public abstract RTEvent tryPost(RTEvent e)
Adds an EventObject to the queue, without blocking if the queue is full.

Specified by:
tryPost in interface RTEventBufferInput
Parameters:
e - the event to enqueue
Returns:
null when event posted to non-full buffer, the event otherwise

tryPost

public abstract RTEvent tryPost(RTEvent e,
                                long timeout)
Adds an RTEvent to the queue, blocks caller if the queue is full up to the specified timeout time.

Specified by:
tryPost in interface RTEventBufferInput
Parameters:
e - the event to enqueue
timeout - the maximum blocking time time in milli-seconds.
Returns:
null when event posted within the timeout time to non-full buffer, the event otherwise.