{
    "file_diffs": [
        {
            "old_file_content": "# Copyright 2015 The Tornado Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass Condition(object):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n    \"\"\"\n\n    def __init__(self):\n        self.io_loop = ioloop.IOLoop.current()\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            self.io_loop.add_timeout(timeout, on_timeout)\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters, if many coroutines wait with a\n        # timeout but notify is called rarely.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        for waiter in self._waiters:\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\n",
            "new_file_content": "# Copyright 2015 The Tornado Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass Condition(object):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n    \"\"\"\n\n    def __init__(self):\n        self.io_loop = ioloop.IOLoop.current()\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            self.io_loop.add_timeout(timeout, on_timeout)\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters, if many coroutines wait with a\n        # timeout but notify is called rarely.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        while self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\n",
            "header": {
                "file": {
                    "path": "tornado/locks.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "8c9ffb8e",
                "new_commit_hash": "ea2e89d9",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/locks.py"
            },
            "plus_file": {
                "path": "b/tornado/locks.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 181,
                            "length": 7
                        },
                        "new_range": {
                            "start": 181,
                            "length": 8
                        },
                        "section": "class Semaphore(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    def release(self):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Increment the counter and wake one waiter.\"\"\"",
                                "type": "context"
                            },
                            {
                                "content": "        self._value += 1",
                                "type": "context"
                            },
                            {
                                "content": "        for waiter in self._waiters:",
                                "type": "deleted"
                            },
                            {
                                "content": "        while self._waiters:",
                                "type": "added"
                            },
                            {
                                "content": "            waiter = self._waiters.popleft()",
                                "type": "added"
                            },
                            {
                                "content": "            if not waiter.done():",
                                "type": "context"
                            },
                            {
                                "content": "                self._value -= 1",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/locks.py",
                            "type": "class",
                            "name": "Semaphore",
                            "content": "class Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        for waiter in self._waiters:\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 146,
                            "end_lineno": 225,
                            "parent": null
                        },
                        {
                            "file_name": "tornado/locks.py",
                            "type": "method",
                            "name": "Semaphore.release",
                            "content": "class Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        for waiter in self._waiters:\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 181,
                            "end_lineno": 195,
                            "parent": {
                                "file_name": "tornado/locks.py",
                                "type": "class",
                                "name": "Semaphore",
                                "content": "class Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        for waiter in self._waiters:\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 146,
                                "end_lineno": 225,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        self.assertFalse((yield c.wait(timedelta(seconds=0.01))))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait(timedelta(seconds=1))\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "new_file_content": "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        self.assertFalse((yield c.wait(timedelta(seconds=0.01))))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait(timedelta(seconds=1))\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "header": {
                "file": {
                    "path": "tornado/test/locks_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "fa7d0e4f",
                "new_commit_hash": "aabb8040",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/locks_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/locks_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 248,
                            "length": 6
                        },
                        "new_range": {
                            "start": 248,
                            "length": 7
                        },
                        "section": "class SemaphoreTest(AsyncTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        sem.release()",
                                "type": "context"
                            },
                            {
                                "content": "        # Now acquire() is instant.",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertTrue(sem.acquire().done())",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(0, len(sem._waiters))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    @gen_test",
                                "type": "context"
                            },
                            {
                                "content": "    def test_acquire_timeout(self):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/locks_test.py",
                            "type": "method",
                            "name": "SemaphoreTest.test_acquire",
                            "content": "class SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 233,
                            "end_lineno": 251,
                            "parent": {
                                "file_name": "tornado/test/locks_test.py",
                                "type": "class",
                                "name": "SemaphoreTest",
                                "content": "class SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 219,
                                "end_lineno": 275,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/test/locks_test.py",
                            "type": "class",
                            "name": "SemaphoreTest",
                            "content": "class SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 219,
                            "end_lineno": 275,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83^",
    "new_commit_hash": "7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83",
    "commit_message": "Merge pull request #1356 from ajdavis/semaphore-memleak\n\nFix memory leak in Semaphore.",
    "commit_date": "2015-02-28T14:47:23-05:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83",
    "test_file_codes": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom datetime import timedelta\n\nfrom tornado import gen, locks\nfrom tornado.gen import TimeoutError\nfrom tornado.testing import gen_test, AsyncTestCase\nfrom tornado.test.util import unittest\n\n\nclass ConditionTest(AsyncTestCase):\n    def setUp(self):\n        super(ConditionTest, self).setUp()\n        self.history = []\n\n    def record_done(self, future, key):\n        \"\"\"Record the resolution of a Future returned by Condition.wait.\"\"\"\n        def callback(_):\n            if not future.result():\n                # wait() resolved to False, meaning it timed out.\n                self.history.append('timeout')\n            else:\n                self.history.append(key)\n        future.add_done_callback(callback)\n\n    def test_repr(self):\n        c = locks.Condition()\n        self.assertIn('Condition', repr(c))\n        self.assertNotIn('waiters', repr(c))\n        c.wait()\n        self.assertIn('waiters', repr(c))\n\n    @gen_test\n    def test_notify(self):\n        c = locks.Condition()\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait()\n\n    def test_notify_1(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 'wait1')\n        self.record_done(c.wait(), 'wait2')\n        c.notify(1)\n        self.history.append('notify1')\n        c.notify(1)\n        self.history.append('notify2')\n        self.assertEqual(['wait1', 'notify1', 'wait2', 'notify2'],\n                         self.history)\n\n    def test_notify_n(self):\n        c = locks.Condition()\n        for i in range(6):\n            self.record_done(c.wait(), i)\n\n        c.notify(3)\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(list(range(3)), self.history)\n        c.notify(1)\n        self.assertEqual(list(range(4)), self.history)\n        c.notify(2)\n        self.assertEqual(list(range(6)), self.history)\n\n    def test_notify_all(self):\n        c = locks.Condition()\n        for i in range(4):\n            self.record_done(c.wait(), i)\n\n        c.notify_all()\n        self.history.append('notify_all')\n\n        # Callbacks execute in the order they were registered.\n        self.assertEqual(\n            list(range(4)) + ['notify_all'],\n            self.history)\n\n    @gen_test\n    def test_wait_timeout(self):\n        c = locks.Condition()\n        self.assertFalse((yield c.wait(timedelta(seconds=0.01))))\n\n    @gen_test\n    def test_wait_timeout_preempted(self):\n        c = locks.Condition()\n\n        # This fires before the wait times out.\n        self.io_loop.call_later(0.01, c.notify)\n        yield c.wait(timedelta(seconds=1))\n\n    @gen_test\n    def test_notify_n_with_timeout(self):\n        # Register callbacks 0, 1, 2, and 3. Callback 1 has a timeout.\n        # Wait for that timeout to expire, then do notify(2) and make\n        # sure everyone runs. Verifies that a timed-out callback does\n        # not count against the 'n' argument to notify().\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n        self.record_done(c.wait(), 3)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify(2)\n        yield gen.sleep(0.01)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        self.assertEqual(['timeout', 0, 2], self.history)\n        c.notify()\n        self.assertEqual(['timeout', 0, 2, 3], self.history)\n\n    @gen_test\n    def test_notify_all_with_timeout(self):\n        c = locks.Condition()\n        self.record_done(c.wait(), 0)\n        self.record_done(c.wait(timedelta(seconds=0.01)), 1)\n        self.record_done(c.wait(), 2)\n\n        # Wait for callback 1 to time out.\n        yield gen.sleep(0.02)\n        self.assertEqual(['timeout'], self.history)\n\n        c.notify_all()\n        self.assertEqual(['timeout', 0, 2], self.history)\n\n    @gen_test\n    def test_nested_notify(self):\n        # Ensure no notifications lost, even if notify() is reentered by a\n        # waiter calling notify().\n        c = locks.Condition()\n\n        # Three waiters.\n        futures = [c.wait() for _ in range(3)]\n\n        # First and second futures resolved. Second future reenters notify(),\n        # resolving third future.\n        futures[1].add_done_callback(lambda _: c.notify())\n        c.notify(2)\n        self.assertTrue(all(f.done() for f in futures))\n\n    @gen_test\n    def test_garbage_collection(self):\n        # Test that timed-out waiters are occasionally cleaned from the queue.\n        c = locks.Condition()\n        for _ in range(101):\n            c.wait(timedelta(seconds=0.01))\n\n        future = c.wait()\n        self.assertEqual(102, len(c._waiters))\n\n        # Let first 101 waiters time out, triggering a collection.\n        yield gen.sleep(0.02)\n        self.assertEqual(1, len(c._waiters))\n\n        # Final waiter is still active.\n        self.assertFalse(future.done())\n        c.notify()\n        self.assertTrue(future.done())\n\n\nclass EventTest(AsyncTestCase):\n    def test_repr(self):\n        event = locks.Event()\n        self.assertTrue('clear' in str(event))\n        self.assertFalse('set' in str(event))\n        event.set()\n        self.assertFalse('clear' in str(event))\n        self.assertTrue('set' in str(event))\n\n    def test_event(self):\n        e = locks.Event()\n        future_0 = e.wait()\n        e.set()\n        future_1 = e.wait()\n        e.clear()\n        future_2 = e.wait()\n\n        self.assertTrue(future_0.done())\n        self.assertTrue(future_1.done())\n        self.assertFalse(future_2.done())\n\n    @gen_test\n    def test_event_timeout(self):\n        e = locks.Event()\n        with self.assertRaises(TimeoutError):\n            yield e.wait(timedelta(seconds=0.01))\n\n        # After a timed-out waiter, normal operation works.\n        self.io_loop.add_timeout(timedelta(seconds=0.01), e.set)\n        yield e.wait(timedelta(seconds=1))\n\n    def test_event_set_multiple(self):\n        e = locks.Event()\n        e.set()\n        e.set()\n        self.assertTrue(e.is_set())\n\n    def test_event_wait_clear(self):\n        e = locks.Event()\n        f0 = e.wait()\n        e.clear()\n        f1 = e.wait()\n        e.set()\n        self.assertTrue(f0.done())\n        self.assertTrue(f1.done())\n\n\nclass SemaphoreTest(AsyncTestCase):\n    def test_negative_value(self):\n        self.assertRaises(ValueError, locks.Semaphore, value=-1)\n\n    def test_repr(self):\n        sem = locks.Semaphore()\n        self.assertIn('Semaphore', repr(sem))\n        self.assertIn('unlocked,value:1', repr(sem))\n        sem.acquire()\n        self.assertIn('locked', repr(sem))\n        self.assertNotIn('waiters', repr(sem))\n        sem.acquire()\n        self.assertIn('waiters', repr(sem))\n\n    def test_acquire(self):\n        sem = locks.Semaphore()\n        f0 = sem.acquire()\n        self.assertTrue(f0.done())\n\n        # Wait for release().\n        f1 = sem.acquire()\n        self.assertFalse(f1.done())\n        f2 = sem.acquire()\n        sem.release()\n        self.assertTrue(f1.done())\n        self.assertFalse(f2.done())\n        sem.release()\n        self.assertTrue(f2.done())\n\n        sem.release()\n        # Now acquire() is instant.\n        self.assertTrue(sem.acquire().done())\n        self.assertEqual(0, len(sem._waiters))\n\n    @gen_test\n    def test_acquire_timeout(self):\n        sem = locks.Semaphore(2)\n        yield sem.acquire()\n        yield sem.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield sem.acquire(timedelta(seconds=0.01))\n\n        f = sem.acquire()\n        sem.release()\n        self.assertTrue(f.done())\n\n    def test_release_unacquired(self):\n        # Unbounded releases are allowed, and increment the semaphore's value.\n        sem = locks.Semaphore()\n        sem.release()\n        sem.release()\n\n        # Now the counter is 3. We can acquire three times before blocking.\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertTrue(sem.acquire().done())\n        self.assertFalse(sem.acquire().done())\n\n\nclass SemaphoreContextManagerTest(AsyncTestCase):\n    @gen_test\n    def test_context_manager(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire()) as yielded:\n            self.assertTrue(yielded is None)\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_exception(self):\n        sem = locks.Semaphore()\n        with self.assertRaises(ZeroDivisionError):\n            with (yield sem.acquire()):\n                1 / 0\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout(self):\n        sem = locks.Semaphore()\n        with (yield sem.acquire(timedelta(seconds=0.01))):\n            pass\n\n        # Semaphore was released and can be acquired again.\n        self.assertTrue(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_timeout_error(self):\n        sem = locks.Semaphore(value=0)\n        with self.assertRaises(gen.TimeoutError):\n            with (yield sem.acquire(timedelta(seconds=0.01))):\n                pass\n\n        # Counter is still 0.\n        self.assertFalse(sem.acquire().done())\n\n    @gen_test\n    def test_context_manager_contended(self):\n        sem = locks.Semaphore()\n        history = []\n\n        @gen.coroutine\n        def f(index):\n            with (yield sem.acquire()):\n                history.append('acquired %d' % index)\n                yield gen.sleep(0.01)\n                history.append('release %d' % index)\n\n        yield [f(i) for i in range(2)]\n\n        expected_history = []\n        for i in range(2):\n            expected_history.extend(['acquired %d' % i, 'release %d' % i])\n\n        self.assertEqual(expected_history, history)\n\n    @gen_test\n    def test_yield_sem(self):\n        # Ensure we catch a \"with (yield sem)\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Semaphore()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with sem\", which should be\n        # \"with (yield sem.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Semaphore():\n                pass\n\n\nclass BoundedSemaphoreTest(AsyncTestCase):\n    def test_release_unacquired(self):\n        sem = locks.BoundedSemaphore()\n        self.assertRaises(ValueError, sem.release)\n        # Value is 0.\n        sem.acquire()\n        # Block on acquire().\n        future = sem.acquire()\n        self.assertFalse(future.done())\n        sem.release()\n        self.assertTrue(future.done())\n        # Value is 1.\n        sem.release()\n        self.assertRaises(ValueError, sem.release)\n\n\nclass LockTests(AsyncTestCase):\n    def test_repr(self):\n        lock = locks.Lock()\n        # No errors.\n        repr(lock)\n        lock.acquire()\n        repr(lock)\n\n    def test_acquire_release(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        future = lock.acquire()\n        self.assertFalse(future.done())\n        lock.release()\n        self.assertTrue(future.done())\n\n    @gen_test\n    def test_acquire_fifo(self):\n        lock = locks.Lock()\n        self.assertTrue(lock.acquire().done())\n        N = 5\n        history = []\n\n        @gen.coroutine\n        def f(idx):\n            with (yield lock.acquire()):\n                history.append(idx)\n\n        futures = [f(i) for i in range(N)]\n        self.assertFalse(any(future.done() for future in futures))\n        lock.release()\n        yield futures\n        self.assertEqual(list(range(N)), history)\n\n    @gen_test\n    def test_acquire_timeout(self):\n        lock = locks.Lock()\n        lock.acquire()\n        with self.assertRaises(gen.TimeoutError):\n            yield lock.acquire(deadline=timedelta(seconds=0.01))\n\n        # Still locked.\n        self.assertFalse(lock.acquire().done())\n\n    def test_multi_release(self):\n        lock = locks.Lock()\n        self.assertRaises(RuntimeError, lock.release)\n        lock.acquire()\n        lock.release()\n        self.assertRaises(RuntimeError, lock.release)\n\n    @gen_test\n    def test_yield_lock(self):\n        # Ensure we catch a \"with (yield lock)\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(gen.BadYieldError):\n            with (yield locks.Lock()):\n                pass\n\n    def test_context_manager_misuse(self):\n        # Ensure we catch a \"with lock\", which should be\n        # \"with (yield lock.acquire())\".\n        with self.assertRaises(RuntimeError):\n            with locks.Lock():\n                pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 818ms\nPrepared 1 package in 1.16s\nInstalled 1 package in 0.95ms\n + tornado==4.2.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83)\nResolved 29 packages in 18ms\nInstalled 29 packages in 158ms\n + attrs==24.3.0\n + automat==24.8.1\n + cachetools==5.5.0\n + cffi==1.17.1\n + chardet==5.2.0\n + colorama==0.4.6\n + constantly==23.10.4\n + distlib==0.3.9\n + exceptiongroup==1.2.2\n + filelock==3.16.1\n + hyperlink==21.0.0\n + idna==3.10\n + incremental==24.7.2\n + iniconfig==2.0.0\n + packaging==24.2\n + platformdirs==4.3.6\n + pluggy==1.5.0\n + pycares==4.5.0\n + pycparser==2.22\n + pycurl==7.45.4\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + setuptools==75.6.0\n + tomli==2.2.1\n + tox==4.23.2\n + twisted==24.11.0\n + typing-extensions==4.12.2\n + virtualenv==20.28.0\n + zope-interface==7.2\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83\n....................................\ncollected 36 items\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BoundedSemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::ConditionTest::test_garbage_collection\nPASSED r2e_tests.test_1::ConditionTest::test_nested_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify_1\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_repr\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout_preempted\nPASSED r2e_tests.test_1::EventTest::test_event\nPASSED r2e_tests.test_1::EventTest::test_event_set_multiple\nPASSED r2e_tests.test_1::EventTest::test_event_timeout\nPASSED r2e_tests.test_1::EventTest::test_event_wait_clear\nPASSED r2e_tests.test_1::EventTest::test_repr\nPASSED r2e_tests.test_1::LockTests::test_acquire_fifo\nPASSED r2e_tests.test_1::LockTests::test_acquire_release\nPASSED r2e_tests.test_1::LockTests::test_acquire_timeout\nPASSED r2e_tests.test_1::LockTests::test_context_manager_misuse\nPASSED r2e_tests.test_1::LockTests::test_multi_release\nPASSED r2e_tests.test_1::LockTests::test_repr\nPASSED r2e_tests.test_1::LockTests::test_yield_lock\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_contended\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_exception\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_misuse\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout_error\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_yield_sem\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout\nPASSED r2e_tests.test_1::SemaphoreTest::test_negative_value\nPASSED r2e_tests.test_1::SemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::SemaphoreTest::test_repr\n=================== 36 passed in 0.19s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83\n....................................\ncollected 36 items\n\n=================================== FAILURES ===================================\n__________ SemaphoreTest.test_acquire __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83/tornado/testing.py\", line 120, in __call__\n    result = self.orig_method(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_7ebed4ac9c5ad8bedac6c8ce4c5d50fef401bf83/r2e_tests/test_1.py\", line 251, in test_acquire\n    self.assertEqual(0, len(sem._waiters))\nAssertionError: 0 != 2\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::BoundedSemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::ConditionTest::test_garbage_collection\nPASSED r2e_tests.test_1::ConditionTest::test_nested_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify\nPASSED r2e_tests.test_1::ConditionTest::test_notify_1\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all\nPASSED r2e_tests.test_1::ConditionTest::test_notify_all_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n\nPASSED r2e_tests.test_1::ConditionTest::test_notify_n_with_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_repr\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout\nPASSED r2e_tests.test_1::ConditionTest::test_wait_timeout_preempted\nPASSED r2e_tests.test_1::EventTest::test_event\nPASSED r2e_tests.test_1::EventTest::test_event_set_multiple\nPASSED r2e_tests.test_1::EventTest::test_event_timeout\nPASSED r2e_tests.test_1::EventTest::test_event_wait_clear\nPASSED r2e_tests.test_1::EventTest::test_repr\nPASSED r2e_tests.test_1::LockTests::test_acquire_fifo\nPASSED r2e_tests.test_1::LockTests::test_acquire_release\nPASSED r2e_tests.test_1::LockTests::test_acquire_timeout\nPASSED r2e_tests.test_1::LockTests::test_context_manager_misuse\nPASSED r2e_tests.test_1::LockTests::test_multi_release\nPASSED r2e_tests.test_1::LockTests::test_repr\nPASSED r2e_tests.test_1::LockTests::test_yield_lock\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_contended\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_exception\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_misuse\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_context_manager_timeout_error\nPASSED r2e_tests.test_1::SemaphoreContextManagerTest::test_yield_sem\nFAILED r2e_tests.test_1::SemaphoreTest::test_acquire\nPASSED r2e_tests.test_1::SemaphoreTest::test_acquire_timeout\nPASSED r2e_tests.test_1::SemaphoreTest::test_negative_value\nPASSED r2e_tests.test_1::SemaphoreTest::test_release_unacquired\nPASSED r2e_tests.test_1::SemaphoreTest::test_repr\n=================== 1 failed, 35 passed in 0.18s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/locks.py tornado/test/locks_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Semaphore Release Does Not Clear Waiters, Causing Acquire Test to Fail**

When releasing a semaphore, the internal waiters queue is not properly cleared. This leads to unexpected behavior where the semaphore retains waiters even after they should have been released, causing tests that expect no remaining waiters to fail.

**Buggy Code Example:**

```python
sem = locks.Semaphore()
f0 = sem.acquire()
f1 = sem.acquire()
f2 = sem.acquire()
sem.release()
# At this point, sem._waiters is expected to be empty
```

**Expected Behavior:**
After releasing the semaphore, all waiters should be cleared, and `sem._waiters` should have a length of 0.

**Actual Behavior:**
After releasing the semaphore, `sem._waiters` still contains waiters, resulting in `len(sem._waiters)` being greater than 0. This causes assertions that expect no remaining waiters to fail.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/locks.py
# Copyright 2015 The Tornado Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from __future__ import absolute_import, division, print_function, with_statement

__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']

import collections

from tornado import gen, ioloop
from tornado.concurrent import Future


class Condition(object):
    """A condition allows one or more coroutines to wait until notified.

    Like a standard `threading.Condition`, but does not need an underlying lock
    that is acquired and released.
    """

    def __init__(self):
        self.io_loop = ioloop.IOLoop.current()
        self._waiters = collections.deque()  # Futures.
        self._timeouts = 0

    def __repr__(self):
        result = '<%s' % (self.__class__.__name__, )
        if self._waiters:
            result += ' waiters[%s]' % len(self._waiters)
        return result + '>'

    def wait(self, timeout=None):
        """Wait for `.notify`.

        Returns a `.Future` that resolves ``True`` if the condition is notified,
        or ``False`` after a timeout.
        """
        waiter = Future()
        self._waiters.append(waiter)
        if timeout:
            def on_timeout():
                waiter.set_result(False)
                self._garbage_collect()
            self.io_loop.add_timeout(timeout, on_timeout)
        return waiter

    def notify(self, n=1):
        """Wake ``n`` waiters."""
        waiters = []  # Waiters we plan to run right now.
        while n and self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():  # Might have timed out.
                n -= 1
                waiters.append(waiter)

        for waiter in waiters:
            waiter.set_result(True)

    def notify_all(self):
        """Wake all waiters."""
        self.notify(len(self._waiters))

    def _garbage_collect(self):
        # Occasionally clear timed-out waiters, if many coroutines wait with a
        # timeout but notify is called rarely.
        self._timeouts += 1
        if self._timeouts > 100:
            self._timeouts = 0
            self._waiters = collections.deque(
                w for w in self._waiters if not w.done())


class Event(object):
    """An event blocks coroutines until its internal flag is set to True.

    Similar to `threading.Event`.
    """
    def __init__(self):
        self._future = Future()

    def __repr__(self):
        return '<%s %s>' % (
            self.__class__.__name__, 'set' if self.is_set() else 'clear')

    def is_set(self):
        """Return ``True`` if the internal flag is true."""
        return self._future.done()

    def set(self):
        """Set the internal flag to ``True``. All waiters are awakened.

        Calling `.wait` once the flag is set will not block.
        """
        if not self._future.done():
            self._future.set_result(None)

    def clear(self):
        """Reset the internal flag to ``False``.
        
        Calls to `.wait` will block until `.set` is called.
        """
        if self._future.done():
            self._future = Future()

    def wait(self, timeout=None):
        """Block until the internal flag is true.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        if timeout is None:
            return self._future
        else:
            return gen.with_timeout(timeout, self._future)


class _ReleasingContextManager(object):
    """Releases a Lock or Semaphore at the end of a "with" statement.

        with (yield semaphore.acquire()):
            pass

        # Now semaphore.release() has been called.
    """
    def __init__(self, obj):
        self._obj = obj

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._obj.release()


class Semaphore(object):
    """A lock that can be acquired a fixed number of times before blocking.

    A Semaphore manages a counter representing the number of `.release` calls
    minus the number of `.acquire` calls, plus an initial value. The `.acquire`
    method blocks if necessary until it can return without making the counter
    negative.

    `.acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> semaphore = locks.Semaphore()
    >>> @gen.coroutine
    ... def f():
    ...    with (yield semaphore.acquire()):
    ...        # Do something holding the semaphore.
    ...        pass
    ...
    ...    # Now the semaphore is released.
    """
    def __init__(self, value=1):
        if value < 0:
            raise ValueError('semaphore initial value must be >= 0')

        self._value = value
        self._waiters = collections.deque()

    def __repr__(self):
        res = super(Semaphore, self).__repr__()
        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(
            self._value)
        if self._waiters:
            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))
        return '<{0} [{1}]>'.format(res[1:-1], extra)

    def release(self):
        """Increment the counter and wake one waiter."""
        self._value += 1
        for waiter in self._waiters:
            if not waiter.done():
                self._value -= 1

                # If the waiter is a coroutine paused at
                #
                #     with (yield semaphore.acquire()):
                #
                # then the context manager's __exit__ calls release() at the end
                # of the "with" block.
                waiter.set_result(_ReleasingContextManager(self))
                break

    def acquire(self, timeout=None):
        """Decrement the counter. Returns a Future.

        Block if the counter is zero and wait for a `.release`. The Future
        raises `.TimeoutError` after the deadline.
        """
        if self._value > 0:
            self._value -= 1
            future = Future()
            future.set_result(_ReleasingContextManager(self))
        else:
            waiter = Future()
            self._waiters.append(waiter)
            if timeout:
                future = gen.with_timeout(timeout, waiter,
                                          quiet_exceptions=gen.TimeoutError)

                # Set waiter's exception after the deadline.
                gen.chain_future(future, waiter)
            else:
                future = waiter
        return future

    def __enter__(self):
        raise RuntimeError(
            "Use Semaphore like 'with (yield semaphore.acquire())', not like"
            " 'with semaphore'")

    __exit__ = __enter__


class BoundedSemaphore(Semaphore):
    """A semaphore that prevents release() being called too many times.

    If `.release` would increment the semaphore's value past the initial
    value, it raises `ValueError`. Semaphores are mostly used to guard
    resources with limited capacity, so a semaphore released too many times
    is a sign of a bug.
    """
    def __init__(self, value=1):
        super(BoundedSemaphore, self).__init__(value=value)
        self._initial_value = value

    def release(self):
        """Increment the counter and wake one waiter."""
        if self._value >= self._initial_value:
            raise ValueError("Semaphore released too many times")
        super(BoundedSemaphore, self).release()


class Lock(object):
    """A lock for coroutines.

    A Lock begins unlocked, and `acquire` locks it immediately. While it is
    locked, a coroutine that yields `acquire` waits until another coroutine
    calls `release`.

    Releasing an unlocked lock raises `RuntimeError`.

    `acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> lock = locks.Lock()
    >>>
    >>> @gen.coroutine
    ... def f():
    ...    with (yield lock.acquire()):
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.
    """
    def __init__(self):
        self._block = BoundedSemaphore(value=1)

    def __repr__(self):
        return "<%s _block=%s>" % (
            self.__class__.__name__,
            self._block)

    def acquire(self, deadline=None):
        """Attempt to lock. Returns a Future.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        return self._block.acquire(deadline)

    def release(self):
        """Unlock.

        The first coroutine in line waiting for `acquire` gets the lock.

        If not locked, raise a `RuntimeError`.
        """
        try:
            self._block.release()
        except ValueError:
            raise RuntimeError('release unlocked lock')

    def __enter__(self):
        raise RuntimeError(
            "Use Lock like 'with (yield lock)', not like 'with lock'")

    __exit__ = __enter__

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Semaphore Release Does Not Clear Waiters, Causing Acquire Test to Fail**

When releasing a semaphore, the internal waiters queue is not properly cleared. This leads to unexpected behavior where the semaphore retains waiters even after they should have been released, causing tests that expect no remaining waiters to fail.

**Buggy Code Example:**

```python
sem = locks.Semaphore()
f0 = sem.acquire()
f1 = sem.acquire()
f2 = sem.acquire()
sem.release()
# At this point, sem._waiters is expected to be empty
```

**Expected Behavior:**
After releasing the semaphore, all waiters should be cleared, and `sem._waiters` should have a length of 0.

**Actual Behavior:**
After releasing the semaphore, `sem._waiters` still contains waiters, resulting in `len(sem._waiters)` being greater than 0. This causes assertions that expect no remaining waiters to fail.
[/ISSUE]
{
    "BoundedSemaphoreTest.test_release_unacquired": "PASSED",
    "ConditionTest.test_garbage_collection": "PASSED",
    "ConditionTest.test_nested_notify": "PASSED",
    "ConditionTest.test_notify": "PASSED",
    "ConditionTest.test_notify_1": "PASSED",
    "ConditionTest.test_notify_all": "PASSED",
    "ConditionTest.test_notify_all_with_timeout": "PASSED",
    "ConditionTest.test_notify_n": "PASSED",
    "ConditionTest.test_notify_n_with_timeout": "PASSED",
    "ConditionTest.test_repr": "PASSED",
    "ConditionTest.test_wait_timeout": "PASSED",
    "ConditionTest.test_wait_timeout_preempted": "PASSED",
    "EventTest.test_event": "PASSED",
    "EventTest.test_event_set_multiple": "PASSED",
    "EventTest.test_event_timeout": "PASSED",
    "EventTest.test_event_wait_clear": "PASSED",
    "EventTest.test_repr": "PASSED",
    "LockTests.test_acquire_fifo": "PASSED",
    "LockTests.test_acquire_release": "PASSED",
    "LockTests.test_acquire_timeout": "PASSED",
    "LockTests.test_context_manager_misuse": "PASSED",
    "LockTests.test_multi_release": "PASSED",
    "LockTests.test_repr": "PASSED",
    "LockTests.test_yield_lock": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_contended": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_exception": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_misuse": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_timeout": "PASSED",
    "SemaphoreContextManagerTest.test_context_manager_timeout_error": "PASSED",
    "SemaphoreContextManagerTest.test_yield_sem": "PASSED",
    "SemaphoreTest.test_acquire": "PASSED",
    "SemaphoreTest.test_acquire_timeout": "PASSED",
    "SemaphoreTest.test_negative_value": "PASSED",
    "SemaphoreTest.test_release_unacquired": "PASSED",
    "SemaphoreTest.test_repr": "PASSED"
}
diff --git a/tornado/locks.py b/tornado/locks.py
index 8c9ffb8e..ea2e89d9 100644
--- a/tornado/locks.py
+++ b/tornado/locks.py
@@ -181,7 +181,8 @@ class Semaphore(object):
     def release(self):
         """Increment the counter and wake one waiter."""
         self._value += 1
-        for waiter in self._waiters:
+        while self._waiters:
+            waiter = self._waiters.popleft()
             if not waiter.done():
                 self._value -= 1
 

{"tornado/locks.py": "# Copyright 2015 The Tornado Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\n__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']\n\nimport collections\n\nfrom tornado import gen, ioloop\nfrom tornado.concurrent import Future\n\n\nclass Condition(object):\n    \"\"\"A condition allows one or more coroutines to wait until notified.\n\n    Like a standard `threading.Condition`, but does not need an underlying lock\n    that is acquired and released.\n    \"\"\"\n\n    def __init__(self):\n        self.io_loop = ioloop.IOLoop.current()\n        self._waiters = collections.deque()  # Futures.\n        self._timeouts = 0\n\n    def __repr__(self):\n        result = '<%s' % (self.__class__.__name__, )\n        if self._waiters:\n            result += ' waiters[%s]' % len(self._waiters)\n        return result + '>'\n\n    def wait(self, timeout=None):\n        \"\"\"Wait for `.notify`.\n\n        Returns a `.Future` that resolves ``True`` if the condition is notified,\n        or ``False`` after a timeout.\n        \"\"\"\n        waiter = Future()\n        self._waiters.append(waiter)\n        if timeout:\n            def on_timeout():\n                waiter.set_result(False)\n                self._garbage_collect()\n            self.io_loop.add_timeout(timeout, on_timeout)\n        return waiter\n\n    def notify(self, n=1):\n        \"\"\"Wake ``n`` waiters.\"\"\"\n        waiters = []  # Waiters we plan to run right now.\n        while n and self._waiters:\n            waiter = self._waiters.popleft()\n            if not waiter.done():  # Might have timed out.\n                n -= 1\n                waiters.append(waiter)\n\n        for waiter in waiters:\n            waiter.set_result(True)\n\n    def notify_all(self):\n        \"\"\"Wake all waiters.\"\"\"\n        self.notify(len(self._waiters))\n\n    def _garbage_collect(self):\n        # Occasionally clear timed-out waiters, if many coroutines wait with a\n        # timeout but notify is called rarely.\n        self._timeouts += 1\n        if self._timeouts > 100:\n            self._timeouts = 0\n            self._waiters = collections.deque(\n                w for w in self._waiters if not w.done())\n\n\nclass Event(object):\n    \"\"\"An event blocks coroutines until its internal flag is set to True.\n\n    Similar to `threading.Event`.\n    \"\"\"\n    def __init__(self):\n        self._future = Future()\n\n    def __repr__(self):\n        return '<%s %s>' % (\n            self.__class__.__name__, 'set' if self.is_set() else 'clear')\n\n    def is_set(self):\n        \"\"\"Return ``True`` if the internal flag is true.\"\"\"\n        return self._future.done()\n\n    def set(self):\n        \"\"\"Set the internal flag to ``True``. All waiters are awakened.\n\n        Calling `.wait` once the flag is set will not block.\n        \"\"\"\n        if not self._future.done():\n            self._future.set_result(None)\n\n    def clear(self):\n        \"\"\"Reset the internal flag to ``False``.\n        \n        Calls to `.wait` will block until `.set` is called.\n        \"\"\"\n        if self._future.done():\n            self._future = Future()\n\n    def wait(self, timeout=None):\n        \"\"\"Block until the internal flag is true.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        if timeout is None:\n            return self._future\n        else:\n            return gen.with_timeout(timeout, self._future)\n\n\nclass _ReleasingContextManager(object):\n    \"\"\"Releases a Lock or Semaphore at the end of a \"with\" statement.\n\n        with (yield semaphore.acquire()):\n            pass\n\n        # Now semaphore.release() has been called.\n    \"\"\"\n    def __init__(self, obj):\n        self._obj = obj\n\n    def __enter__(self):\n        pass\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._obj.release()\n\n\nclass Semaphore(object):\n    \"\"\"A lock that can be acquired a fixed number of times before blocking.\n\n    A Semaphore manages a counter representing the number of `.release` calls\n    minus the number of `.acquire` calls, plus an initial value. The `.acquire`\n    method blocks if necessary until it can return without making the counter\n    negative.\n\n    `.acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> semaphore = locks.Semaphore()\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield semaphore.acquire()):\n    ...        # Do something holding the semaphore.\n    ...        pass\n    ...\n    ...    # Now the semaphore is released.\n    \"\"\"\n    def __init__(self, value=1):\n        if value < 0:\n            raise ValueError('semaphore initial value must be >= 0')\n\n        self._value = value\n        self._waiters = collections.deque()\n\n    def __repr__(self):\n        res = super(Semaphore, self).__repr__()\n        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(\n            self._value)\n        if self._waiters:\n            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))\n        return '<{0} [{1}]>'.format(res[1:-1], extra)\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        self._value += 1\n        for waiter in self._waiters:\n            if not waiter.done():\n                self._value -= 1\n\n                # If the waiter is a coroutine paused at\n                #\n                #     with (yield semaphore.acquire()):\n                #\n                # then the context manager's __exit__ calls release() at the end\n                # of the \"with\" block.\n                waiter.set_result(_ReleasingContextManager(self))\n                break\n\n    def acquire(self, timeout=None):\n        \"\"\"Decrement the counter. Returns a Future.\n\n        Block if the counter is zero and wait for a `.release`. The Future\n        raises `.TimeoutError` after the deadline.\n        \"\"\"\n        if self._value > 0:\n            self._value -= 1\n            future = Future()\n            future.set_result(_ReleasingContextManager(self))\n        else:\n            waiter = Future()\n            self._waiters.append(waiter)\n            if timeout:\n                future = gen.with_timeout(timeout, waiter,\n                                          quiet_exceptions=gen.TimeoutError)\n\n                # Set waiter's exception after the deadline.\n                gen.chain_future(future, waiter)\n            else:\n                future = waiter\n        return future\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Semaphore like 'with (yield semaphore.acquire())', not like\"\n            \" 'with semaphore'\")\n\n    __exit__ = __enter__\n\n\nclass BoundedSemaphore(Semaphore):\n    \"\"\"A semaphore that prevents release() being called too many times.\n\n    If `.release` would increment the semaphore's value past the initial\n    value, it raises `ValueError`. Semaphores are mostly used to guard\n    resources with limited capacity, so a semaphore released too many times\n    is a sign of a bug.\n    \"\"\"\n    def __init__(self, value=1):\n        super(BoundedSemaphore, self).__init__(value=value)\n        self._initial_value = value\n\n    def release(self):\n        \"\"\"Increment the counter and wake one waiter.\"\"\"\n        if self._value >= self._initial_value:\n            raise ValueError(\"Semaphore released too many times\")\n        super(BoundedSemaphore, self).release()\n\n\nclass Lock(object):\n    \"\"\"A lock for coroutines.\n\n    A Lock begins unlocked, and `acquire` locks it immediately. While it is\n    locked, a coroutine that yields `acquire` waits until another coroutine\n    calls `release`.\n\n    Releasing an unlocked lock raises `RuntimeError`.\n\n    `acquire` supports the context manager protocol:\n\n    >>> from tornado import gen, locks\n    >>> lock = locks.Lock()\n    >>>\n    >>> @gen.coroutine\n    ... def f():\n    ...    with (yield lock.acquire()):\n    ...        # Do something holding the lock.\n    ...        pass\n    ...\n    ...    # Now the lock is released.\n    \"\"\"\n    def __init__(self):\n        self._block = BoundedSemaphore(value=1)\n\n    def __repr__(self):\n        return \"<%s _block=%s>\" % (\n            self.__class__.__name__,\n            self._block)\n\n    def acquire(self, deadline=None):\n        \"\"\"Attempt to lock. Returns a Future.\n\n        Returns a Future, which raises `tornado.gen.TimeoutError` after a\n        timeout.\n        \"\"\"\n        return self._block.acquire(deadline)\n\n    def release(self):\n        \"\"\"Unlock.\n\n        The first coroutine in line waiting for `acquire` gets the lock.\n\n        If not locked, raise a `RuntimeError`.\n        \"\"\"\n        try:\n            self._block.release()\n        except ValueError:\n            raise RuntimeError('release unlocked lock')\n\n    def __enter__(self):\n        raise RuntimeError(\n            \"Use Lock like 'with (yield lock)', not like 'with lock'\")\n\n    __exit__ = __enter__\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Semaphore Release Does Not Clear Waiters, Causing Acquire Test to Fail**

When releasing a semaphore, the internal waiters queue is not properly cleared. This leads to unexpected behavior where the semaphore retains waiters even after they should have been released, causing tests that expect no remaining waiters to fail.

**Buggy Code Example:**

```python
sem = locks.Semaphore()
f0 = sem.acquire()
f1 = sem.acquire()
f2 = sem.acquire()
sem.release()
# At this point, sem._waiters is expected to be empty
```

**Expected Behavior:**
After releasing the semaphore, all waiters should be cleared, and `sem._waiters` should have a length of 0.

**Actual Behavior:**
After releasing the semaphore, `sem._waiters` still contains waiters, resulting in `len(sem._waiters)` being greater than 0. This causes assertions that expect no remaining waiters to fail.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/locks.py
# Copyright 2015 The Tornado Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from __future__ import absolute_import, division, print_function, with_statement

__all__ = ['Condition', 'Event', 'Semaphore', 'BoundedSemaphore', 'Lock']

import collections

from tornado import gen, ioloop
from tornado.concurrent import Future


class Condition(object):
    """A condition allows one or more coroutines to wait until notified.

    Like a standard `threading.Condition`, but does not need an underlying lock
    that is acquired and released.
    """

    def __init__(self):
        self.io_loop = ioloop.IOLoop.current()
        self._waiters = collections.deque()  # Futures.
        self._timeouts = 0

    def __repr__(self):
        result = '<%s' % (self.__class__.__name__, )
        if self._waiters:
            result += ' waiters[%s]' % len(self._waiters)
        return result + '>'

    def wait(self, timeout=None):
        """Wait for `.notify`.

        Returns a `.Future` that resolves ``True`` if the condition is notified,
        or ``False`` after a timeout.
        """
        waiter = Future()
        self._waiters.append(waiter)
        if timeout:
            def on_timeout():
                waiter.set_result(False)
                self._garbage_collect()
            self.io_loop.add_timeout(timeout, on_timeout)
        return waiter

    def notify(self, n=1):
        """Wake ``n`` waiters."""
        waiters = []  # Waiters we plan to run right now.
        while n and self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():  # Might have timed out.
                n -= 1
                waiters.append(waiter)

        for waiter in waiters:
            waiter.set_result(True)

    def notify_all(self):
        """Wake all waiters."""
        self.notify(len(self._waiters))

    def _garbage_collect(self):
        # Occasionally clear timed-out waiters, if many coroutines wait with a
        # timeout but notify is called rarely.
        self._timeouts += 1
        if self._timeouts > 100:
            self._timeouts = 0
            self._waiters = collections.deque(
                w for w in self._waiters if not w.done())


class Event(object):
    """An event blocks coroutines until its internal flag is set to True.

    Similar to `threading.Event`.
    """
    def __init__(self):
        self._future = Future()

    def __repr__(self):
        return '<%s %s>' % (
            self.__class__.__name__, 'set' if self.is_set() else 'clear')

    def is_set(self):
        """Return ``True`` if the internal flag is true."""
        return self._future.done()

    def set(self):
        """Set the internal flag to ``True``. All waiters are awakened.

        Calling `.wait` once the flag is set will not block.
        """
        if not self._future.done():
            self._future.set_result(None)

    def clear(self):
        """Reset the internal flag to ``False``.
        
        Calls to `.wait` will block until `.set` is called.
        """
        if self._future.done():
            self._future = Future()

    def wait(self, timeout=None):
        """Block until the internal flag is true.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        if timeout is None:
            return self._future
        else:
            return gen.with_timeout(timeout, self._future)


class _ReleasingContextManager(object):
    """Releases a Lock or Semaphore at the end of a "with" statement.

        with (yield semaphore.acquire()):
            pass

        # Now semaphore.release() has been called.
    """
    def __init__(self, obj):
        self._obj = obj

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._obj.release()


class Semaphore(object):
    """A lock that can be acquired a fixed number of times before blocking.

    A Semaphore manages a counter representing the number of `.release` calls
    minus the number of `.acquire` calls, plus an initial value. The `.acquire`
    method blocks if necessary until it can return without making the counter
    negative.

    `.acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> semaphore = locks.Semaphore()
    >>> @gen.coroutine
    ... def f():
    ...    with (yield semaphore.acquire()):
    ...        # Do something holding the semaphore.
    ...        pass
    ...
    ...    # Now the semaphore is released.
    """
    def __init__(self, value=1):
        if value < 0:
            raise ValueError('semaphore initial value must be >= 0')

        self._value = value
        self._waiters = collections.deque()

    def __repr__(self):
        res = super(Semaphore, self).__repr__()
        extra = 'locked' if self._value == 0 else 'unlocked,value:{0}'.format(
            self._value)
        if self._waiters:
            extra = '{0},waiters:{1}'.format(extra, len(self._waiters))
        return '<{0} [{1}]>'.format(res[1:-1], extra)

    def release(self):
        """Increment the counter and wake one waiter."""
        self._value += 1
        for waiter in self._waiters:
            if not waiter.done():
                self._value -= 1

                # If the waiter is a coroutine paused at
                #
                #     with (yield semaphore.acquire()):
                #
                # then the context manager's __exit__ calls release() at the end
                # of the "with" block.
                waiter.set_result(_ReleasingContextManager(self))
                break

    def acquire(self, timeout=None):
        """Decrement the counter. Returns a Future.

        Block if the counter is zero and wait for a `.release`. The Future
        raises `.TimeoutError` after the deadline.
        """
        if self._value > 0:
            self._value -= 1
            future = Future()
            future.set_result(_ReleasingContextManager(self))
        else:
            waiter = Future()
            self._waiters.append(waiter)
            if timeout:
                future = gen.with_timeout(timeout, waiter,
                                          quiet_exceptions=gen.TimeoutError)

                # Set waiter's exception after the deadline.
                gen.chain_future(future, waiter)
            else:
                future = waiter
        return future

    def __enter__(self):
        raise RuntimeError(
            "Use Semaphore like 'with (yield semaphore.acquire())', not like"
            " 'with semaphore'")

    __exit__ = __enter__


class BoundedSemaphore(Semaphore):
    """A semaphore that prevents release() being called too many times.

    If `.release` would increment the semaphore's value past the initial
    value, it raises `ValueError`. Semaphores are mostly used to guard
    resources with limited capacity, so a semaphore released too many times
    is a sign of a bug.
    """
    def __init__(self, value=1):
        super(BoundedSemaphore, self).__init__(value=value)
        self._initial_value = value

    def release(self):
        """Increment the counter and wake one waiter."""
        if self._value >= self._initial_value:
            raise ValueError("Semaphore released too many times")
        super(BoundedSemaphore, self).release()


class Lock(object):
    """A lock for coroutines.

    A Lock begins unlocked, and `acquire` locks it immediately. While it is
    locked, a coroutine that yields `acquire` waits until another coroutine
    calls `release`.

    Releasing an unlocked lock raises `RuntimeError`.

    `acquire` supports the context manager protocol:

    >>> from tornado import gen, locks
    >>> lock = locks.Lock()
    >>>
    >>> @gen.coroutine
    ... def f():
    ...    with (yield lock.acquire()):
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.
    """
    def __init__(self):
        self._block = BoundedSemaphore(value=1)

    def __repr__(self):
        return "<%s _block=%s>" % (
            self.__class__.__name__,
            self._block)

    def acquire(self, deadline=None):
        """Attempt to lock. Returns a Future.

        Returns a Future, which raises `tornado.gen.TimeoutError` after a
        timeout.
        """
        return self._block.acquire(deadline)

    def release(self):
        """Unlock.

        The first coroutine in line waiting for `acquire` gets the lock.

        If not locked, raise a `RuntimeError`.
        """
        try:
            self._block.release()
        except ValueError:
            raise RuntimeError('release unlocked lock')

    def __enter__(self):
        raise RuntimeError(
            "Use Lock like 'with (yield lock)', not like 'with lock'")

    __exit__ = __enter__

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user