changeset 102:bcd6ce036b2a

Implement a first simple .atexit handler: call uwsgin.atexit and handle "atexit" registrations. BUGS: No threading BUGS: The flag to disable atexit handler is not yet supported.
author Franz Glasner <fzglas.hg@dom66.de>
date Tue, 04 Aug 2020 09:47:59 +0200
parents cc494d5ae895
children e44e80fd2810
files uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__plugin.c uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py
diffstat 2 files changed, 205 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__plugin.c	Sun Aug 02 22:04:17 2020 +0200
+++ b/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__plugin.c	Tue Aug 04 09:47:59 2020 +0200
@@ -1,7 +1,10 @@
 --- plugins/pypy/pypy_plugin.c.orig	2020-07-09 07:54:09.000000000 +0200
-+++ plugins/pypy/pypy_plugin.c
-@@ -44,7 +44,7 @@ void (*uwsgi_pypy_hook_request)(void *, int);
++++ plugins/pypy/pypy_plugin.c	2020-08-04 09:28:14.194761000 +0200
+@@ -42,9 +42,10 @@ void (*uwsgi_pypy_hook_paste_loader)(char *);
+ void (*uwsgi_pypy_hook_pythonpath)(char *);
+ void (*uwsgi_pypy_hook_request)(void *, int);
  void (*uwsgi_pypy_post_fork_hook)(void);
++void (*uwsgi_pypy_hook_atexit)(void);
  
  extern struct uwsgi_server uwsgi;
 -struct uwsgi_plugin pypy_plugin;
