use strict;
use warnings;

use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More tests => 1;

use threads;
use threads::shared;

sub reload {
    my @args = @_;
    my ($thread_num, $node) = @args;
    my $i = 1;
    $SIG{'KILL'} = sub { print("Thread killed on iteration $i.\n"); threads->exit(); };
    print("Thread $thread_num started\n");
    while (1) {
		$node->reload();
		$i++;
	}
}

sub shutdown_threads {
    my @args = @_;
    my (@threads) = @args;
    for my $thread (@threads) {
        if ($thread->is_running()) {
            $thread->kill('KILL')->detach;
        }
    }
    return;
}


my $node = PostgreSQL::Test::Cluster->new("node");
$node->init;
$node->start;

my $numthreads = 20;
my @threads;
foreach my $ti (1 .. $numthreads) {
    push @threads, threads->create('reload', $ti, $node);
}
my $max_duration = 100;

my $failed_threads = 0;
my $duration = 0;
while (1) {
    foreach my $ti (1 .. $numthreads) {
        my $thread = $threads[$ti - 1];
        if ($thread->is_joinable()) {
            my $result = $thread->join();
            $failed_threads += 1;
            diag("Thread $ti failed:\n$result");
        } elsif (!$thread->is_running()) {
            $failed_threads += 1;
            diag("Thread $ti is not running:\n");
        }
    }
    if ($failed_threads > 0) {
        last;
    }
    sleep(1);
    diag("$duration\n");
    $duration += 1;
    if ($duration >= $max_duration) {
        last;
    }
}

diag($failed_threads);
shutdown_threads(@threads);
ok($failed_threads == 0);
