"semaphore" -- Semaphore classes
********************************

class eventlet.semaphore.Semaphore(value=1)

   An unbounded semaphore. Optionally initialize with a resource
   *count*, then "acquire()" and "release()" resources as needed.
   Attempting to "acquire()" when *count* is zero suspends the calling
   greenthread until *count* becomes nonzero again.

   This is API-compatible with "threading.Semaphore".

   It is a context manager, and thus can be used in a with block:

      sem = Semaphore(2)
      with sem:
        do_some_stuff()

   If not specified, *value* defaults to 1.

   It is possible to limit acquire time:

      sem = Semaphore()
      ok = sem.acquire(timeout=0.1)
      # True if acquired, False if timed out.

   acquire(blocking=True, timeout=None)

      Acquire a semaphore.

      When invoked without arguments: if the internal counter is
      larger than zero on entry, decrement it by one and return
      immediately. If it is zero on entry, block, waiting until some
      other thread has called release() to make it larger than zero.
      This is done with proper interlocking so that if multiple
      acquire() calls are blocked, release() will wake exactly one of
      them up. The implementation may pick one at random, so the order
      in which blocked threads are awakened should not be relied on.
      There is no return value in this case.

      When invoked with blocking set to true, do the same thing as
      when called without arguments, and return true.

      When invoked with blocking set to false, do not block. If a call
      without an argument would block, return false immediately;
      otherwise, do the same thing as when called without arguments,
      and return true.

      Timeout value must be strictly positive.

   balance

      An integer value that represents how many new calls to
      "acquire()" or "release()" would be needed to get the counter to
      0.  If it is positive, then its value is the number of acquires
      that can happen before the next acquire would block.  If it is
      negative, it is the negative of the number of releases that
      would be required in order to make the counter 0 again (one more
      release would push the counter to 1 and unblock acquirers).  It
      takes into account how many greenthreads are currently blocking
      in "acquire()".

   bounded()

      Returns False; for consistency with "CappedSemaphore".

   locked()

      Returns true if a call to acquire would block.

   release(blocking=True)

      Release a semaphore, incrementing the internal counter by one.
      When it was zero on entry and another thread is waiting for it
      to become larger than zero again, wake up that thread.

      The *blocking* argument is for consistency with CappedSemaphore
      and is ignored

class eventlet.semaphore.BoundedSemaphore(value=1)

   A bounded semaphore checks to make sure its current value doesn't
   exceed its initial value. If it does, ValueError is raised. In most
   situations semaphores are used to guard resources with limited
   capacity. If the semaphore is released too many times it's a sign
   of a bug. If not given, *value* defaults to 1.

   release(blocking=True)

      Release a semaphore, incrementing the internal counter by one.
      If the counter would exceed the initial value, raises
      ValueError.  When it was zero on entry and another thread is
      waiting for it to become larger than zero again, wake up that
      thread.

      The *blocking* argument is for consistency with
      "CappedSemaphore" and is ignored

class eventlet.semaphore.CappedSemaphore(count, limit)

   A blockingly bounded semaphore.

   Optionally initialize with a resource *count*, then "acquire()" and
   "release()" resources as needed. Attempting to "acquire()" when
   *count* is zero suspends the calling greenthread until count
   becomes nonzero again.  Attempting to "release()" after *count* has
   reached *limit* suspends the calling greenthread until *count*
   becomes less than *limit* again.

   This has the same API as "threading.Semaphore", though its
   semantics and behavior differ subtly due to the upper limit on
   calls to "release()".  It is **not** compatible with
   "threading.BoundedSemaphore" because it blocks when reaching
   *limit* instead of raising a ValueError.

   It is a context manager, and thus can be used in a with block:

      sem = CappedSemaphore(2)
      with sem:
        do_some_stuff()

   acquire(blocking=True)

      Acquire a semaphore.

      When invoked without arguments: if the internal counter is
      larger than zero on entry, decrement it by one and return
      immediately. If it is zero on entry, block, waiting until some
      other thread has called release() to make it larger than zero.
      This is done with proper interlocking so that if multiple
      acquire() calls are blocked, release() will wake exactly one of
      them up. The implementation may pick one at random, so the order
      in which blocked threads are awakened should not be relied on.
      There is no return value in this case.

      When invoked with blocking set to true, do the same thing as
      when called without arguments, and return true.

      When invoked with blocking set to false, do not block. If a call
      without an argument would block, return false immediately;
      otherwise, do the same thing as when called without arguments,
      and return true.

   balance

      An integer value that represents how many new calls to
      "acquire()" or "release()" would be needed to get the counter to
      0.  If it is positive, then its value is the number of acquires
      that can happen before the next acquire would block.  If it is
      negative, it is the negative of the number of releases that
      would be required in order to make the counter 0 again (one more
      release would push the counter to 1 and unblock acquirers).  It
      takes into account how many greenthreads are currently blocking
      in "acquire()" and "release()".

   bounded()

      Returns true if a call to release would block.

   locked()

      Returns true if a call to acquire would block.

   release(blocking=True)

      Release a semaphore.  In this class, this behaves very much like
      an "acquire()" but in the opposite direction.

      Imagine the docs of "acquire()" here, but with every direction
      reversed.  When calling this method, it will block if the
      internal counter is greater than or equal to *limit*.
