txt: ## dist_cpan-JNTHN-OO-Monitors.md
  # OO::Monitors
  
  [![Build Status](https://travis-ci.org/jnthn/oo-monitors.svg?branch=master)](https://travis-ci.org/jnthn/oo-monitors)
  
  A monitor provides per-instance mutual exclusion for objects. This means that
  for a given object instance, only one thread can ever be inside its methods at
  a time. This is achieved by a lock being associated with each object. The lock
  is acquired automatically at the entry to each method in the monitor. Condition
  variables are also supported.
  
  ## Basic Usage
  
  A monitor looks like a normal class, but declared with the `monitor` keyword.
  
  ```
  use OO::Monitors;
  
  monitor IPFilter {
      has %!active;
      has %!blacklist; 
      has $.limit = 10;
      has $.blocked = 0;
      
      method should-start-request($ip) {
          if %!blacklist{$ip} || (%!active{$ip} // 0) == $.limit {
              $!blocked++;
              return False;
          }
          else {
              %!active{$ip}++;
              return True;
          }
      }
      
      method end-request($ip) {
          %!active{$ip}--;
      }
  }
  
  ```
  
  That's about all there is to it. The monitor meta-object enforces mutual
  exclusion.
  
  ## Conditions
  
  Condition variables are declared with the `conditioned` trait on the monitor.
  To wait on a condition, use `wait-condition`. To signal that a condition has
  been met, use `meet-condition`. Here is an example of a bounded queue.
  
  ```
  monitor BoundedQueue is conditioned(< not-full not-empty >) {
      has @!tasks;
      has $.limit = die "Must specify a limit";
      
      method add-task($task) {
          while @!tasks.elems == $!limit {
              wait-condition <not-full>;
          }
          @!tasks.push($task);
          meet-condition <not-empty>;
      }
  
      method take-task() {
          until @!tasks {
              wait-condition <not-empty>;
          }
          meet-condition <not-full>;
          return @!tasks.shift;
      }
  }
  
  ```
  
  When `wait-conditon` is used, the lock is released and the thread blocks until
  the condition is met by some other thread. By contrast, `meet-condition` just
  marks a waiting thread as unblocked, but retains the lock until the method
  is over.
  
  ## Circular waiting
  
  Monitors are vulnerable to deadlock, if you set up a circular dependency. Keep
  object graphs involving monitors simple and cycle-free, so far as is possible.
  