On Tue, Jan 24, 2012 at 12:06 AM, Roberto De Ioris <[email protected]> wrote: >> On Mon, Jan 23, 2012 at 3:09 AM, Roberto De Ioris <[email protected]> >> wrote: >> >> when stepping the code, Py_IsInitialized() does return true, but deep >> within python routines threadstate_getframe receives (and tries to >> dereference) a null pointer. >> >> it's like python is using threads anyway? once i comment out the check >> for `uwsgi.has_threads` in `uwsgi_python_atexit`, and thus >> unconditionally call `PyGILState_Ensure()`, everything works fine, but >> i don't know enough to understand why completely. > > This is pretty strange, it looks like the python interactive shell > (--pyshell) is not fully releasing python, but freeing resources in some > way. > Maybe it would be easier to remove "atexit" handler if the worker has been > hijacked.
i think this is by design. SIGINT does not cause interpreter shutdown, but rather a KeyboardInterrupt (when interactive at least), followed by a new prompt, eg: # python Python 3.2.2 (default, Nov 21 2011, 16:50:59) [GCC 4.6.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> KeyboardInterrupt >>> sys <module 'sys' (built-in)> >>> ... the "interactive session" is not destroyed, else calling `sys` would raise NameError. rather than skip the exit hooks (per your message, which does work as intended), why not just remove uWSGI signal handlers altogether? or at least for --pyshell children? this would allow the python interpreter to do it's own thing, and only exit on EOF like a normal interactive session. IMO, the stack should only be killed if the *master* receives a SIGINT. however, on EOF with `--master`, uWSGI respawns the dead child in a similar fashion as a KeyboardInterrupt (SIGINT), but without `--master` it of course just dies on either event ... this poses a problem because as-is, if the signal handler is removed completely as i suggested, there would be no [clean] way to terminate uWSGI from the same shell it was started -- you'd have to manually send a SIGINT to the master process from another shell. possible solution: --pyshell and possibly similar children are "oneshot" only, ie. they only get one life ... after that they revert to normal workers. this would let you spawn uWSGI with --pyshell, do something useful, and leave. it would also prevent this from occurring: # ./uwsgi --master --pyshell -s@null <<<'' *** Starting uWSGI 1.1-dev-1862 (64bit) on [Tue Jan 24 20:28:50 2012] *** [...] *** Operational MODE: single process *** *** no app loaded. going in full dynamic mode *** *** uWSGI is running in multiple interpreter mode *** spawned uWSGI master process (pid: 5486) spawned uWSGI worker 1 (pid: 5487, cores: 1) >>> >>> DAMN ! worker 1 (pid: 5487) died :( trying respawn ... Respawned uWSGI worker 1 (new pid: 5488) >>> DAMN ! worker 1 (pid: 5488) died :( trying respawn ... Respawned uWSGI worker 1 (new pid: 5489) >>> DAMN [... repeat forever ...] ... which loops forever until killed. if --pyshell was "oneshot", you could pipe an initialization script into uWSGI, execute it, let the hijacked worker die, then respawn as a regular worker ... this might be useful for other scenarios too. so ... removing uWSGI handlers and only giving the hijacked worker one life == no unbound looping, a neat way to pipe commands into uWSGI, and clean shutdown in all cases i can think of. thoughts? -- C Anthony _______________________________________________ uWSGI mailing list [email protected] http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi
