atexit_threads.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # threads are dumb, this module is smart.
  2. #
  3. # The contents of this file are subject to the Python Software Foundation
  4. # License Version 2.3 (the License). You may not copy or use this file, in
  5. # either source code or executable form, except in compliance with the License.
  6. # You may obtain a copy of the License at http://www.python.org/license.
  7. #
  8. # Software distributed under the License is distributed on an AS IS basis,
  9. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  10. # for the specific language governing rights and limitations under the
  11. # License.
  12. #
  13. # by Greg Hazel
  14. import sys
  15. import time
  16. import atexit
  17. import threading
  18. def _get_non_daemons():
  19. return [d for d in threading.enumerate() if not d.isDaemon() and d != threading.currentThread()]
  20. def register(func, *targs, **kargs):
  21. def duh():
  22. nondaemons = _get_non_daemons()
  23. for th in nondaemons:
  24. th.join()
  25. func(*targs, **kargs)
  26. atexit.register(duh)
  27. def megadeth():
  28. time.sleep(10)
  29. try:
  30. import wx
  31. wx.Kill(wx.GetProcessId(), wx.SIGKILL)
  32. except:
  33. pass
  34. def register_verbose(func, *targs, **kargs):
  35. def duh():
  36. nondaemons = _get_non_daemons()
  37. timeout = 4
  38. for th in nondaemons:
  39. start = time.time()
  40. th.join(timeout)
  41. timeout = max(0, timeout - (time.time() - start))
  42. if timeout == 0:
  43. break
  44. # kill all the losers
  45. # remove this when there are no more losers
  46. t = threading.Thread(target=megadeth)
  47. t.setDaemon(True)
  48. t.start()
  49. if timeout == 0:
  50. sys.stderr.write("non-daemon threads not shutting down "
  51. "in a timely fashion:\n")
  52. nondaemons = _get_non_daemons()
  53. for th in nondaemons:
  54. sys.stderr.write(" %s\n" % th)
  55. sys.stderr.write("You have no chance to survive make your time.\n")
  56. for th in nondaemons:
  57. th.join()
  58. func(*targs, **kargs)
  59. atexit.register(duh)