/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007  The Open Thread Group
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/


//
// Barrier - C++ barrier class
// ~~~~~~~
//

#ifndef _OPENTHREADS_BARRIER_
#define _OPENTHREADS_BARRIER_

#include <OpenThreads/Exports>

namespace OpenThreads {


/**
 *  @class Barrier
 *  @brief This class provides an object-oriented thread barrier interface
 *
 *  @warning It is unwise to use the construct "Barrier barrier" in the
 *           global namespace on sgi's.  The object "barrier"
 *           will confilict with the c-library sproc function "barrier" and
 *           unpredictable results may occur. You have been warned.
 */
class OPENTHREAD_EXPORT_DIRECTIVE Barrier {

public:

    /**
     *  Constructor
     */
    Barrier(int numThreads=0);

    /**
     *  Destructor
     */
    virtual ~Barrier();

    /**
     *  Reset the barrier to it's original state.
     */
    virtual void reset();

    /**
     *  Block until numThreads threads have entered the barrier.
     */
    virtual void block(unsigned int numThreads=0);

    /**
     *  Release the barrier, now.
     */
    virtual void release();

    /**
     *  Return the number of threads currently blocked in the barrier,
     *  Return -1 if error.
     */
    virtual int numThreadsCurrentlyBlocked();


    void invalidate();

private:

    /**
     *  Private copy constructor, to prevent tampering.
     */
    Barrier(const Barrier &/*b*/) {};

    /**
     *  Private copy assignment, to prevent tampering.
     */
    Barrier &operator=(const Barrier &/*b*/) {return *(this);};

    /**
     *  Implementation-specific private data.
     */
    void *_prvData;


    bool _valid;

};

}

#endif // !_OPENTHREADS_BARRIER_