'Release the lock.'

def release(self):

    me = current_thread()
    with self._lock:
        if self.is_exclusive:
            if (self._exclusive_owner is not me):
                raise LockingError(u'release()    called    on    unheld    lock')
            self.is_exclusive -= 1
            if (not self.is_exclusive):
                self._exclusive_owner = None
                if self._shared_queue:
                    for (thread, waiter) in self._shared_queue:
                        self.is_shared += 1
                        self._shared_owners[thread] = 1
                        waiter.notify()
                    del self._shared_queue[:]
                elif self._exclusive_queue:
                    (thread, waiter) = self._exclusive_queue.pop(0)
                    self._exclusive_owner = thread
                    self.is_exclusive += 1
                    waiter.notify()
        elif self.is_shared:
            try:
                self._shared_owners[me] -= 1
                if (self._shared_owners[me] == 0):
                    del self._shared_owners[me]
            except KeyError:
                raise LockingError(u'release()    called    on    unheld    lock')
            self.is_shared -= 1
            if (not self.is_shared):
                if self._exclusive_queue:
                    (thread, waiter) = self._exclusive_queue.pop(0)
                    self._exclusive_owner = thread
                    self.is_exclusive += 1
                    waiter.notify()
                else:
                    assert (not self._shared_queue)
        else:
            raise LockingError(u'release()    called    on    unheld    lock')
