//
// This is a class for guard objects using OpenMP
// It is adapted from the book
// "Pattern-Oriented Software Architecture". 
// Taken from http://www.thinkingparallel.com - Michael Suess
//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
//
#ifndef OMP_GUARD_HPP
#define OMP_GUARD_HPP
 
#include <Config.hpp>
#include <omp.h>

namespace mgx
{ 
  /** 
   * This is a class for guard objects using OpenMP
   *  It is adapted from the book
   *  "Pattern-Oriented Software Architecture". 
   *  Taken from http://www.thinkingparallel.com - Michael Suess
   */
  class mgx_EXPORT OMPGuard 
  {
  public:
    /** Acquire the lock and store a pointer to it */
    OMPGuard (omp_lock_t &lock);
    /** Destruct guard object */
    ~OMPGuard();
   
  private:
    /** Set the lock explicitly */
    void acquire();
    /** Release the lock explicitly (owner thread only!) */
    void release();

    omp_lock_t *_lock;  // pointer to our lock
    bool _owner;   // is this object the owner of the lock?
     
    // Disallow copies or assignment
    OMPGuard(const OMPGuard &);
    void operator=(const OMPGuard &);
  };
}
#endif 
