in reply to the unsafe signals controversy

It seems to me that 'deferred signals' is a temporary workaround until the 'unsafe signals' can be made safe. Does anyone else feel this way?
It doesn't matter how anyone feels on the matter. You either take a signal dispatch within an opcode (unsafe), or you don't (safe).

If you take one within an opcode, there's a chance that the opcode is executing something nasty, like redeploying a hash that's grown too big for its britches. If your signal code also accesses the same hash, boom, you're gone!

If you wait until the opcode is done, the world is a safer place, because you won't be in the "middle" of a Perl instruction. The problem is, some opcodes can take a really long time, as you've apparently discovered.

I don't really see a third option. It's not like some magical component is going to fall out of the sky that'll make it possible to do intra-opcode interrupts that automatically avoid touching everything that is mid-action. That'd be like interrupting a processor instruction in the middle of an add or something.

I remember reading a book on CPU architecture when I was really young, and came across the astounding assertion that at some level, all interrupts are really polls, so that they happen at the proper logical time. You're just seeing that the granularity of Perl "polling" is a single Perl opcode, as expected by design.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

Replies are listed 'Best First'.
Re^2: the unsafe signals controversy (grainy)
by tye (Sage) on Mar 23, 2004 at 17:10 UTC

    I thought the next step was rather obvious. If there are certain opcodes that can take a long time to run, then the code run by those opcodes should be made smarter, releasing the critical section (or whatever else it might be called) during the parts of the opcode when blocking I/O is being done and unlocking it briefly and repeatedly at 'safe' points if the opcode involves some long-running actions such as looping.

    - tye        

      Yes, that's part of the solution. Another part is to detect duplicate signals and failover to the unsafe system if it is determined that the safe signal is not being delivered in a timely fashion. Then the poor schmuck bouncing on Ctrl-C has a chance to bomb out of his program sometime before next October.
      Not unlike the move-long (MVCL) and compare-long (CLCL) instructions in the MVS Architecture (IBM OS/370, OS/390, z-OS, or whatever they are calling it today). The instructions operate on blocks of data up to 2^^24 bytes in length, but the micro-code stores state and take interupts every 1024 bytes. The Architecture also has save-state and resume-state functions implemented as single instructions, and hardware save-areas reserved for six different kinds of interupts, so it is easy to receive interupts in a timely fashion.

      IIRC, before the advent of the outboard I/O Subsystem, all of the I/O programming was done the same way -- start a transfer of 32 bytes, wait for it to finish, check status, transfer-in-channel back to the start of the I/O command chain; the TIC instruction was interupatable, the channel commands weren't.

      ----
      I Go Back to Sleep, Now.

      OGB

Re: •Re: the unsafe signals controversy
by jfroebe (Parson) on Mar 23, 2004 at 18:53 UTC
    I see your point but there are instances when the opcode will never return (i.e. name resolution where the udp packet was lost).

    Perhaps some of the single opcodes should be two or more by using the reentrant versions of the system calls (if available on the platform).

    I'm trying to see some way to either safely abort an operation (i.e connect to a DBI oracle backend) or minimize the damage done (spawning off a process?).

    There are two paramount items in enterprise systems: 1) performance 2) reliability. These two have always been at odds but with the inability to safely timeout a connection to an Oracle or Sybase dbms, timeout a name lookup call, etc. the use of perl will be limited to non-production jobs in enterprise systems.

    Jason

      For the Sybase part at least you can use the "loginTimeout" connection property, so you don't actually have to use a perl-level alarm() call to interrupt the request.

      Michael

Re: •Re: the unsafe signals controversy
by eserte (Deacon) on Mar 23, 2004 at 17:45 UTC
    Can some Perl internals specialist give an estimate about possible memory corruption or segfaults if only a single integer scalar is changed in the signal handler?
      If the only code is $integer++, it doesn't take an "internals specialist" to realize that there is about 0 chance of memory corruption or segfaults.
        If the only code is $integer++, it doesn't take an "internals specialist" to realize that there is about 0 chance of memory corruption or segfaults.

        Wanna bet?

        Unless $integer has already just been assigned an integer value, it will currently be of type SVt_NULL; the first ++ will upgrade it to SVt_IV, which may cause a malloc. If the signal occured during a call to malloc, then Boom!

        Of course you could avoid this by ensuring that there is the initial assignment $integer=0 before the signal handler is called, but even that isn't enough. A Perl-level signal handler calls a *sub* not a statement, and entering a sub involves pushing things onto the context and save stacks, which can again trigger mallocs.