You have a big problem. A perl interp is not thread safe with itself. I could tell you to use to just use PERL_SET_CONTEXT to move the perl interp pointer between threads, but you will then probably have random panics and bizzare type errors. I suggest a pure C callback system with a struct with a mutex in it, that is shared between your SO's threads and your perl interp's thread. Your SO thread will run, get the lock, write whatever into the struct, release the lock, then your XS code will obtain the lock on the struct (or block on the lock of the SO side), read the contents, release the lock. The design won't work if the C caller requires some kind of data that must be calculated in the C callback, and can't sanely be done in pure C with a pile of flags and option codes in a struct.
BrowserUK's solution is one choice, its too adventurous for my taste, freezing the perl interp, putting it in a pool of some kind, grabbing it for your library's thread to use, run some Perl code, then releasing it back to the pool, and eventually the original XS func will take the interp from the pool and return it back to the original Perl thread. I don't know if sleep() is the "correct" way to freeze the perl interp or if perl's sleep op is rated for reenterancey. To use sleep to freeze the interp, you would be depending on the internal implementation of perl safe/deferred signals at the moment. I think a dedicated XS func to freeze the interp and release the interp to be locked by the pool of threads is safer.
My opinion is there are no problems that make it impossible to use your library, its just very difficult for someone isn't familiar with XS, the perl interp, and OS multithreading/thread safety. You should also have a -Od/-DDEBUGGING compiled perl interp, a C debugger, and full symbols for that debugger. Be sure to use " #define PERL_NO_GET_CONTEXT " and use aTHX/aTHX_ and pTHX/pTHX_ and " tTHX my_perl;" to declare but not initialize a my_perl pointer. A dTHX will declare and initialize. Use your C compiler and a C code fomatter to look at the post-processed output of your code. Once you see the post-processor code, you will get a better idea what going on. You have to create a my_perl pointer AND use PERL_SET_CONTEXT. Both are required. Some parts of the perl interp pass the my_perl pointer as a c parameter, others parts of the perl interp use dTHX to fetch it from, atleast on Windows its called Thread Local Storage. No idea what perl uses on Unix for PERL_SET_CONTEXT. Remember at the end of your C callback in the library's thread, to do "PERL_SET_CONTEXT(NULL);" to make sure that there is no accident of making a callback into the interp while the interp is executing other code. Also Browser UK's solution doesn't scale well if you have dozens of threads, and alot of synchronous I/O or long (many millsecs) Perl language code to run. Your library will start to slow down because the C callbacks block on the lock for the single perl interp. Remember your library probably creates many OS threads for a good reason. If push this design too far, you will have effectively made your library single threaded. If your run into the limitation of having only 1 perl interp in the process, you have to create more. I've never seen C code that made a pool of perl interps that get borrowed randomly by random OS threads, but it should be possible.
Without seeing code, its difficult to help you with anything else but generalities.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.