prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Upcoming Tornado change breaks gunicorn.workers.gtornado
  The next release of Tornado (will be 4.0 when released, although the current master branch hasn't been updated to change all mentions of 3.3 to 4.0) makes some major changes to the HTTP internals and breaks gunicorn's monkey-patching of HTTPConnection.finish.  Fortunately, there is now a cleaner way to do the tracking that gunicorn wants to do here, since the interface between HTTPServer and Application is more formally defined by the HTTPServerConnectionDelegate and HTTPMessageDelegate interfaces, so you should be able to wrap the Application (which implements/subclasses HTTPServerConnectionDelegate) and the HTTPMessageDelegate its start_request method returns.  
  
  
  </issue>
  <code>
  [start of gunicorn/workers/gtornado.py]
  1 # -*- coding: utf-8 -
  2 #
  3 # This file is part of gunicorn released under the MIT license.
  4 # See the NOTICE for more information.
  5 
  6 import os
  7 import sys
  8 
  9 try:
  10     import tornado.web
  11 except ImportError:
  12     raise RuntimeError("You need tornado installed to use this worker.")
  13 import tornado.httpserver
  14 from tornado.ioloop import IOLoop, PeriodicCallback
  15 from tornado.wsgi import WSGIContainer
  16 from gunicorn.workers.base import Worker
  17 from gunicorn import __version__ as gversion
  18 
  19 
  20 class TornadoWorker(Worker):
  21 
  22     @classmethod
  23     def setup(cls):
  24         web = sys.modules.pop("tornado.web")
  25         old_clear = web.RequestHandler.clear
  26 
  27         def clear(self):
  28             old_clear(self)
  29             self._headers["Server"] += " (Gunicorn/%s)" % gversion
  30         web.RequestHandler.clear = clear
  31         sys.modules["tornado.web"] = web
  32 
  33     def handle_exit(self, sig, frame):
  34         if self.alive:
  35             super(TornadoWorker, self).handle_exit(sig, frame)
  36             self.stop()
  37 
  38     def handle_request(self):
  39         self.nr += 1
  40         if self.alive and self.nr >= self.max_requests:
  41             self.alive = False
  42             self.log.info("Autorestarting worker after current request.")
  43             self.stop()
  44 
  45     def watchdog(self):
  46         if self.alive:
  47             self.notify()
  48 
  49         if self.ppid != os.getppid():
  50             self.log.info("Parent changed, shutting down: %s", self)
  51             self.stop()
  52 
  53     def run(self):
  54         self.ioloop = IOLoop.instance()
  55         self.alive = True
  56         PeriodicCallback(self.watchdog, 1000, io_loop=self.ioloop).start()
  57 
  58         # Assume the app is a WSGI callable if its not an
  59         # instance of tornado.web.Application or is an
  60         # instance of tornado.wsgi.WSGIApplication
  61         app = self.wsgi
  62         if not isinstance(app, tornado.web.Application) or \
  63            isinstance(app, tornado.wsgi.WSGIApplication):
  64             app = WSGIContainer(app)
  65 
  66         # Monkey-patching HTTPConnection.finish to count the
  67         # number of requests being handled by Tornado. This
  68         # will help gunicorn shutdown the worker if max_requests
  69         # is exceeded.
  70         httpserver = sys.modules["tornado.httpserver"]
  71         old_connection_finish = httpserver.HTTPConnection.finish
  72 
  73         def finish(other):
  74             self.handle_request()
  75             old_connection_finish(other)
  76         httpserver.HTTPConnection.finish = finish
  77         sys.modules["tornado.httpserver"] = httpserver
  78 
  79         if self.cfg.is_ssl:
  80             server = tornado.httpserver.HTTPServer(app, io_loop=self.ioloop,
  81                     ssl_options=self.cfg.ssl_options)
  82         else:
  83             server = tornado.httpserver.HTTPServer(app,
  84                     io_loop=self.ioloop)
  85 
  86         self.server = server
  87 
  88         for s in self.sockets:
  89             s.setblocking(0)
  90             if hasattr(server, "add_socket"):  # tornado > 2.0
  91                 server.add_socket(s)
  92             elif hasattr(server, "_sockets"):  # tornado 2.0
  93                 server._sockets[s.fileno()] = s
  94 
  95         server.no_keep_alive = self.cfg.keepalive <= 0
  96         server.start(num_processes=1)
  97 
  98         self.ioloop.start()
  99 
  100     def stop(self):
  101         if hasattr(self, 'server'):
  102             try:
  103                 self.server.stop()
  104             except Exception:
  105                 pass
  106         PeriodicCallback(self.stop_ioloop, 1000, io_loop=self.ioloop).start()
  107 
  108     def stop_ioloop(self):
  109         if not self.ioloop._callbacks and len(self.ioloop._timeouts) <= 1:
  110             self.ioloop.stop()
  111
  [end of gunicorn/workers/gtornado.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/gunicorn/workers/gtornado.py b/gunicorn/workers/gtornado.py
  --- a/gunicorn/workers/gtornado.py
  +++ b/gunicorn/workers/gtornado.py
  @@ -68,20 +68,31 @@
           # will help gunicorn shutdown the worker if max_requests
           # is exceeded.
           httpserver = sys.modules["tornado.httpserver"]
  -        old_connection_finish = httpserver.HTTPConnection.finish
  +        if hasattr(httpserver, 'HTTPConnection'):
  +            old_connection_finish = httpserver.HTTPConnection.finish
   
  -        def finish(other):
  -            self.handle_request()
  -            old_connection_finish(other)
  -        httpserver.HTTPConnection.finish = finish
  -        sys.modules["tornado.httpserver"] = httpserver
  +            def finish(other):
  +                self.handle_request()
  +                old_connection_finish(other)
  +            httpserver.HTTPConnection.finish = finish
  +            sys.modules["tornado.httpserver"] = httpserver
  +
  +            server_class = tornado.httpserver.HTTPServer
  +        else:
  +
  +            class _HTTPServer(tornado.httpserver.HTTPServer):
  +
  +                def on_close(instance, server_conn):
  +                    self.handle_request()
  +                    super(_HTTPServer, instance).on_close(server_conn)
  +
  +            server_class = _HTTPServer
   
           if self.cfg.is_ssl:
  -            server = tornado.httpserver.HTTPServer(app, io_loop=self.ioloop,
  +            server = server_class(app, io_loop=self.ioloop,
                       ssl_options=self.cfg.ssl_options)
           else:
  -            server = tornado.httpserver.HTTPServer(app,
  -                    io_loop=self.ioloop)
  +            server = server_class(app, io_loop=self.ioloop)
   
           self.server = server
  
verification_info: {"golden_diff": "diff --git a/gunicorn/workers/gtornado.py b/gunicorn/workers/gtornado.py\n--- a/gunicorn/workers/gtornado.py\n+++ b/gunicorn/workers/gtornado.py\n@@ -68,20 +68,31 @@\n         # will help gunicorn shutdown the worker if max_requests\n         # is exceeded.\n         httpserver = sys.modules[\"tornado.httpserver\"]\n-        old_connection_finish = httpserver.HTTPConnection.finish\n+        if hasattr(httpserver, 'HTTPConnection'):\n+            old_connection_finish = httpserver.HTTPConnection.finish\n \n-        def finish(other):\n-            self.handle_request()\n-            old_connection_finish(other)\n-        httpserver.HTTPConnection.finish = finish\n-        sys.modules[\"tornado.httpserver\"] = httpserver\n+            def finish(other):\n+                self.handle_request()\n+                old_connection_finish(other)\n+            httpserver.HTTPConnection.finish = finish\n+            sys.modules[\"tornado.httpserver\"] = httpserver\n+\n+            server_class = tornado.httpserver.HTTPServer\n+        else:\n+\n+            class _HTTPServer(tornado.httpserver.HTTPServer):\n+\n+                def on_close(instance, server_conn):\n+                    self.handle_request()\n+                    super(_HTTPServer, instance).on_close(server_conn)\n+\n+            server_class = _HTTPServer\n \n         if self.cfg.is_ssl:\n-            server = tornado.httpserver.HTTPServer(app, io_loop=self.ioloop,\n+            server = server_class(app, io_loop=self.ioloop,\n                     ssl_options=self.cfg.ssl_options)\n         else:\n-            server = tornado.httpserver.HTTPServer(app,\n-                    io_loop=self.ioloop)\n+            server = server_class(app, io_loop=self.ioloop)\n \n         self.server = server\n", "issue": "Upcoming Tornado change breaks gunicorn.workers.gtornado\nThe next release of Tornado (will be 4.0 when released, although the current master branch hasn't been updated to change all mentions of 3.3 to 4.0) makes some major changes to the HTTP internals and breaks gunicorn's monkey-patching of HTTPConnection.finish.  Fortunately, there is now a cleaner way to do the tracking that gunicorn wants to do here, since the interface between HTTPServer and Application is more formally defined by the HTTPServerConnectionDelegate and HTTPMessageDelegate interfaces, so you should be able to wrap the Application (which implements/subclasses HTTPServerConnectionDelegate) and the HTTPMessageDelegate its start_request method returns.  \n\n", "before_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport os\nimport sys\n\ntry:\n    import tornado.web\nexcept ImportError:\n    raise RuntimeError(\"You need tornado installed to use this worker.\")\nimport tornado.httpserver\nfrom tornado.ioloop import IOLoop, PeriodicCallback\nfrom tornado.wsgi import WSGIContainer\nfrom gunicorn.workers.base import Worker\nfrom gunicorn import __version__ as gversion\n\n\nclass TornadoWorker(Worker):\n\n    @classmethod\n    def setup(cls):\n        web = sys.modules.pop(\"tornado.web\")\n        old_clear = web.RequestHandler.clear\n\n        def clear(self):\n            old_clear(self)\n            self._headers[\"Server\"] += \" (Gunicorn/%s)\" % gversion\n        web.RequestHandler.clear = clear\n        sys.modules[\"tornado.web\"] = web\n\n    def handle_exit(self, sig, frame):\n        if self.alive:\n            super(TornadoWorker, self).handle_exit(sig, frame)\n            self.stop()\n\n    def handle_request(self):\n        self.nr += 1\n        if self.alive and self.nr >= self.max_requests:\n            self.alive = False\n            self.log.info(\"Autorestarting worker after current request.\")\n            self.stop()\n\n    def watchdog(self):\n        if self.alive:\n            self.notify()\n\n        if self.ppid != os.getppid():\n            self.log.info(\"Parent changed, shutting down: %s\", self)\n            self.stop()\n\n    def run(self):\n        self.ioloop = IOLoop.instance()\n        self.alive = True\n        PeriodicCallback(self.watchdog, 1000, io_loop=self.ioloop).start()\n\n        # Assume the app is a WSGI callable if its not an\n        # instance of tornado.web.Application or is an\n        # instance of tornado.wsgi.WSGIApplication\n        app = self.wsgi\n        if not isinstance(app, tornado.web.Application) or \\\n           isinstance(app, tornado.wsgi.WSGIApplication):\n            app = WSGIContainer(app)\n\n        # Monkey-patching HTTPConnection.finish to count the\n        # number of requests being handled by Tornado. This\n        # will help gunicorn shutdown the worker if max_requests\n        # is exceeded.\n        httpserver = sys.modules[\"tornado.httpserver\"]\n        old_connection_finish = httpserver.HTTPConnection.finish\n\n        def finish(other):\n            self.handle_request()\n            old_connection_finish(other)\n        httpserver.HTTPConnection.finish = finish\n        sys.modules[\"tornado.httpserver\"] = httpserver\n\n        if self.cfg.is_ssl:\n            server = tornado.httpserver.HTTPServer(app, io_loop=self.ioloop,\n                    ssl_options=self.cfg.ssl_options)\n        else:\n            server = tornado.httpserver.HTTPServer(app,\n                    io_loop=self.ioloop)\n\n        self.server = server\n\n        for s in self.sockets:\n            s.setblocking(0)\n            if hasattr(server, \"add_socket\"):  # tornado > 2.0\n                server.add_socket(s)\n            elif hasattr(server, \"_sockets\"):  # tornado 2.0\n                server._sockets[s.fileno()] = s\n\n        server.no_keep_alive = self.cfg.keepalive <= 0\n        server.start(num_processes=1)\n\n        self.ioloop.start()\n\n    def stop(self):\n        if hasattr(self, 'server'):\n            try:\n                self.server.stop()\n            except Exception:\n                pass\n        PeriodicCallback(self.stop_ioloop, 1000, io_loop=self.ioloop).start()\n\n    def stop_ioloop(self):\n        if not self.ioloop._callbacks and len(self.ioloop._timeouts) <= 1:\n            self.ioloop.stop()\n", "path": "gunicorn/workers/gtornado.py"}]}