Beremiz_service.py
changeset 2484 2318a7cde101
parent 2476 1881d0ff5ae2
child 2489 27e4fd37fea6
equal deleted inserted replaced
2483:6a7f92b84855 2484:2318a7cde101
    28 from __future__ import print_function
    28 from __future__ import print_function
    29 import os
    29 import os
    30 import sys
    30 import sys
    31 import getopt
    31 import getopt
    32 import threading
    32 import threading
    33 from threading import Thread, Semaphore, Lock
    33 from threading import Thread, Semaphore, Lock, currentThread
    34 import __builtin__
    34 import __builtin__
    35 from builtins import str as text
    35 from builtins import str as text
    36 from past.builtins import execfile
    36 from past.builtins import execfile
    37 from six.moves import builtins
    37 from six.moves import builtins
    38 
    38 
   412 
   412 
   413 if havetwisted:
   413 if havetwisted:
   414     if havewx:
   414     if havewx:
   415         reactor.registerWxApp(app)
   415         reactor.registerWxApp(app)
   416 
   416 
       
   417 twisted_reactor_thread_id = None
       
   418 ui_thread = None 
       
   419 
   417 if havewx:
   420 if havewx:
   418     wx_eval_lock = Semaphore(0)
   421     wx_eval_lock = Semaphore(0)
   419     # FIXME : beware wx mainloop is _not_ running in main thread
       
   420     # main_thread = currentThread()
       
   421 
   422 
   422     def statuschangeTskBar(status):
   423     def statuschangeTskBar(status):
   423         wx.CallAfter(taskbar_instance.UpdateIcon, status)
   424         wx.CallAfter(taskbar_instance.UpdateIcon, status)
   424 
   425 
   425     statuschange.append(statuschangeTskBar)
   426     statuschange.append(statuschangeTskBar)
   428         tocall, args, kwargs = obj.call
   429         tocall, args, kwargs = obj.call
   429         obj.res = default_evaluator(tocall, *args, **kwargs)
   430         obj.res = default_evaluator(tocall, *args, **kwargs)
   430         wx_eval_lock.release()
   431         wx_eval_lock.release()
   431 
   432 
   432     def evaluator(tocall, *args, **kwargs):
   433     def evaluator(tocall, *args, **kwargs):
   433         # FIXME : should implement anti-deadlock
   434         # To prevent deadlocks, check if current thread is not one of the UI
   434         # if main_thread == currentThread():
   435         # UI threads can be either the one from WX main loop or
   435         #     # avoid dead lock if called from the wx mainloop
   436         # worker thread from twisted "threadselect" reactor
   436         #     return default_evaluator(tocall, *args, **kwargs)
   437         current_id = currentThread().ident
   437         # else:
   438         if ui_thread is not None \
   438         o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
   439             and ui_thread.ident != current_id \
   439         wx.CallAfter(wx_evaluator, o)
   440             and (not havetwisted or (
   440         wx_eval_lock.acquire()
   441                 twisted_reactor_thread_id is not None 
   441         return o.res
   442                 and twisted_reactor_thread_id != current_id)):
       
   443 
       
   444             o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
       
   445             wx.CallAfter(wx_evaluator, o)
       
   446             wx_eval_lock.acquire()
       
   447             return o.res
       
   448         else:
       
   449             # avoid dead lock if called from the wx mainloop
       
   450             return default_evaluator(tocall, *args, **kwargs)
   442 else:
   451 else:
   443     evaluator = default_evaluator
   452     evaluator = default_evaluator
   444 
   453 
   445 # Exception hooks
   454 # Exception hooks
   446 
   455 
   558     ui_thread = Thread(target=ui_thread_target)
   567     ui_thread = Thread(target=ui_thread_target)
   559     ui_thread.start()
   568     ui_thread.start()
   560 
   569 
   561     # This order ui loop to unblock main thread when ready.
   570     # This order ui loop to unblock main thread when ready.
   562     if havetwisted:
   571     if havetwisted:
   563         reactor.callLater(0, ui_thread_started.release)
   572         def signal_uithread_started():
       
   573             twisted_reactor_thread_id = currentThread().ident
       
   574             ui_thread_started.release()
       
   575         reactor.callLater(0, signal_uithread_started)
   564     else:
   576     else:
   565         wx.CallAfter(ui_thread_started.release)
   577         wx.CallAfter(ui_thread_started.release)
   566 
   578 
   567     # Wait for ui thread to be effective
   579     # Wait for ui thread to be effective
   568     ui_thread_started.acquire()
   580     ui_thread_started.acquire()