We discussed this in IRC on 2009-07-18. I think the plan was something like:
* Don't add threads. * Use SIGALRM for both JS_TriggerOperationCallback and the select() race, with the same signal handler function. * Add a global variable that lists the scripts being evaluated. Each element of the list contains a JSContext * and a time_t. The list should normally have just 0 or 1 element so we don't need any fancy priority queue. * Add ecmascript_check_alarms(), which walks this list and calls JS_TriggerOperationCallback for each context whose timeout has expired. It then returns the number that should be passed to the next alarm() call. * Before each call to JS_EvaluateScript, construct a list element as an auto variable, add it to the list, and call alarm(ecmascript_check_alarms()). * After each call to JS_EvaluateScript, remove the element from the list, and call alarm(ecmascript_check_alarms()). * If e.g. Win32 doesn't support alarm(), don't implement the ECMAScript timeout there. * The old SIGALRM code (critical_section, pending_alarm, alarm_handler, check_for_select_race, uninstall_alarm) seems intended to handle the case where a signal occurs immediately before select() and ELinks would instead like it to interrupt the select(). (The race condition could be entirely prevented, by blocking the signals almost all the time and letting pselect() unblock them. That would however be less portable.) Because select_loop() is not called recursively, this should never get run during ECMAScript evaluation. Add some assertions for that. * There are some sleep() calls in error handlers. Replace those with a wrapper that calls alarm(ecmascript_check_alarms()) at the end, in case sleep() interfered with alarm().
pgpKsS6C1CmhM.pgp
Description: PGP signature