home *** CD-ROM | disk | FTP | other *** search
- //--------------------------------------------------------------------------
- //
- // BUFFERS.H: header file for DOSMonitor-based bounded buffer.
- // Copyright (c) J.English 1993.
- // Author's address: je@unix.brighton.ac.uk
- //
- // Permission is granted to use copy and distribute the
- // information contained in this file provided that this
- // copyright notice is retained intact and that any software
- // or other document incorporating this file or parts thereof
- // makes the source code for the library of which this file
- // is a part freely available.
- //
- //--------------------------------------------------------------------------
- //
- // Revision history:
- // 1.0 March 1993 Initial coding
- //
- //--------------------------------------------------------------------------
-
- #ifndef __BUFFERS_H
- #define __BUFFERS_H
-
- #include "threads.h"
-
- //--------------------------------------------------------------------------
- //
- // Class BoundedBuffer.
- //
- // This is a template for a DOSMonitor-based bounded buffer.
- // The constructor requires the size of the buffer as a parameter.
- // The member functions "get" and "put" allow individual data items
- // to be taken out of and put into the buffer. The member function
- // "close" allows the buffer to be closed against further use. The
- // member function "items" returns the number of items currently in
- // the buffer.
- //
- template<class T> class BoundedBuffer : public DOSMonitor
- {
- public:
- BoundedBuffer (unsigned n) : buffer(new T[n]), buffersize(n),
- count(0), inptr(0), outptr(0), closed(0)
- { }
- ~BoundedBuffer () { delete [] buffer; }
-
- unsigned items () { return count; }
-
- int get (T& item); // get an item from the buffer
- int put (const T& item); // put an item into the buffer
- void close (); // close buffer against further use
-
- private:
- DOSMonitorQueue full;
- DOSMonitorQueue empty;
- T* buffer;
- unsigned buffersize;
- unsigned count;
- unsigned inptr;
- unsigned outptr;
- unsigned closed;
- };
-
- //--------------------------------------------------------------------------
- //
- // BoundedBuffer::get.
- //
- // Get an item from the buffer. The thread will be suspended on the
- // "empty" queue as long as the buffer is empty or until the buffer
- // is closed. If the buffer is closed, the function will return 0.
- // Otherwise, the next item is extracted and the "inptr" is moved
- // to point to the next item. Finally, any threads waiting while the
- // buffer is full are resumed (since there is now an empty space in
- // the buffer) and the value 1 is returned to indicate success.
- //
- template <class T> int BoundedBuffer<T>::get (T& item)
- {
- lock ();
- while (count == 0 && !closed)
- suspend (empty); // await non-empty buffer
- if (count != 0)
- { item = buffer [inptr++];
- inptr %= buffersize;
- count--;
- resume (full); // awaken threads waiting for non-full buffer
- }
- unlock ();
- return !closed;
- }
-
-
- //--------------------------------------------------------------------------
- //
- // BoundedBuffer::put.
- //
- // Put an item into the buffer. The thread will be suspended on the
- // "full" queue as long as the buffer is empty or until the buffer
- // is closed. If the buffer is closed, the function will return 0.
- // Otherwise, the item is stored in the next available space and
- // "outptr" is moved to point to the next free space. Finally,
- // any threads waiting while the buffer was empty are resumed (since
- // there is now an item in the buffer) and the value 1 is returned
- // to indicate success.
- //
- template <class T> int BoundedBuffer<T>::put (const T& item)
- {
- lock ();
- while (count == buffersize && !closed)
- suspend (full); // await non-full buffer
- if (count != buffersize)
- { buffer [outptr++] = item;
- outptr %= buffersize;
- count++;
- resume (empty); // awaken threads waiting for non-empty buffer
- }
- unlock ();
- return !closed;
- }
-
- //--------------------------------------------------------------------------
- //
- // BoundedBuffer::close.
- //
- // This function closes the buffer against further use. The "closed"
- // flag is set and any suspended threads are resumed. This is to guard
- // against situations where a thread might wait forever for an item
- // which never arrives, which would prevent the program from ever
- // terminating.
- //
- template <class T> void BoundedBuffer<T>::close ()
- {
- lock ();
- closed = 1;
- resume (full);
- resume (empty);
- unlock ();
- }
-
- #endif
-