We have a scenario where a Python program uses a C++ module. The C++ module creates its own threads, and these threads sometimes call back into Python (after first acquiring the GIL, of course). This works quite nicely on Linux and desktop Windows, but crashes on CE. After some debugging I discovered the cause: PythonCE uses its own errno macro which pulls a pointer out of thread-local storage and dereferences it. This works fine if the thread was started in Python, since new threads have a valid address placed into the thread-local storage slot. Non-Python threads, however, have the default initial value for the slot which happens to be zero, so dereferencing it crashes the program.
As far as I can tell, there is no way to work around this that does not involve modifying the PythonCE source. I think we need some call we can make to initialize the thread-local storage for a non-Python thread. The solution is complicated somewhat by the fact that I want to be able to initialize the same thread multiple times without breaking it. The reason for this probably requires some explanation. The straight-forward approach would be to have any new non-Python thread call an initialization function when it starts, then call a de-register function when it finishes (just like Python threads currently do). This approach falls short because it assumes that the creator of a thread knows whether or not that thread will ever call Python. This makes it impossible to take a general-purpose, Python-agnostic C++ module that uses threads and a callback mechanism and expose it to Python in a way that allows callbacks to be written in Python. Because of this, the only sensible approach is to surround the call into Python with our register-thread and de-register-thread functions. This is really not an extra burden, because we already have to surround it with the GIL-acquiring and releasing functions. Now, assume that a thread created in C++ calls into Python, which calls back into C++, which calls into Python again. Since the calls into Python are surrounded by the thread registration/de-registration functions, the registration needs to be smart enough to do nothing the second time, and only de-register the last time. I think I have a solution, but it's not very nice. I'd like to see some suggestions about how to handle this in a more elegant way, and hopefully a permanent solution added to the official distribution. Thanks. -Kevin _______________________________________________ PythonCE mailing list PythonCE@python.org http://mail.python.org/mailman/listinfo/pythonce