Kernel32 I/O will never create threads. APCs dont do it. IO Completion Ports don't do it, and doing a WaitForMultipleObjects won't create threads.
Perl crash during perl_clone
, I would have done it a different way than was done in that thread. It looks to me, like your tried to run Perl code from a QueueUserWorkItem
style thread. A random thread, of which there is a random count of at a single point in time, and the threads come and go randomly, and they run C callbacks randomly. Perl generally can't be fit into that model, since creating and tearing down interps will take too many milliseconds per callback run. There can be 1 interp, and using C/OS level locks, it can be checked out by a random thread, and then returned to a free state. The original OS thread the Perl interp started from goes into a blocking wait of some kind and lets the interp go "thread free" and then random threads pick it up, run a CV, then return to thread free state. I think I have seen a live sample of that on PerlMonks before, maybe by BrowserUk
Oh well, I see that is what you did. In a OS thread pool model, you can use just ints into a Perl Array/AV/package @array in 1 Perl thread. It is easier than sending SV/CV/etc *s through the thread pool as opaque with a ref count notch being owned by thread pool queue/3rd party lib, since a random thread callback can't dec the SV * if it reaches 0 and there isn't THE one free interp around anymore since the process is exiting or something. You can't move SV *s between interps. "Free to wrong pool".
My solution is to never try to move the Perl thread off its original OS thread. Instead use a mechanism (CS locks/queues/linked lists/C structs/C arrays/Windows Message Queue) to deliver the event from the random OS thread to the 1 Perl thread in the process. If the caller of the C callback wants an answer to running the user supplied C callback, a return value for example, the return value in my design is selected on Perl lang level before the async transaction is started. This may not be acceptable in certain kinds async transactions. Of course the C callback can send the event from the thread room, into the many C threads to 1 Perl thread queue, and block in the random C thread until the 1 Perl thread processes the event, then sets a return value, then unblocks the random C thread that originated the event. Assuming the 1 Perl thread isn't CPU maxed out, the response time of the C callback will be max a couple ms.
's callback support has been fixed to be crash resistant. If you try to run it in an OS thread with no perl interp in Thread Local Storage (AKA thread pool), it will safely complain, not crash, and not try to run any Perl code, see https://github.com/bulk88/perl5-win32-api/blob/master/Callback/Callback.xs#L187