)]}'
{"heat/engine/service.py":[{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"c85b99b1f1f3668572afe4444af5d7526eaf0ed4","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        resources.initialise()"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        self.listener \u003d EngineListener(host, stack_lock.engine_id)"},{"line_number":95,"context_line":"        logger.debug(\"Starting listener for engine %s\" % stack_lock.engine_id)"},{"line_number":96,"context_line":"        self.listener.start()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _start_in_thread(self, stack_id, func, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2BqtI%3D","line":95,"updated":"2013-11-21 19:51:20.000000000","message":"wrap message in _(\u0027\u0027)","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"c7064bd523f6c9157fef86212b85b42c97adc97e","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        resources.initialise()"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        self.listener \u003d EngineListener(host, stack_lock.engine_id)"},{"line_number":95,"context_line":"        logger.debug(\"Starting listener for engine %s\" % stack_lock.engine_id)"},{"line_number":96,"context_line":"        self.listener.start()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _start_in_thread(self, stack_id, func, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2BqkE%3D","line":95,"in_reply_to":"AAAATn%2F%2BqtI%3D","updated":"2013-11-21 21:11:47.000000000","message":"Done","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"}],"heat/engine/stack_lock.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"adebbe13d7a551d799fd5248cd93b9994730ac92","unresolved":false,"context_lines":[{"line_number":65,"context_line":""},{"line_number":66,"context_line":"                logger.info(\"Engine %s successfully stole the lock\" % engine_id)"},{"line_number":67,"context_line":"        else:"},{"line_number":68,"context_line":"            rows_affected \u003d db_api.stack_lock_create(self.stack.id, engine_id)"},{"line_number":69,"context_line":"            if rows_affected \u003d\u003d 0:"},{"line_number":70,"context_line":"                raise exception.Error(\"Engine %s failed to create lock\""},{"line_number":71,"context_line":"                                      % engine_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2B6Cs%3D","line":68,"updated":"2013-11-18 18:22:22.000000000","message":"This is still wrong - if you end up with a race then one engine will report an error when it should just report ActionInProgress. The lock needs to be acquired, atomically, at the point where you\u0027re calling stack_lock_get().","commit_id":"c3e2596345a9286bef04d1b23a6c47d8983ed6f2"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"71e625b84c86160b890402e743db37ae46cc9be7","unresolved":false,"context_lines":[{"line_number":65,"context_line":""},{"line_number":66,"context_line":"                logger.info(\"Engine %s successfully stole the lock\" % engine_id)"},{"line_number":67,"context_line":"        else:"},{"line_number":68,"context_line":"            rows_affected \u003d db_api.stack_lock_create(self.stack.id, engine_id)"},{"line_number":69,"context_line":"            if rows_affected \u003d\u003d 0:"},{"line_number":70,"context_line":"                raise exception.Error(\"Engine %s failed to create lock\""},{"line_number":71,"context_line":"                                      % engine_id)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2B5C4%3D","line":68,"in_reply_to":"AAAATn%2F%2B6Cs%3D","updated":"2013-11-18 22:21:30.000000000","message":"Done","commit_id":"c3e2596345a9286bef04d1b23a6c47d8983ed6f2"},{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"c85b99b1f1f3668572afe4444af5d7526eaf0ed4","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        lock_engine_id \u003d db_api.stack_lock_create(self.stack.id, engine_id)"},{"line_number":49,"context_line":"        if lock_engine_id is None:"},{"line_number":50,"context_line":"            logger.debug(\"Engine %s acquired lock on stack %s (%s)\""},{"line_number":51,"context_line":"                         % (engine_id, self.stack.id, self.stack.action))"},{"line_number":52,"context_line":"            return"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if lock_engine_id \u003d\u003d engine_id or self._engine_alive(lock_engine_id):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2Bq0U%3D","line":51,"updated":"2013-11-21 19:51:20.000000000","message":"Include debug/info/error messages in _()\n(recently all the existing messages were changed to wrap in _(\u0027\u0027) for  translation/localization)","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"c7064bd523f6c9157fef86212b85b42c97adc97e","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        lock_engine_id \u003d db_api.stack_lock_create(self.stack.id, engine_id)"},{"line_number":49,"context_line":"        if lock_engine_id is None:"},{"line_number":50,"context_line":"            logger.debug(\"Engine %s acquired lock on stack %s (%s)\""},{"line_number":51,"context_line":"                         % (engine_id, self.stack.id, self.stack.action))"},{"line_number":52,"context_line":"            return"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if lock_engine_id \u003d\u003d engine_id or self._engine_alive(lock_engine_id):"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2BqjY%3D","line":51,"in_reply_to":"AAAATn%2F%2Bq0U%3D","updated":"2013-11-21 21:11:47.000000000","message":"Done","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"},{"author":{"_account_id":7230,"name":"Vijendar Komalla","email":"vijendar.komalla@rackspace.com","username":"vijendar"},"change_message_id":"c85b99b1f1f3668572afe4444af5d7526eaf0ed4","unresolved":false,"context_lines":[{"line_number":60,"context_line":"                        \"to steal the lock\" % engine_id)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"            rows_affected \u003d db_api.stack_lock_steal(self.stack.id,"},{"line_number":63,"context_line":"                                                    lock_engine_id, engine_id)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"            # Either the old_engine_id didn\u0027t match (lost race) or"},{"line_number":66,"context_line":"            # the lock was *just* released."}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2Bqto%3D","line":63,"updated":"2013-11-21 19:51:20.000000000","message":"instead of returning rows_affected, return engine_id from stack_lock_steal. could you please take look at below logic, see if it makes sense or not!\n\nret_engine_id \u003d db_api.stack_lock_steal(self.stack.id, locked_engine_id, current_engine_id)\nif ret_engine_id \u003d\u003d current_engine_id:\n    # stolen the lock successfully\nelif ret_engine_id is None:\n    # locked_engine_id just released the lock\n    # should we try one more time to acquire the lock??\nelse:\n    # lost the race and some else stolen the lock\n    # raise ActionInProgress exception","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"c7064bd523f6c9157fef86212b85b42c97adc97e","unresolved":false,"context_lines":[{"line_number":60,"context_line":"                        \"to steal the lock\" % engine_id)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"            rows_affected \u003d db_api.stack_lock_steal(self.stack.id,"},{"line_number":63,"context_line":"                                                    lock_engine_id, engine_id)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"            # Either the old_engine_id didn\u0027t match (lost race) or"},{"line_number":66,"context_line":"            # the lock was *just* released."}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F%2Bqag%3D","line":63,"in_reply_to":"AAAATn%2F%2Bqto%3D","updated":"2013-11-21 21:11:47.000000000","message":"Good suggestion, thanks.","commit_id":"003bf3170fcd9478af987f6248145e5df5e60d7a"},{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"e135bd23ef9549cb77e52a5d479b1e8cc02d0a38","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def release(self):"},{"line_number":93,"context_line":"        \"\"\"Release a stack lock.\"\"\""},{"line_number":94,"context_line":"        # Only the engine that owns the lock will be releasing it."},{"line_number":95,"context_line":"        # This ensures the lock being released is"},{"line_number":96,"context_line":"        rows_affected \u003d db_api.stack_lock_release(self.stack.id, engine_id)"},{"line_number":97,"context_line":"        if rows_affected \u003d\u003d 0:"},{"line_number":98,"context_line":"            logger.debug(_(\"Lock was already released on stack %s\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BNm0%3D","line":95,"updated":"2013-11-29 08:32:24.000000000","message":"unfinished sentence?","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"31839f619664ef228f489b54921efcc8bb9e0684","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def release(self):"},{"line_number":93,"context_line":"        \"\"\"Release a stack lock.\"\"\""},{"line_number":94,"context_line":"        # Only the engine that owns the lock will be releasing it."},{"line_number":95,"context_line":"        # This ensures the lock being released is"},{"line_number":96,"context_line":"        rows_affected \u003d db_api.stack_lock_release(self.stack.id, engine_id)"},{"line_number":97,"context_line":"        if rows_affected \u003d\u003d 0:"},{"line_number":98,"context_line":"            logger.debug(_(\"Lock was already released on stack %s\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2FaY%3D","line":95,"in_reply_to":"AAAATn%2F%2BNm0%3D","updated":"2013-12-03 18:57:29.000000000","message":"Done","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"abc81c9efe22ad5b7c936233c3bb099dc383a64e","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        # This ensures the lock being released is"},{"line_number":96,"context_line":"        rows_affected \u003d db_api.stack_lock_release(self.stack.id, engine_id)"},{"line_number":97,"context_line":"        if rows_affected \u003d\u003d 0:"},{"line_number":98,"context_line":"            logger.debug(_(\"Lock was already released on stack %s\")"},{"line_number":99,"context_line":"                         % self.stack.id)"},{"line_number":100,"context_line":"        else:"},{"line_number":101,"context_line":"            logger.debug(_(\"Engine %(engine)s released lock on stack \""}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BPYM%3D","line":98,"updated":"2013-11-28 14:12:21.000000000","message":"I\u0027d log this at least at warning, and probably error level.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"31839f619664ef228f489b54921efcc8bb9e0684","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        # This ensures the lock being released is"},{"line_number":96,"context_line":"        rows_affected \u003d db_api.stack_lock_release(self.stack.id, engine_id)"},{"line_number":97,"context_line":"        if rows_affected \u003d\u003d 0:"},{"line_number":98,"context_line":"            logger.debug(_(\"Lock was already released on stack %s\")"},{"line_number":99,"context_line":"                         % self.stack.id)"},{"line_number":100,"context_line":"        else:"},{"line_number":101,"context_line":"            logger.debug(_(\"Engine %(engine)s released lock on stack \""}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2FiU%3D","line":98,"in_reply_to":"AAAATn%2F%2BPYM%3D","updated":"2013-12-03 18:57:29.000000000","message":"Done","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"abc81c9efe22ad5b7c936233c3bb099dc383a64e","unresolved":false,"context_lines":[{"line_number":102,"context_line":"                           \"%(stack)s\") % {\u0027engine\u0027: engine_id,"},{"line_number":103,"context_line":"                                           \u0027stack\u0027: self.stack.id})"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def _gt_callback_release(self, gt, *args, **kwargs):"},{"line_number":106,"context_line":"        \"\"\"Callback function that will be passed to GreenThread.link().\"\"\""},{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BPMI%3D","line":105,"updated":"2013-11-28 14:12:21.000000000","message":"This is used as a public API, so I\u0027m surprised it has a name starting with an underscore.\n\nAlso, the purpose of this function appears to be related to greenthreads, not to locks, so I don\u0027t think it even belong here. It can easily be incorporated in the caller:\n\n    def _start_thread_with_lock(self, cnxt, stack, func, *args):\n        lock \u003d stack_lock.StackLock(cnxt, stack)\n        lock.acquire()\n        def release(gt):\n            try:\n                gt.wait()\n            finally:\n                lock.release()\n        th \u003d self._start_in_thread(stack.id, func, *args)\n        th.link(release)","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"31839f619664ef228f489b54921efcc8bb9e0684","unresolved":false,"context_lines":[{"line_number":102,"context_line":"                           \"%(stack)s\") % {\u0027engine\u0027: engine_id,"},{"line_number":103,"context_line":"                                           \u0027stack\u0027: self.stack.id})"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def _gt_callback_release(self, gt, *args, **kwargs):"},{"line_number":106,"context_line":"        \"\"\"Callback function that will be passed to GreenThread.link().\"\"\""},{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2FYQ%3D","line":105,"in_reply_to":"AAAATn%2F%2BPMI%3D","updated":"2013-12-03 18:57:29.000000000","message":"Nice suggestion, thanks.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"e135bd23ef9549cb77e52a5d479b1e8cc02d0a38","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BM%2Fg%3D","line":110,"updated":"2013-11-29 08:32:24.000000000","message":"Sorry, I still don\u0027t quite understand this, and I am a little curious about what I have missed here. \n\nFrom the _start_thread_with_lock method, a greenthread will be created only if lock.acquire() succeeds without raising ActionInProgress exception. So how can there be a pending _gt_callback_release() left? Also by looking at the greenthread module, \n\n    def link(self, func, *curried_args, **curried_kwargs):\n        self._exit_funcs \u003d getattr(self, \u0027_exit_funcs\u0027, deque())\n        self._exit_funcs.append((func, curried_args, curried_kwargs))\n        if self._exit_event.ready():\n            self._resolve_links()\n        \n    def main(self, function, args, kwargs):\n        try:\n            result \u003d function(*args, **kwargs)\n        except:\n            self._exit_event.send_exception(*sys.exc_info())\n            self._resolve_links()\n            raise\n        else:\n            self._exit_event.send(result)\n            self._resolve_links()\n    \n    def _resolve_links(self):\n        # ca and ckw are the curried function arguments\n        if self._resolving_links:\n            return\n        self._resolving_links \u003d True\n        try:\n            exit_funcs \u003d getattr(self, \u0027_exit_funcs\u0027, deque())\n            while exit_funcs:\n                f, ca, ckw \u003d exit_funcs.popleft()\n                f(self, *ca, **ckw)\n        finally:\n            self._resolving_links \u003d False\n\nThe exit_funcs would not be called before the functions (to be run in the greenthread) finishes execution.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"31839f619664ef228f489b54921efcc8bb9e0684","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2FBo%3D","line":110,"in_reply_to":"AAAATn%2F%2BHUY%3D","updated":"2013-12-03 18:57:29.000000000","message":"I was also confused about why that was necessary.  And now I\u0027m even more confused as to why I can\u0027t reproduce the problem I described in the comment above.  I\u0027ll remove the call to wait().","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"87599b372b344755e927f15b02dae5ee508a4374","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BHUY%3D","line":110,"in_reply_to":"AAAATn%2F%2BM%2Fg%3D","updated":"2013-12-02 13:20:24.000000000","message":"I was confused about that too. The documentation appears to recommend it:\n\nhttp://eventlet.net/doc/modules/greenthread.html#eventlet.greenthread.GreenThread.link\n\nbut now I realise that what it means is that you don\u0027t get passed the result of the function running in the green thread, so if you want to know it you can get it from calling wait().\n\nWe\u0027re not actually using it here, unless it throws an exception in which case we do the Wrong Thing, so we should actually just get rid of this function.\n\nIt\u0027s very clear from the eventlet code that wait() just waits for an event that has necessarily already happened by the time _resolve_links() is called, and therefore will return immediately.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"babefa43c2027b67e1da6c83279cddd3563bcb4c","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2BH0%3D","line":110,"in_reply_to":"AAAATn%2F%2BM%2Fg%3D","updated":"2013-12-03 21:54:45.000000000","message":"Liang, regarding your question \"how can there be a pending _gt_callback_release() left?\", the pending _gt_callback_release() is from the active lock (an in-progress stack-create on another engine for example).","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"babefa43c2027b67e1da6c83279cddd3563bcb4c","unresolved":false,"context_lines":[{"line_number":107,"context_line":"        # If gt.wait() isn\u0027t called here and a lock exists, then the"},{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2BIc%3D","line":110,"in_reply_to":"AAAATn%2F9%2FBo%3D","updated":"2013-12-03 21:54:45.000000000","message":"Nevermind, it still happens.  This was during a stack-delete on a stack that was create, in-progress  http://dunsmor.com/shots/2013-12-03-150001_565x967.png\n\nI\u0027m going to have to add the call to gt.wait() back.  I will continue looking at the greenthread code to try to understand this.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"abc81c9efe22ad5b7c936233c3bb099dc383a64e","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F%2BPEI%3D","line":111,"updated":"2013-11-28 14:12:21.000000000","message":"This throws an exception if the code in the thread exited with an exception (including if it was killed or cancelled), which would cause the lock to not be released in that case. Use try/finally as above.","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"31839f619664ef228f489b54921efcc8bb9e0684","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        # pending _gt_callback_release() from the previous acquire()"},{"line_number":109,"context_line":"        # will be executed immediately upon the next call to"},{"line_number":110,"context_line":"        # acquire().  This leads to a pre-mature release of the lock."},{"line_number":111,"context_line":"        gt.wait()"},{"line_number":112,"context_line":"        self.release()"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATn%2F9%2FYw%3D","line":111,"in_reply_to":"AAAATn%2F%2BPEI%3D","updated":"2013-12-03 18:57:29.000000000","message":"Done","commit_id":"2043e50e1eab0e8681e2fa000acd0f324c604b6b"},{"author":{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},"change_message_id":"943f7939978131889ffb3a45d9f39fd10cdf0ba3","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from heat.openstack.common.rpc.common import Timeout"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":"engine_id \u003d uuidutils.generate_uuid()"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class StackLock(object):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATn%2F9gEg%3D","line":28,"updated":"2013-12-10 21:43:41.000000000","message":"This has just been removed from oslo, use str(uuid.uuid4())","commit_id":"ebe83ea362dfaece5b08998f68f93449db7b0039"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"51c2f2f152d1ef242447a1d6e5fe1ae84978426c","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from heat.openstack.common.rpc.common import Timeout"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":"engine_id \u003d uuidutils.generate_uuid()"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class StackLock(object):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATn%2F9f7U%3D","line":28,"in_reply_to":"AAAATn%2F9gEg%3D","updated":"2013-12-10 22:04:24.000000000","message":"Done","commit_id":"ebe83ea362dfaece5b08998f68f93449db7b0039"}]}
