changeset 106:6b45dd9d05ed

Fairly complete atexit handler: modelled after the CPython plugin, but implemented in pypy_setup.py. Handle: + uwsgi.atexit + atexit module exit handlers + "skip-atexit-teardown" + worker and master differences when hijacked, busy and async
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 05 Aug 2020 09:49:03 +0200
parents 2bbb4ab01566
children 8e3d9d28af27
files uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py
diffstat 1 files changed, 48 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py	Wed Aug 05 09:47:14 2020 +0200
+++ b/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py	Wed Aug 05 09:49:03 2020 +0200
@@ -1,5 +1,5 @@
 --- plugins/pypy/pypy_setup.py.orig	2020-07-09 07:54:09.000000000 +0200
-+++ plugins/pypy/pypy_setup.py	2020-08-04 09:43:23.798868000 +0200
++++ plugins/pypy/pypy_setup.py	2020-08-05 02:24:53.865927000 +0200
 @@ -31,8 +31,15 @@
  extern void (*uwsgi_pypy_hook_pythonpath)(char *);
  extern void (*uwsgi_pypy_hook_request)(struct wsgi_request *);
@@ -41,7 +41,23 @@
  # uwsgi definitions
  cdefines = '''
  %s
-@@ -168,7 +181,7 @@
+@@ -110,6 +123,8 @@
+         uint64_t running_time;
+         uint64_t avg_response_time;
+         uint64_t tx;
++
++        int hijacked;
+         ...;
+ };
+ 
+@@ -164,11 +179,14 @@
+         struct wsgi_request *wsgi_req;
+ 
+         struct uwsgi_plugin *p[];
++
++        int skip_atexit_teardown;
++
+         ...;
  };
  struct uwsgi_server uwsgi;
  
@@ -50,7 +66,7 @@
  
  const char *uwsgi_pypy_version;
  
-@@ -269,7 +282,7 @@
+@@ -269,7 +287,7 @@
  %s
  
  extern struct uwsgi_server uwsgi;
@@ -59,7 +75,7 @@
  %s
  ''' % ('\n'.join(uwsgi_defines), uwsgi_dot_h, hooks)
  
-@@ -286,7 +299,7 @@
+@@ -286,7 +304,7 @@
  
  # fix argv if needed
  if len(sys.argv) == 0:
@@ -68,7 +84,7 @@
  
  
  @ffi.callback("void(char *)")
-@@ -305,7 +318,7 @@
+@@ -305,7 +323,7 @@
      load a wsgi module
      """
      global wsgi_application
@@ -77,7 +93,7 @@
      c = 'application'
      if ':' in m:
          m, c = m.split(':')
-@@ -322,7 +335,7 @@
+@@ -322,7 +340,7 @@
      load a mod_wsgi compliant .wsgi file
      """
      global wsgi_application
@@ -86,7 +102,7 @@
      c = 'application'
      mod = imp.load_source('uwsgi_file_wsgi', w)
      wsgi_application = getattr(mod, c)
-@@ -334,7 +347,7 @@
+@@ -334,7 +352,7 @@
      load a .ini paste app
      """
      global wsgi_application
@@ -95,7 +111,7 @@
      if c.startswith('config:'):
          c = c[7:]
      if c[0] != '/':
-@@ -358,12 +371,28 @@
+@@ -358,12 +376,47 @@
          uwsgi.post_fork_hook()
  
  
@@ -103,16 +119,35 @@
 +def uwsgi_pypy_atexit():
 +    """
 +    .atexit handler implementation
++
++    Modelled after python_plugin.c
 +    """
++    mywid = lib.uwsgi.mywid
++    if mywid > 0:
++        # if hijacked do not run atexit hooks
++        if lib.uwsgi.workers[mywid].hijacked:
++            return
++        # if busy do not run atexit hooks
++        if lib.uwsgi_worker_is_busy(mywid):
++            return
++        # managing atexit in async mode is a real pain...skip it for now
++        if lib.uwsgi.async > 0:
++            return
++
 +    import uwsgi
 +    uahandler = getattr(uwsgi, "atexit", None)
 +    if callable(uahandler):
 +        uahandler()
 +
++    if lib.uwsgi.skip_atexit_teardown:
++        return
++
 +    import atexit
 +    aefn = getattr(atexit, "_run_exitfuncs", None)
 +    if callable(aefn):
 +        aefn()
++    else:
++        print("!!! atexit._run_exitfuncs() not found !!!")
 +
 +
  @ffi.callback("void(char *)")
@@ -125,7 +160,7 @@
      sys.path.append(path)
      print("added %s to pythonpath" % path)
  
-@@ -470,15 +499,17 @@
+@@ -470,15 +523,17 @@
      def start_response(status, headers, exc_info=None):
          if exc_info:
              traceback.print_exception(*exc_info)
@@ -144,7 +179,7 @@
  
      environ['wsgi.version'] = (1, 0)
      scheme = 'http'
-@@ -523,6 +554,7 @@
+@@ -523,6 +578,7 @@
  lib.uwsgi_pypy_hook_pythonpath = uwsgi_pypy_pythonpath
  lib.uwsgi_pypy_hook_request = uwsgi_pypy_wsgi_handler
  lib.uwsgi_pypy_post_fork_hook = uwsgi_pypy_post_fork_hook
@@ -152,7 +187,7 @@
  
  """
  Here we define the "uwsgi" virtual module
-@@ -537,7 +569,7 @@
+@@ -537,7 +593,7 @@
  def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler):
      cb = ffi.callback('void(int)', handler)
      uwsgi_gc.append(cb)
@@ -161,7 +196,7 @@
          raise Exception("unable to register signal %d" % signum)
  uwsgi.register_signal = uwsgi_pypy_uwsgi_register_signal
  
-@@ -562,7 +594,7 @@
+@@ -562,7 +618,7 @@
      rpc_func = uwsgi_pypy_RPC(func)
      cb = ffi.callback("int(int, char*[], int[], char**)", rpc_func)
      uwsgi_gc.append(cb)
@@ -170,7 +205,7 @@
          raise Exception("unable to register rpc func %s" % name)
  uwsgi.register_rpc = uwsgi_pypy_uwsgi_register_rpc
  
-@@ -598,8 +630,8 @@
+@@ -598,8 +654,8 @@
  
  def uwsgi_pypy_call(func, *args):
      node = None