gthread.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """
  2. @package core.gthread
  3. @brief Threading
  4. Classes:
  5. - gthread::gThread
  6. (C) 2013-2014 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. @author Stepan Turek <stepan.turek seznam.cz> (mentor: Martin Landa)
  10. """
  11. import threading
  12. import time
  13. import wx
  14. import sys
  15. if sys.version_info.major == 2:
  16. import Queue
  17. else:
  18. import queue as Queue
  19. from core.gconsole import EVT_CMD_DONE, wxCmdDone
  20. class gThread(threading.Thread, wx.EvtHandler):
  21. """Thread for various backends"""
  22. requestId = 0
  23. def __init__(self, requestQ=None, resultQ=None, **kwds):
  24. wx.EvtHandler.__init__(self)
  25. self.terminate = False
  26. threading.Thread.__init__(self, **kwds)
  27. if requestQ is None:
  28. self.requestQ = Queue.Queue()
  29. else:
  30. self.requestQ = requestQ
  31. if resultQ is None:
  32. self.resultQ = Queue.Queue()
  33. else:
  34. self.resultQ = resultQ
  35. self.setDaemon(True)
  36. self.Bind(EVT_CMD_DONE, self.OnDone)
  37. self.start()
  38. def Run(self, *args, **kwds):
  39. """Run command in queue
  40. :param args: unnamed command arguments
  41. :param kwds: named command arguments, keyword 'callable'
  42. represents function to be run, keyword 'ondone'
  43. represents function to be called after the
  44. callable is done
  45. :return: request id in queue
  46. """
  47. gThread.requestId += 1
  48. self.requestQ.put((gThread.requestId, args, kwds))
  49. return gThread.requestId
  50. def GetId(self):
  51. """Get id for next command"""
  52. return gThread.requestId + 1
  53. def SetId(self, id):
  54. """Set starting id"""
  55. gThread.requestId = id
  56. def run(self):
  57. while True:
  58. requestId, args, kwds = self.requestQ.get()
  59. for key in ('callable', 'ondone', 'userdata'):
  60. if key in kwds:
  61. vars()[key] = kwds[key]
  62. del kwds[key]
  63. else:
  64. vars()[key] = None
  65. requestTime = time.time()
  66. ret = None
  67. exception = None
  68. time.sleep(.01)
  69. if self.terminate:
  70. return
  71. ret = vars()['callable'](*args, **kwds)
  72. if self.terminate:
  73. return
  74. # except Exception as e:
  75. # exception = e;
  76. self.resultQ.put((requestId, ret))
  77. event = wxCmdDone(ondone=vars()['ondone'],
  78. kwds=kwds,
  79. args=args, # TODO expand args to kwds
  80. ret=ret,
  81. exception=exception,
  82. userdata=vars()['userdata'],
  83. pid=requestId)
  84. # send event
  85. wx.PostEvent(self, event)
  86. def OnDone(self, event):
  87. if event.ondone:
  88. event.ondone(event)
  89. def Terminate(self, terminate=True):
  90. """Abort command(s)"""
  91. self.terminate = terminate