Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl subroutine timeout

I have a subroutine that normally takes 1 second to run. Sometimes, it can run infinitely. I want to move on in the code if the subroutine is taking too long (> 10 seconds) and ignore that run of that subroutine. Here is what I have so far using alarm.

use Win32::OLE;

eval { 
    local $SIG{ALRM} = sub { die "alarm\n" };
    alarm 10;                   # schedule alarm in 10 seconds 
    &do_the_subroutine;
    alarm 0;                    # cancel the alarm
};

if ($@) {
    $error_string .= $script;
    #Do something else if the subroutine took too long.
}

do_the_subroutine{
# use existing instance if Excel is already running
    eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')};
    die "Excel not installed" if $@;
    unless (defined $ex) {
        $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
                or die "Oops, cannot start Excel";
    }

    # get a new workbook
    $book = $ex->Workbooks->Add;

    # write to a particular cell
    $sheet = $book->Worksheets(1);
    $sheet->Cells(1,1)->{Value} = "foo";

    # write a 2 rows by 3 columns range
    $sheet->Range("A8:C9")->{Value} = [[ undef, 'Xyzzy', 'Plugh' ],
                                       [ 42,    'Perl',  3.1415  ]];

    # print "XyzzyPerl"
    $array = $sheet->Range("A8:C9")->{Value};
    for (@$array) {
        for (@$_) {
            print defined($_) ? "$_|" : "<undef>|";
        }
        print "\n";
    }

    # save and exit
    $book->SaveAs( 'test.xls' );
    undef $book;
    undef $ex;
}

&do_the_subroutine never returns so I'm not able to move on. I'm also not able to put this block of code inside that subroutine. Any thoughts?

like image 208
ansario Avatar asked Jul 28 '15 15:07

ansario


1 Answers

I suspect that what you want to do is simply not natively possible with alarm on Windows.

From perldoc perlport:

alarm Emulated using timers that must be explicitly polled whenever Perl wants to dispatch "safe signals" and therefore cannot interrupt blocking system calls. (Win32)

like image 89
dpw Avatar answered Sep 29 '22 01:09

dpw