let write_protect ctl f x =
  Mutex.lock ctl.mutex;
  while ctl.readers > 0 do Condition.wait ctl.write_enable ctl.mutex done;
  unwind_protect f x Mutex.unlock ctl.mutex;;

let read_protect ctl f x =
  Mutex.lock ctl.mutex;
  ctl.readers <- ctl.readers + 1;
  Mutex.unlock ctl.mutex;
  let release() =
    Mutex.lock ctl.mutex;
    ctl.readers <- ctl.readers - 1;
    if ctl.readers = 0 then Condition.broadcast ctl.write_enable;
    Mutex.unlock ctl.mutex in
  unwind_protect f x release ();;