@@ -9,37 +12,43 @@
  
  static int uwsgi_pypy_init() {
  
-@@ -68,11 +68,11 @@ static int uwsgi_pypy_init() {
+@@ -68,26 +69,26 @@ static int uwsgi_pypy_init() {
  		if (upypy.home) {
  			// first try with /bin way:
  #ifdef __CYGWIN__
 -                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy-c.dll");
-+                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
++			char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
  #elif defined(__APPLE__)
 -                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy-c.dylib");
-+                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
++			char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
  #else
 -                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy-c.so");
-+                        char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
++			char *libpath = uwsgi_concat2(upypy.home, "/bin/libpypy3-c.so");
  #endif
  			if (uwsgi_file_exists(libpath)) {
-                                 upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
-@@ -83,11 +83,11 @@ static int uwsgi_pypy_init() {
+-                                upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
+-                        }
+-                        free(libpath);
++				upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
++			}
++			free(libpath);
+ 
+ 			// fallback to old-style way
  			if (!upypy.handler) {
  			
  #ifdef __CYGWIN__
 -                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dll");
-+                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.so");
++				char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.so");
  #elif defined(__APPLE__)
 -                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dylib");
-+                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.dylib");
++				char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.dylib");
  #else
 -                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.so");
-+                        	char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.so");
++				char *libpath = uwsgi_concat2(upypy.home, "/libpypy3-c.so");
  #endif
  				if (uwsgi_file_exists(libpath)) {
  					upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
-@@ -98,11 +98,11 @@ static int uwsgi_pypy_init() {
+@@ -98,11 +99,11 @@ static int uwsgi_pypy_init() {
  		// fallback to standard library search path
  		if (!upypy.handler) {
  #ifdef __CYGWIN__
@@ -54,7 +63,134 @@
  #endif
  		}
  	}
-@@ -372,8 +372,8 @@ static int uwsgi_pypy_mule(char *opt) {
+@@ -125,9 +126,9 @@ static int uwsgi_pypy_init() {
+ 	}
+ 
+ 	u_pypy_init_threads = dlsym(upypy.handler, "pypy_init_threads");
+-        if (!u_pypy_init_threads) {
+-                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_init_threads, multithreading will not work !!!\n");
+-        }
++	if (!u_pypy_init_threads) {
++		uwsgi_log("!!! WARNING your libpypy-c does not export pypy_init_threads, multithreading will not work !!!\n");
++	}
+ 	
+ 	u_rpython_startup_code();
+ 
+@@ -148,9 +149,9 @@ static int uwsgi_pypy_init() {
+ 				goto ready;
+ 			}
+ 		}
+-                uwsgi_log("unable to set pypy home to \"%s\"\n", upypy.home);
++		uwsgi_log("unable to set pypy home to \"%s\"\n", upypy.home);
+ 		exit(1);
+-        }
++	}
+ 
+ ready:
+ 	u_pypy_execute_source = dlsym(upypy.handler, "pypy_execute_source");
+@@ -160,9 +161,9 @@ ready:
+ 	}
+ 
+ 	u_pypy_thread_attach = dlsym(upypy.handler, "pypy_thread_attach");
+-        if (!u_pypy_thread_attach) {
+-                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_thread_attach, multithreading will not work !!!\n");
+-        }
++	if (!u_pypy_thread_attach) {
++		uwsgi_log("!!! WARNING your libpypy-c does not export pypy_thread_attach, multithreading will not work !!!\n");
++	}
+ 
+ 	if (upypy.setup) {
+ 		buffer = uwsgi_open_and_read(upypy.setup, &rlen, 1, NULL);
+@@ -233,14 +234,14 @@ static void uwsgi_pypy_preinit_apps() {
+ 
+ static int uwsgi_pypy_request(struct wsgi_request *wsgi_req) {
+ 	/* Standard WSGI request */
+-        if (!wsgi_req->len) {
+-                uwsgi_log( "Empty pypy request. skip.\n");
+-                return -1;
+-        }
++	if (!wsgi_req->len) {
++		uwsgi_log( "Empty pypy request. skip.\n");
++		return -1;
++	}
+ 
+-        if (uwsgi_parse_vars(wsgi_req)) {
+-                return -1;
+-        }
++	if (uwsgi_parse_vars(wsgi_req)) {
++		return -1;
++	}
+ 
+ 	if (uwsgi_pypy_hook_request) {
+ 		uwsgi_pypy_hook_request(wsgi_req, wsgi_req->async_id);
+@@ -266,16 +267,19 @@ static void uwsgi_pypy_init_apps() {
+ 	}
+ }
+ 
+-/*
++
+ static void uwsgi_pypy_atexit() {
+-	if (pypy_debug_file)
+-		fflush(pypy_debug_file);
++	if (!uwsgi_pypy_hook_atexit) {
++		uwsgi_log("!!! Your pypy setup does not define a uwsgi_pypy_atexit !!!\n");	       
++		return;
++	}	     
++	uwsgi_pypy_hook_atexit();
+ }
+-*/
+ 
++
+ static void uwsgi_opt_pypy_ini_paste(char *opt, char *value, void *foobar) {
+-        uwsgi_opt_load_ini(opt, value, NULL);
+-        upypy.paste = value;
++	uwsgi_opt_load_ini(opt, value, NULL);
++	upypy.paste = value;
+ }
+ 
+ 
+@@ -332,14 +336,14 @@ static void uwsgi_pypy_post_fork() {
+ 	pthread_mutex_init(&upypy.attach_thread_lock, NULL);
+ 	struct uwsgi_string_list *usl = NULL;
+ 	uwsgi_foreach(usl, upypy.eval_post_fork) {
+-                uwsgi_pypy_hook_execute_source(usl->value);
+-        }
++		uwsgi_pypy_hook_execute_source(usl->value);
++	}
+ 	uwsgi_foreach(usl, upypy.exec_post_fork) {
+-                size_t rlen = 0;
+-                char *buffer = uwsgi_open_and_read(usl->value, &rlen, 1, NULL);
+-                uwsgi_pypy_hook_execute_source(buffer);
+-                free(buffer);
+-        }
++		size_t rlen = 0;
++		char *buffer = uwsgi_open_and_read(usl->value, &rlen, 1, NULL);
++		uwsgi_pypy_hook_execute_source(buffer);
++		free(buffer);
++	}
+ 
+ 	if (uwsgi_pypy_post_fork_hook) {
+ 		uwsgi_pypy_post_fork_hook();
+@@ -360,20 +364,20 @@ static int uwsgi_pypy_mule(char *opt) {
+ 		exit(1);
+ 	}
+ 
+-        if (uwsgi_endswith(opt, ".py")) {
+-                size_t rlen = 0;
+-                char *buffer = uwsgi_open_and_read(opt, &rlen, 1, NULL);
+-                uwsgi_pypy_hook_execute_source(buffer);
++	if (uwsgi_endswith(opt, ".py")) {
++		size_t rlen = 0;
++		char *buffer = uwsgi_open_and_read(opt, &rlen, 1, NULL);
++		uwsgi_pypy_hook_execute_source(buffer);
+ 		free(buffer);
+-                return 1;
+-        }
+-        return 0;
++		return 1;
++	}
++	return 0;
+ 
  }
  
  
@@ -65,3 +201,10 @@
  	.modifier1 = 0,
  	.on_load = uwsgi_pypy_onload,
  	.init = uwsgi_pypy_init,
+@@ -388,4 +392,6 @@ struct uwsgi_plugin pypy_plugin = {
+ 	.rpc = uwsgi_pypy_rpc,
+ 	.post_fork = uwsgi_pypy_post_fork,
+ 	.mule = uwsgi_pypy_mule,
++
++	.atexit = uwsgi_pypy_atexit,
+ };
--- a/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py	Sun Aug 02 22:04:17 2020 +0200
+++ b/uwsginl-plugin-lang-pypy3/files/extra/patch-plugins_pypy_pypy__setup.py	Tue Aug 04 09:47:59 2020 +0200
@@ -1,7 +1,10 @@
---- plugins/pypy/pypy_setup.py.orig	2020-06-14 11:50:00.000000000 +0200
-+++ plugins/pypy/pypy_setup.py	2020-06-17 22:05:41.175101000 +0200
-@@ -33,6 +33,12 @@
+--- 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
+@@ -31,8 +31,15 @@
+ extern void (*uwsgi_pypy_hook_pythonpath)(char *);
+ extern void (*uwsgi_pypy_hook_request)(struct wsgi_request *);
  extern void (*uwsgi_pypy_post_fork_hook)(void);
++extern void (*uwsgi_pypy_hook_atexit)(void);
  '''
  
 +
@@ -13,7 +16,7 @@
  # here we load CFLAGS and uwsgi.h from the binary
  defines0 = '''
  char *uwsgi_get_cflags();
-@@ -46,7 +52,7 @@
+@@ -46,7 +53,7 @@
  # basically it build a list of #define from binary CFLAGS
  uwsgi_cdef = []
  uwsgi_defines = []
@@ -22,7 +25,7 @@
  for cflag in uwsgi_cflags:
      if cflag.startswith('-D'):
          line = cflag[2:]
-@@ -57,8 +63,14 @@
+@@ -57,8 +64,14 @@
          else:
              uwsgi_cdef.append('#define %s ...' % line)
              uwsgi_defines.append('#define %s 1' % line)
@@ -38,7 +41,7 @@
  # uwsgi definitions
  cdefines = '''
  %s
-@@ -168,7 +180,7 @@
+@@ -168,7 +181,7 @@
  };
  struct uwsgi_server uwsgi;
  
@@ -47,7 +50,7 @@
  
  const char *uwsgi_pypy_version;
  
-@@ -269,7 +281,7 @@
+@@ -269,7 +282,7 @@
  %s
  
  extern struct uwsgi_server uwsgi;
@@ -56,7 +59,7 @@
  %s
  ''' % ('\n'.join(uwsgi_defines), uwsgi_dot_h, hooks)
  
-@@ -286,7 +298,7 @@
+@@ -286,7 +299,7 @@
  
  # fix argv if needed
  if len(sys.argv) == 0:
@@ -65,7 +68,7 @@
  
  
  @ffi.callback("void(char *)")
-@@ -305,7 +317,7 @@
+@@ -305,7 +318,7 @@
      load a wsgi module
      """
      global wsgi_application
@@ -74,7 +77,7 @@
      c = 'application'
      if ':' in m:
          m, c = m.split(':')
-@@ -322,7 +334,7 @@
+@@ -322,7 +335,7 @@
      load a mod_wsgi compliant .wsgi file
      """
      global wsgi_application
@@ -83,7 +86,7 @@
      c = 'application'
      mod = imp.load_source('uwsgi_file_wsgi', w)
      wsgi_application = getattr(mod, c)
-@@ -334,7 +346,7 @@
+@@ -334,7 +347,7 @@
      load a .ini paste app
      """
      global wsgi_application
@@ -92,7 +95,28 @@
      if c.startswith('config:'):
          c = c[7:]
      if c[0] != '/':
-@@ -363,7 +375,7 @@
+@@ -358,12 +371,28 @@
+         uwsgi.post_fork_hook()
+ 
+ 
++@ffi.callback("void()")
++def uwsgi_pypy_atexit():
++    """
++    .atexit handler implementation
++    """
++    import uwsgi
++    uahandler = getattr(uwsgi, "atexit", None)
++    if callable(uahandler):
++        uahandler()
++
++    import atexit
++    aefn = getattr(atexit, "_run_exitfuncs", None)
++    if callable(aefn):
++        aefn()
++
++
+ @ffi.callback("void(char *)")
+ def uwsgi_pypy_pythonpath(item):
      """
      add an item to the pythonpath
      """
@@ -101,11 +125,11 @@
      sys.path.append(path)
      print("added %s to pythonpath" % path)
  
-@@ -470,15 +482,17 @@
+@@ -470,15 +499,17 @@
      def start_response(status, headers, exc_info=None):
          if exc_info:
              traceback.print_exception(*exc_info)
-+        status = status.encode("latin1")            
++        status = status.encode("latin1")
          lib.uwsgi_response_prepare_headers(wsgi_req, ffi.new("char[]", status), len(status))
          for hh in headers:
 +            hh = (hh[0].encode("latin1"), hh[1].encode("latin1"))
@@ -120,7 +144,15 @@
  
      environ['wsgi.version'] = (1, 0)
      scheme = 'http'
-@@ -537,7 +551,7 @@
+@@ -523,6 +554,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
++lib.uwsgi_pypy_hook_atexit = uwsgi_pypy_atexit
+ 
+ """
+ Here we define the "uwsgi" virtual module
+@@ -537,7 +569,7 @@
  def uwsgi_pypy_uwsgi_register_signal(signum, kind, handler):
      cb = ffi.callback('void(int)', handler)
      uwsgi_gc.append(cb)
@@ -129,7 +161,7 @@
          raise Exception("unable to register signal %d" % signum)
  uwsgi.register_signal = uwsgi_pypy_uwsgi_register_signal
  
-@@ -562,7 +576,7 @@
+@@ -562,7 +594,7 @@
      rpc_func = uwsgi_pypy_RPC(func)
      cb = ffi.callback("int(int, char*[], int[], char**)", rpc_func)
      uwsgi_gc.append(cb)
@@ -138,7 +170,7 @@
          raise Exception("unable to register rpc func %s" % name)
  uwsgi.register_rpc = uwsgi_pypy_uwsgi_register_rpc
  
-@@ -598,8 +612,8 @@
+@@ -598,8 +630,8 @@
  
  def uwsgi_pypy_call(func, *args):
      node = None