2014-09-23, 15:54
EDIT: I added more comments in the code example to hopefully make it clearer.
I included the sleep in my code as a demo to demonstrate how it works in a fully runnable example. I have no idea exactly how the OP intends to use the routine so I wanted to ensure that the .isupdating variable gets updated, regardless of what he is doing in his main thread. I have nothing to do in my main thread in an example. I could have written an infinite loop to keep things alive instead (in the following example I use time.sleep to keep it alive)...
And in my experience, if the main thread does not release control by sleeping with xbmc.sleep, the event will not be executed.
For example:
Using this I ran the code four times, manually changing the variable test_cond. If you use threading and do not call xbmc.sleep, the variable (.isupdating) gets updated without any issues (test_cond = 2). If you do not use threading and do not call xbmc.sleep, the variable is never updated and the method fails (test_cond=4).
If you say that the events are not reliably called within xbmc when db scans start and stop, then the whole issue is moot. If the problem hasn't been reported then perhaps you may want to open a ticket at http://trac.xbmc.org/
I included the sleep in my code as a demo to demonstrate how it works in a fully runnable example. I have no idea exactly how the OP intends to use the routine so I wanted to ensure that the .isupdating variable gets updated, regardless of what he is doing in his main thread. I have nothing to do in my main thread in an example. I could have written an infinite loop to keep things alive instead (in the following example I use time.sleep to keep it alive)...
And in my experience, if the main thread does not release control by sleeping with xbmc.sleep, the event will not be executed.
For example:
Code:
import threading
import time
import xbmc
dbmonitor = None
class XbmcMonitor (xbmc.Monitor):
def __init__(self):
xbmc.Monitor.__init__(self)
self.isupdating = False
def onDatabaseScanStarted(self, database):
self.isupdating = True
xbmc.log('######## Scan started thread: %s' % str(threading.current_thread().ident), level=xbmc.LOGNOTICE)
def onDatabaseUpdated(self, database):
self.isupdating = False
xbmc.log('######## Scan ended thread: %s' % str(threading.current_thread().ident), level=xbmc.LOGNOTICE)
def threadstart():
global dbmonitor
dbmonitor = XbmcMonitor()
while not xbmc.abortRequested:
xbmc.sleep(250)
def main():
# test_cond = 1: Use threading and xbmc.sleep - result successful
# test_cond = 2: Use threading and time.sleep - result successful
# test_cond = 3: No threading and xbmc.sleep - result successful
# test_cond = 4: No threading and time.sleep - fails
test_cond = 4 # Change this manually to test different scenarios
if test_cond == 1 or test_cond == 2: # Use threading
thread = threading.Thread(target=threadstart)
thread.start()
xbmc.sleep(1000) # Need to wait until thread is started before checking .isupdating below since there is some
# asynchronous time overhead for thread starting
elif test_cond == 3 or test_cond == 4: # No threading
global dbmonitor
dbmonitor = XbmcMonitor()
while not xbmc.abortRequested:
if dbmonitor.isupdating is True:
xbmc.log('######### DB updating thread: %s' % str(threading.current_thread().ident), level=xbmc.LOGNOTICE)
if test_cond == 1 or test_cond == 3:
xbmc.sleep(500)
else:
time.sleep(0.500) # This could be an infinite loop or a bunch of other code that doesn't release control
if __name__ == '__main__':
main()
Using this I ran the code four times, manually changing the variable test_cond. If you use threading and do not call xbmc.sleep, the variable (.isupdating) gets updated without any issues (test_cond = 2). If you do not use threading and do not call xbmc.sleep, the variable is never updated and the method fails (test_cond=4).
If you say that the events are not reliably called within xbmc when db scans start and stop, then the whole issue is moot. If the problem hasn't been reported then perhaps you may want to open a ticket at http://trac.xbmc.org/