Re: Question about cancelling sub-routine



On 14 August 2010 00:41, muppet <scott asofyet org> wrote:

On Aug 12, 2010, at 11:07 PM, Mike Martin wrote:

This works

if ($append == 1){

die (main::encode_loop) if $count == 100; # this is a count as a test
- the loop goes from 1-150
}


but if I try to put it as the action for a cancel sub it fails silently


$widget{btn_cancel}->signal_connect('clicked', sub {

die (main::encode_loop)

      );

for info the above lines were consecutive

any suggestions


Need more context.  Is the loop you're trying to kill on the main thread, on a background thread, or a 
chain of idle events?  Does the btn_cancel callback run when clicked or wait to run until after the loop 
finishes?



very much on the main thread, after some pre-processing it runs

our $tag=  Glib::IO->add_watch ( fileno($file), ['in', 'hup'], sub {
                                        my ($fileno, $condition,$tag) = @_;
                                        if ($condition eq 'hup') {
                                        close $file;
                                        Gtk2->main_quit();
                                        return 0;
                                        }
                                        my $line ;

                                        sysread $file, $line, 256;

                                        if ($feedback_type eq '0'){
                                        $buffer->insert($buffer->get_end_iter,$line) if $subname ne 'gd'
and $subname ne 'gd_m';
                                        $widget{gtkend}->set_text($line)
                                        }

                                        return 1;
                                        }



As written, die() from a button callback is rather pointless.  That will cause the exception in the event 
handler, which will be caught and eaten (see old threads from '04 or so for why that is, and the faq [1] 
for some info on what it does).


I'll have a look

If the encode_loop you're trying to cancel is on the main thread, then most likely the callback doesn't run 
until after the encode_loop completes, because that loop is blocking the main thread.  You'd need to do 
"Gtk2->main_iteration while Gtk2->events_pending" on each iteration of your encode_loop to handle events 
and possibly catch the cancel button event.  The event would have to set a flag that the encode_loop checks 
because of the aforementioned die()-eating behavior.

If the encode_loop is on another thread, you'll have to poke a thread-shared variable that your other 
thread reads, or otherwise forcibly kill the other thread.



[1]: 
http://live.gnome.org/GTK2-Perl/FrequentlyAskedQuestions#My_app_doesn.27t_die_when_there.27s_a_problem_in_a_signal_callback.2C_I_just_get_some_strange_error_message.2C_what.27s_up_with_that.3F

--
Aw, my lemon is empty.
 -- Yvonne, at dinner



This is what I have done to "solve" the issue

I have a global variable called $sub_stop.

then code is

die (main::encode_loop) if $sub_stop == 1;

then button code is

$widget{btn_cancel}->signal_connect('clicked', sub {
$sub_stop=1; ## sets control variable to 1

if ($pid1 != 1){  ## to cope with when no ext programmes running when
there are no $pids ##
        kill (15,$pid1,$pid); ## clears up running external proc ##
                if (kill($pid1,$pid) !=0){
                                        kill (9,$pid1,$pid); ## deals with process when it does not die 
cleanly ##
                                        }
                                        }       
#$sub_stop=0;
                }
#



        );

($sub_stop is set to 0 when encode_loop is run)

This works



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]