Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

eval with timeout, threaded perl

by erroneousBollock (Curate)
on Jan 14, 2002 at 16:22 UTC ( #138554=perlquestion: print w/replies, xml ) Need Help??

erroneousBollock has asked for the wisdom of the Perl Monks concerning the following question:

Hello all,

I am in a group writing yet another webserver in Perl. This server uses Thread.pm (adaptive pre-threading server). This server has embedded perl pages (like a higher level PHP).

There are "Very Good Reasons" (outside the scope of a simple http daemon) for this being a threaded implementation.

My problem is that I wish to eval() the embedded perl code (yes with Safe.pm) so that said eval() will timeout (in say X seconds), printing whatever had been produced thus-far, with an appropriate timeout error message.

I first thought about alarm(), but quickly realised that signals cannot be delivered to specific threads.

I then tried reusing a pre-existing "monitor" thread in the server to kill off individual threads after a timeout period. Unfortunately, as there is no "kill thread" method or easily forseeable alternative, I had to periodically poll the "monitor" thread from each child.... which of course does not help for killing off a child who is performing some non-deterministic perl user-code.

I toyed with async(), and Time::HiRes, but thusfar have not found the "easy" way I seek. (The embedded perl code, and a timer , race to lock a per-thread scalar, the output or error is printed, the losing-thread is cleaned up).

If anyone has any suggestions, I would be supremely grateful. Either concepts or real code is fine.

PS: I am not too concerned about malicious user code crashing the server, as for applications "not audited by the administrator", the server will fork() a whole new threaded server... which will or won't die.

Replies are listed 'Best First'.
Re (tilly) 1: eval with timeout, threaded perl
by tilly (Archbishop) on Jan 14, 2002 at 18:40 UTC
    Are your "very good reasons" good enough to justify using a threading implementation which is experimental and is known not to be thread-safe?

    You haven't said what you are doing, but my strong recommendation is to use an existing solution, such as Apache with mod_perl.

    As for your problem, the best way I can think of to solve it with threading is to split the child thread into 2. One to write back to the client, one to wait a fixed time, and if the page is still loading send a timeout message and then close the connection. (The backend work still gets done either way.) Hope and pray that you don't have a race between when the sleeper starts writing its timeout message and when the other thread chooses to finish what it is doing...

      Are your "very good reasons" good enough to justify using a threading implementation which is experimental and is known not to be thread-safe?
      Of course ;p I am aware of the threading stability issues, including those affecting non-threaded functionality in the threaded perl interpreter. (Eventually, probably long before perl6 :) that'll become less of an issue.)

      Hmmmm, as to your suggestion.... not robust but a good idea. I wonder if i can pass 2 tie()'d filehandles to the client code (replacing STDIN & STDOUT), with explicit functionality to stop the close() from working, replacing it with some cond_wait() on a per-thread scalar.... hmmmm, an async() block cotaining a timer either will or wont have locked that scalar.

      Ewwww, it sounds just evil enough to work!
      Thanks I'll try :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://138554]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2022-06-29 01:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My most frequent journeys are powered by:









    Results (94 votes). Check out past polls.

    Notices?