------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 199x by International Computer Science Institute            --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 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 Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------

abstract class $BARRIER_LOCK < $LOCK is end;

class DOOR_LOCK_HELPER < $BARRIER_LOCK is
   include LOCK_INCLUDE;
   readonly attr primary:DOOR_LOCK;
   private attr condition:BOOL;

   create(b:DOOR_LOCK,cond:BOOL):SAME is
      r::=new;
      r.primary:=b;
      r.condition:=cond;
      return r;
   end;
   acquirable(tid:THREAD_ID):BOOL is
      return primary.is_open=condition and primary.acquirable(tid);
   end;

   acquire(tid:THREAD_ID) is  return;end;
   release(tid:THREAD_ID) is return; end;
   request(tid:THREAD_ID) is primary.request(tid); return end;
   cancel_request(tid:THREAD_ID) is primary.cancel_request(tid); return end;
   wait_for(tid:THREAD_ID):ARRAY{THREAD_ID} is return primary.wait_for(tid); end;
   combinations:ARRAY{ARRAY{$LOCK}} is return void; end;
end;

class DOOR_LOCK < $MUTEX is
   include MUTEX_INCLUDE;
   private const mutex_t,open_t,close_t;
   readonly attr is_open:BOOL;

   readonly attr open:$LOCK;
   readonly attr close:$LOCK;

   is_closed:BOOL is return ~is_open; end;

   create:SAME is
      r::=new;
      r.open:=#DOOR_LOCK_HELPER(r,true);
      r.close:=#DOOR_LOCK_HELPER(r,false);
      LM_MULTIPLE_LOCK_MANAGER::create(|r,r.open,r.close|);
      return r;
   end;

   open_door is
      lock when self then is_open:=true; end;
   end;

   close_door is
      lock when self then is_open:=false; end;
   end;
end;
