// -*- c++ -*-

/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: Mutex.h,v 1.11 2003/09/26 09:31:11 florian Exp $
 */

#ifdef JAKELIB_THREADS
# ifndef INCLUDE_JAKELIB2_LANG_MUTEX_H
#  define INCLUDE_JAKELIB2_LANG_MUTEX_H

#  ifdef HAVE_PTHREAD_H
#   include <pthread.h>
#  endif
#  if defined(JAKELIB_WIN32API)
#   include <windows.h>
#  endif

namespace jakelib {
  namespace lang {

    /**
     * A Mutex for synchronization in multi-threaded programs.
     *
     * Mutexes cannot be shared between different processes.
     * Mutexes are internally used in \c Synchronizeable. => only use
     * them if you know what you are doing.
     *
     * @class Mutex
     * @version $Id: Mutex.h,v 1.11 2003/09/26 09:31:11 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class Mutex : public Object
    {
    public:

      /**
       * Creates a new \c Mutex object.
       */
      Mutex();

      ~Mutex();

      /**
       * Locks the mutex.
       *
       * If the mutex is locked when a thread calls this method,
       * the thread waits for the mutex to become available.
       *
       * The thread that has locked a mutex becomes its current owner
       * and remains the owner until the same thread has unlocked it.
       * This method returns with the mutex in the locked state and with
       * the current thread as the mutex's current owner. 
       */
      void lock();

      /**
       * Unlocks the mutex.
       *
       * If no threads are waiting for the mutex, the mutex unlocks
       * with no current owner. If one or more threads are waiting
       * to lock the specified mutex, this routine causes one thread
       * to return from its call to \c lock(). The scheduling policy
       * is used to determine which thread acquires the mutex.
       *
       * The results of calling this routine are unpredictable if
       * the mutex specified in mutex is unlocked. The results of
       * calling this routine are also unpredictable if the mutex
       * specified in mutex is currently owned by a thread other
       * than the calling thread. 
       */
      void unlock();

      /**
       * @brief Destroys this \c Mutex object.
       */
      void destroy();

      static void initMutexClass();

    protected:

#if defined(JAKELIB_WIN32API)
      HANDLE mutex;
      CRITICAL_SECTION cs;
#elif defined(HAVE_PTHREADS)
      pthread_mutex_t mutex;
      static pthread_mutexattr_t *mutexAttr;
#endif

      jboolean destroyed;

      JAKELIB_DECLARE_CLASS(Mutex);
    };
  }
}

# endif
#endif

