#pike __REAL_VERSION__ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void create(int t) |
{ |
delay = t; |
#ifndef __NT__ |
#if constant(alarm) |
signal(signum("SIGALRM"), alarm_alarm_alarm); |
#endif |
signal(signum("SIGQUIT"), print_debug); |
#endif |
update_watchdog(); |
} |
|
|
|
|
|
void set_delay( int t ) |
{ |
delay = t; |
} |
|
protected object backend_thread = this_thread(); |
protected int delay, last_seen; |
protected int expected_cpu_time; |
protected array(function(void:void)) debug_funcs = ({}); |
protected array(function(void:bool)) probes = ({}); |
|
|
|
void print_debug() |
{ |
|
|
object threads_disabled = _disable_threads(); |
gc(); |
|
Stdio.stderr.write("### Describing all Pike threads:\n\n"); |
int n; |
foreach( all_threads(), Thread.Thread t ) |
{ |
array bt = t->backtrace(); |
Stdio.stderr.write("### Thread %O%s:\n", |
t, t == backend_thread ? " (backend thread)" : ""); |
Stdio.stderr.write(describe_backtrace(bt) + "\n"); |
n++; |
} |
|
Stdio.stderr.write("Total %d Pike threads\n", n); |
|
gc(); |
Stdio.stderr.write("\nMemory usage:\n\n"); |
Stdio.stderr.write(Debug.pp_memory_usage()+"\n"); |
|
gc(); |
Stdio.stderr.write(Debug.pp_object_usage()+"\n"); |
|
#if constant(get_profiling_info) |
Debug.Profiling.display(); |
#endif |
|
foreach( debug_funcs, function f ) |
catch(f()); |
|
threads_disabled = 0; |
} |
|
|
|
void alarm_alarm_alarm() |
{ |
if( System.getrusage()->utime < expected_cpu_time && (time()-last_seen) < delay*2 ) |
{ |
float cpus = (System.getrusage()->utime - expected_cpu_time + (delay*900))/1000.0; |
|
Stdio.stderr.write("\n" |
"****************************************\n"); |
Stdio.stderr.write("** WATCHDOG PENDING. **\n"); |
Stdio.stderr.write("** Last activity %4d seconds ago **\n", time()-last_seen); |
Stdio.stderr.write("** %4.1f CPU seconds have been used **\n", cpus); |
Stdio.stderr.write("****************************************\n"); |
#if constant(alarm) |
alarm( 1 ); |
#endif |
} |
really_trigger_watchdog_promise(); |
} |
|
|
|
|
void really_trigger_watchdog_promise() |
{ |
Stdio.stderr.write("\n\n***************************************************\n"); |
Stdio.stderr.write("***************************************************\n"); |
Stdio.stderr.write("***** WATCHDOG TRIGGERED ****\n"); |
Stdio.stderr.write("***** Last activity %4d seconds ago ****\n", time()-last_seen); |
Stdio.stderr.write("***************************************************\n"); |
Stdio.stderr.write("***************************************************\n"); |
|
catch(print_debug()); |
_exit(1); |
} |
|
|
|
|
void add_debug( function(void:void) f ) |
{ |
debug_funcs += ({ f }); |
} |
|
|
|
|
void add_probe( function(void:bool) f ) |
{ |
probes += ({ f }); |
} |
|
|
|
|
|
|
void ping() |
{ |
if( (time()-last_seen) > delay/2.0 ) |
update_watchdog(); |
} |
|
protected void update_watchdog() |
{ |
last_seen = time(); |
call_out( update_watchdog, min(delay/2.0,2.0) ); |
|
|
expected_cpu_time = System.getrusage()->utime + delay*900; |
|
foreach( probes, function(void:bool) probe ) |
{ |
if( !probe() ) |
{ |
Stdio.stderr.write("%O did not return true.\n", probe); |
catch(really_trigger_watchdog_promise()); |
_exit(1); |
} |
} |
#if constant(alarm) |
alarm( delay ); |
#endif |
} |
|
|