/**
  * File: Concurrency.idl
  * Content: corba definition of monitors and transactions
  * Author: LuisM Pena
  * Date: 28th November 2000
  * Version: 0.51.00
  * Last change:
  *
  **/

#ifndef CONCURRENCY_IDL
#define CONCURRENCY_IDL

#include "DomainMessage.idl"
#include "StateTransfer.idl"

module sensei
{

  module middleware
  {

    module domains
    {

      typedef sensei::middleware::gms::GroupMemberIdList GroupMemberIdList;

      /***********************************************************************/
      /************************* MONITOR *************************************/
      /***********************************************************************/

      exception MonitorException{};

      interface Monitor
      {
        /**
          * Locks the monitor.
          * This locking is reentrant: the member acquiring it can lock it again.
          * As a consequence, if the member intends to access the monitor from
          * different threads, it will have to include the synchronization
          * by itself
          **/
        void lock() raises (MemberStateException);

        /**
          * Unlocks the monitor;
          * @throws MonitorException if the monitor was not locked by this member
          **/
        void unlock() raises (MonitorException, MemberStateException);
      };

      /***********************************************************************/
      /************************* GROUP MONITOR ******************************/
      /***********************************************************************/

      interface GroupMonitor : Monitor, ExtendedCheckpointable
      {
      };

      /***********************************************************************/
      /************************* TRANSACTIONS HANDLER ************************/
      /***********************************************************************/

      /**
       * Exception sent during a startTransaction operation when the group handler associated does not
       * allow transactions (behaviour is not MembersOnTransferExcludedFromGroup)
       */
      exception TransactionException{};

      interface TransactionsHandler
      {
        /**
         * Starts a transaction, locking first the given monitor.
         * Transactions can be nested, but nested transactions only end when the initial transaction
         * is finished.
         * A system on a transaction does not start any state transfer, and all the messages
         * sent by the group handler are queued until the transaction ends. As the result, messages
         * can be seen by other members in different views, and this interface is therefore only
         * allowed under mode MembersOnTransferExcludedFromGroup.
         * @exception MonitorException if the monitor is not valid
         * @exception TransactionException if transactions are not allowed
         */
        void startTransaction(in Monitor locker)
          raises (MonitorException, TransactionException, MemberStateException);

        /**
         * Ends a transaction, unlocking the given monitor. The operation only takes place, in case
         * of nested transactions, when the initial transaction ends.
         * @exception MonitorException if the monitor used for the transaction has been unlocked inside
         *            the transaction
         * @exception TransactionException if transactions are not allowed, or there is not any current transaction
         */
        void endTransaction()
          raises (MonitorException, TransactionException, MemberStateException);
      };

    };
  };
};

#endif