<div class="gmail_quote">On Sat, Feb 26, 2011 at 3:34 AM, Nils Bruin <span dir="ltr"><<a href="mailto:nbruin@cecm.sfu.ca">nbruin@cecm.sfu.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I did not quite understand the mprotect trick first but I think I do now. Let me verify:<br>
- If the ECL signal handler finds that the interrupted code is not "safe", then the handler stores the signal information and marks "env" read-only.<br>
- The next time "env" is accessed, a SIGSEGV will be triggered, which the ECL signal handler recognises as being triggered by the mprotected region.<br></blockquote><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; ">
- If safe, the handler now processes the queued signals and we're done.<br></blockquote><div><br></div><div>That's it! This is a trick that I learned in some blog post, but I slightly adapted it.</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Q: Is it guaranteed that this will happen in a "safe" area or is it possible that the signal handler discovers that it is still not safe and hence leaves the queue as is?<br>
</blockquote><div><br></div><div>More or less this is what I expect. I try to keep the signal-protected regions as small as possible, but sometimes it is difficult. The pattern I tried to implement is the following one (in the C core)</div>
<div><br></div><div>* Assign 1 to the flag that blocks signals</div><div>* Execute a small section of protected code.</div><div> Here the signal handler may receive SIGINT and mark the environment as read-only</div><div>
* Assign 0 to that flag</div><div> This may trigger a SIGSEGV if the environment was marked read-only</div><div><br></div><div>The protected code should not _write_ to the environment during the protected region. This is normally the case.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">It still leaves a small window where ECLs handlers are in place but ECLs environment isn't yet. If it would be possible to set the ECL signal handlers to "queue, don't handle" before entering ECL and enable them once the ECL environment is in place it might be possible to remove this one glitch.</blockquote>
<div><br></div><div>In the window from the signal handler swap until ECL is booted, ECL will simply discard all signals, because the signal queue is not installed and ECL is not marked as booted. Or do you perform the swap every time that ECL code is executed?</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Also, this solution would probably not work very well for lots of very small calls into ECL, due to the overhead of all the sigaction calls. I don't think this is much of an issue at the moment, but if it were I imagine the proper solution would be to make sage's signal handler ECL-aware and take appropriate action there (and hooks in the ECL API would help for that)<br>
</blockquote><div><br></div><div>Your previous suggestion, using some API, looks fine, but it would not work with the mprotect() trick, unless your code uses sigaction() and passes the appropriate records</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
In fact, ECL does seem to have a small race condition itself (as most programs seem to have): If I run ECL (stand-alone) and truly bombard it with SIGINTs, I get a segfault.</blockquote></div><br clear="all">I will look into that.<div>
<br></div><div>Juanjo<br><div><br>-- <br>Instituto de Física Fundamental, CSIC<br>c/ Serrano, 113b, Madrid 28006 (Spain) <br><a href="http://juanjose.garciaripoll.googlepages.com" target="_blank">http://juanjose.garciaripoll.googlepages.com</a><br>
</div></div>