/*
 * 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: Synchronizeable.h,v 1.13 2003/08/29 11:58:55 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_LANG_SYNCHRONIZEABLE_H
# define INCLUDE_JAKELIB2_LANG_SYNCHRONIZEABLE_H
# include "Mutex.h"
# include "Sentry.h"

#ifdef JAKELIB_THREADS
# define JAKELIB_SYNCHRONIZED(obj) jakelib::lang::Sentry _jakelib2_synchro((obj)->_jakelib2_getMutex())
#else
# define JAKELIB_SYNCHRONIZED(obj)
#endif

namespace jakelib {
  namespace lang {
    class Mutex;

    /**
     * @brief Classes derived from \c Object and \c Synchronizeable have a
     * mutex like all Java objects do.
     *
     * I.e. one can protect critical sections of code by synchronizing on 
     * such an object (see the \c synchronized keyword in Java).
     * The \c JAKELIB_SYNCHRONIZED(obj) macro provides a shortcut to
     * synchronize on the object \c obj (see example below).
     *
     * Note that the \c Synchronizeable 'interface' does not support
     * \c wait() and \c notify(). Hopefully \c Monitorable will do so in the
     * future :-)
     *
     * \b Example:
     *
     * You need an object to synchronize on that is derived from
     * \c Synchronizeable:
     * \code
     *  class Sync : public Object, public Synchronizeable {
     *   public:
     *    Sync() {};
     * };
     * \endcode
     *
     * You need an instance of the new \c Sync class:
     * <code><pre> Sync *sync = new Sync();</pre></code>
     *
     * Now you can synchronize blocks of code on this new synchronizeable
     * object \c sync:
     * \code
     * // some code
     * ...
     * {
     *   JAKELIB_SYNCHRONIZED(sync);
     *   ...
     *   // inside synchronized block!
     *   ...
     * }
     * \endcode
     *
     * The same code written in Java:
     * \code
     * Object sync = new Object();
     *
     * // some code
     * ...
     * synchronized(sync) {
     *   ...
     *   // inside synchronized block!
     *   ...
     * }
     * \endcode
     *
     * @class Synchronizeable
     * @version $Id: Synchronizeable.h,v 1.13 2003/08/29 11:58:55 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class Synchronizeable : public Interface
      {
      public:
	Synchronizeable();

	~Synchronizeable();

        Mutex* _jakelib2_getMutex();

      protected:

#ifdef JAKELIB_THREADS
        Mutex* _jakelib2_mutex;
#endif

        JAKELIB_DECLARE_INTERFACE(Synchronizeable);
      };
  }
}
#endif

