{"action":"created","issue":{"url":"https://api.github.com/repos/ninia/jep/issues/161","repository_url":"https://api.github.com/repos/ninia/jep","labels_url":"https://api.github.com/repos/ninia/jep/issues/161/labels{/name}","comments_url":"https://api.github.com/repos/ninia/jep/issues/161/comments","events_url":"https://api.github.com/repos/ninia/jep/issues/161/events","html_url":"https://github.com/ninia/jep/issues/161","id":353020416,"node_id":"MDU6SXNzdWUzNTMwMjA0MTY=","number":161,"title":"Jep should throw exception when closing a Jep sub-interpreter instance that has threads still running","user":{"login":"ndjensen","id":5747885,"node_id":"MDQ6VXNlcjU3NDc4ODU=","avatar_url":"https://avatars3.githubusercontent.com/u/5747885?v=4","gravatar_id":"","url":"https://api.github.com/users/ndjensen","html_url":"https://github.com/ndjensen","followers_url":"https://api.github.com/users/ndjensen/followers","following_url":"https://api.github.com/users/ndjensen/following{/other_user}","gists_url":"https://api.github.com/users/ndjensen/gists{/gist_id}","starred_url":"https://api.github.com/users/ndjensen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ndjensen/subscriptions","organizations_url":"https://api.github.com/users/ndjensen/orgs","repos_url":"https://api.github.com/users/ndjensen/repos","events_url":"https://api.github.com/users/ndjensen/events{/privacy}","received_events_url":"https://api.github.com/users/ndjensen/received_events","type":"User","site_admin":false},"labels":[{"id":227720411,"node_id":"MDU6TGFiZWwyMjc3MjA0MTE=","url":"https://api.github.com/repos/ninia/jep/labels/improvement","name":"improvement","color":"009800","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-22T16:00:21Z","updated_at":"2018-11-17T22:26:54Z","closed_at":null,"author_association":"MEMBER","body":"See https://groups.google.com/forum/#!topic/jep-project/9qnpnNBipXA\r\n\r\nIf a Jep instance is closed while a thread is still running inside that sub-interpreter, the process/application will exit and shut down.\r\n\r\nExample:\r\n\r\n```java\r\ntry(Jep jep = new Jep()) {\r\n    jep.runScript(\"./src/main/python/thread_test.py\");\r\n} catch (JepException e) {\r\n    e.printStackTrace();\r\n}\r\n\r\n```\r\n\r\n```python\r\nimport threading\r\nimport time\r\nimport sys\r\n# import thread\r\ndef f1():\r\n    for i in range(5):\r\n        print (\"f1...\\n\")\r\n        sys.stdout.flush()\r\n        time.sleep(1)\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n    t = threading.Thread(target=f1, args=())\r\n    t.setDaemon(True)\r\n    t.start()\r\n\r\n    for t in threading.enumerate():\r\n        print (t.getName())\r\n        #if t.getName() != \"MainThread\":\r\n            #t._Thread__stop()\r\n            #t._stop()\r\n    print (threading.enumerate())\r\n```\r\n\r\nCurrent C code in pyembed.c's `pyembed_thread_close()`:\r\n```C\r\nif (jepThread->tstate->interp == mainThreadState->interp) {\r\n    PyThreadState_Clear(jepThread->tstate);\r\n    PyThreadState_Swap(NULL);\r\n    PyThreadState_Delete(jepThread->tstate);\r\n} else {\r\n    Py_EndInterpreter(jepThread->tstate);\r\n}\r\n````\r\n\r\nWhen Jep.close() is called,  there is a fatal error:\r\n`Fatal Python error: Py_EndInterpreter: not the last thread`.  `Py_EndInterpreter(jepThread->tstate);` eventually uses Py_FatalError which will end the process.  https://github.com/python/cpython/blob/46dc4e34ed8005a688d7f3512844ef227a3465f4/Python/pylifecycle.c#L1506\r\n\r\nJep should attempt to detect this situation and throw an exception indicating the developer needs to manage their threads, preventing an exit and shutdown of the process."},"comment":{"url":"https://api.github.com/repos/ninia/jep/issues/comments/439652127","html_url":"https://github.com/ninia/jep/issues/161#issuecomment-439652127","issue_url":"https://api.github.com/repos/ninia/jep/issues/161","id":439652127,"node_id":"MDEyOklzc3VlQ29tbWVudDQzOTY1MjEyNw==","user":{"login":"bsteffensmeier","id":13338101,"node_id":"MDQ6VXNlcjEzMzM4MTAx","avatar_url":"https://avatars1.githubusercontent.com/u/13338101?v=4","gravatar_id":"","url":"https://api.github.com/users/bsteffensmeier","html_url":"https://github.com/bsteffensmeier","followers_url":"https://api.github.com/users/bsteffensmeier/followers","following_url":"https://api.github.com/users/bsteffensmeier/following{/other_user}","gists_url":"https://api.github.com/users/bsteffensmeier/gists{/gist_id}","starred_url":"https://api.github.com/users/bsteffensmeier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bsteffensmeier/subscriptions","organizations_url":"https://api.github.com/users/bsteffensmeier/orgs","repos_url":"https://api.github.com/users/bsteffensmeier/repos","events_url":"https://api.github.com/users/bsteffensmeier/events{/privacy}","received_events_url":"https://api.github.com/users/bsteffensmeier/received_events","type":"User","site_admin":false},"created_at":"2018-11-17T22:26:54Z","updated_at":"2018-11-17T22:26:54Z","author_association":"MEMBER","body":"This is fixed in dev_3.9 with d36a4b9."}}
{"actor":{"display_login":"bsteffensmeier"}}