Using Python threads in enigma2 plugins (helper-code inside)

    • Offizieller Beitrag

    -- some links at the bottom!


    Hi,


    as many of you may have already noticed we've recently (2 tarballs ago) added a small change with some big effects some plugins.
    Basically we have added an ASSERT(currentThread != mainThread) to eTimer and eSocketNotfier.


    We did this to ensure plugins are not calling enigma2 core functionality from any thread other than the main thread.


    We thought this change would only affect one or maybe two plugins, and well... it seems we've been wrong there, so i would like to explain some things.


    Why did we do this?


    The reason is very simple: The enigma2 core/mainloop is not thread safe and therefore calling any core-functionality from a different thread than the Main-Thread will sooner or later get you (or well, enigma2) into trouble.
    Not necessarily always or immediately but if, it usualy rips enigma2 apart causing deadlocks (preferrably with epg operations) or pretty much random crashes.
    We had a quick look at the plugins on schwerkraft and from that point of view only very few plugins would've been affected by the change.


    As seen in the past few days quite some of the plugins not hosted on schwerkraft have been heavily affected by this change causing enigma2 to crash quite frequently.
    Some of those plugins have been cleaned up by their maintainers already (e.g. Lcd4Linux, FanControl2) while others are still to be fixed or added some quick workarounds to avoid the crashes.


    To fix your plugin(s) please follow these rules of thumb:

    • only use threads for things that really take a long time to process, don' wrap a thread around your whole code just because it seems easier to handle
    • never call any functionality that is, no matter how, linked to the core (bascially nothing that is directly connected to enigma2, like Screens, Components, Sources, EPG, basically everything that leads back to "from enigma2 import ..." at some point)
    • yes EPG, it can take long but it's currently totally NOT thread-safe, don't thread it! Autotimer works without epg in a thread, so you can do that, too!
    • eMessagePump IS thread-safe, actually it has been built for inter-thread-communication and may be used in python threads, too!
    • twisted has quite some functionality to make using threads in python easier!
    • let me quote: "Most code in Twisted is not thread-safe". BUT: Twisted it is asynchronous by nature and shouldn't need threads!



    If you're not sure wether a method is being called on the mainThread or not you could use

    Python
    from threading import currentThread
    print currentThread().getName()


    To check that! It will return "MainThread" in case of the main thread or something like "PoolThread-twisted.internet.reactor-1" for any other python thread.


    You may also want to know something about the call stack, you can print the python call stack with:

    Code
    import traceback
    traceback.print_stack()


    I've linked to a pastebin with some helper code and an examplary test() function for doing expensive things in a thread but keeping enigma2 stuff on the main thread.
    There's also a link to twisted's short explanation of using threads properly, the two helper-functions in the first link just simplify to of the most common cases a little bit for you.


    - Python Helpers to call a function on the main thread: http://pastebin.com/dqHGnJ8B
    - twisted threads documentation: http://twistedmatrix.com/docum…core/howto/threading.html


    If you still have questions or issues feel free to join #enigma2 on the freenode IRC network.

    mfg ,
    Reichi

    14 Mal editiert, zuletzt von Reichi ()