~stacyharper/bonsai

4b6df95d582341ef75cee5b7c0473da5914dc982 — Stacy Harper 4 months ago b5093b5
chain delay and read delay child with the server
3 files changed, 35 insertions(+), 26 deletions(-)

M bonsai/tree/voyager.ha
M cmd/bonsaid/main.ha
M cmd/bonsaid/socket.ha
M bonsai/tree/voyager.ha => bonsai/tree/voyager.ha +3 -10
@@ 70,7 70,7 @@ fn voyager_forward_context_changed(
	trigger_delay_branch(voyager);
};

fn voyager_forward_available_branches(voyager: *voyager) void = {
export fn voyager_forward_available_branches(voyager: *voyager) void = {
	for (let i = 0z; i < len(voyager.available_branches); i += 1) {
		match(voyager.available_branches[i]) {
		case let context_branch: branch_context =>


@@ 106,7 106,7 @@ fn voyager_forward_available_branches(voyager: *voyager) void = {
	};
};

fn trigger_delay_branch(voyager: *voyager) void = {
export fn trigger_delay_branch(voyager: *voyager) void = {
	match (find_to_wait_branch_delay(voyager.available_branches)) {
	case let delay_branch: branch_delay =>
		run_branch_delay(voyager, delay_branch);


@@ 137,11 137,8 @@ fn run_branch_delay(voyager: *voyager, branch: branch_delay) void = {
	case let err: exec::error =>
		fmt::fatal("delay scheduling failed", exec::strerror(err));
	case let child_pid: int =>
		io::close(wait_pipes.1)!;
		voyager.wait_pid = child_pid;
	case void =>
		io::close(wait_pipes.0)!;

		signal::unblock(signal::SIGINT, signal::SIGTERM);

		time::sleep(branch.delay_duration);


@@ 154,7 151,6 @@ fn run_branch_delay(voyager: *voyager, branch: branch_delay) void = {
		write_tree(wait_pipes.1, voyager.available_branches);

		fmt::fprintln(wait_pipes.1)!;
		io::close(wait_pipes.1)!;

		os::exit(0);
	};


@@ 171,7 167,7 @@ fn voyager_restart(voyager: *voyager) bool = {
};

// kill wait forked process and get back it results
fn sync_back_wait_child(voyager: *voyager, abort_it: bool) bool = {
export fn sync_back_wait_child(voyager: *voyager, abort_it: bool) bool = {
	if (voyager.wait_pid == 0) {
		return false;
	};


@@ 213,10 209,7 @@ fn sync_back_wait_child(voyager: *voyager, abort_it: bool) bool = {
		};
	};

	io::close(wait_pipes.0)!;

	voyager.wait_pid = 0;
	voyager.wait_pipes = void;

	return true;
};

M cmd/bonsaid/main.ha => cmd/bonsaid/main.ha +4 -5
@@ 57,17 57,16 @@ export fn main() void = {
	const sigfd = signal::signalfd(signal::SIGINT, signal::SIGTERM)!;
	defer io::close(sigfd)!;

	const server = bind(sigfd, daemonize);

	server.branches = branches;
	server.voyager = tree::voyager {
	let voyager = tree::voyager {
		tree = branches,
		available_branches = branches,
		context_elements = [],
		wait_pid = 0,
		wait_pipes = void,
		wait_pipes = unix::pipe(unix::pipe_flag::NONBLOCK)!,
	};

	const server = bind(sigfd, daemonize, voyager);

	if (daemonize) {
		match (exec::fork()) {
		case let err: exec::error =>

M cmd/bonsaid/socket.ha => cmd/bonsaid/socket.ha +28 -11
@@ 14,11 14,12 @@ use strings;
use unix::poll::{event};
use unix::poll;
use unix::signal;
use unix;
use bonsai::tree;

def CLIENT_MAXBUF: size = 16777216; // 16 MiB
def MAX_CLIENTS: size = 256;
def POLLFD_RESERVED: size = 2;
def POLLFD_RESERVED: size = 3;

type server = struct {
	sock: net::socket,


@@ 30,13 31,13 @@ type server = struct {
	daemonized: bool,
	terminate: bool,

	branches: []tree::branch,
	voyager: tree::voyager,
};

fn bind(
	signalfd: io::file,
	daemonize: bool,
	voyager: tree::voyager
) server = {
	const statedir = match (dirs::runtime()) {
	case let err: fs::error =>


@@ 56,21 57,31 @@ fn bind(
	};
	os::chmod(sockpath, 0o700)!;

	let pollfd = alloc([poll::pollfd {
		fd = sock,
		events = event::POLLIN,
		...
	}, poll::pollfd {
		fd = signalfd,
		events = event::POLLIN,
		...
	}]);
	let wait_pipes = voyager.wait_pipes as (io::file, io::file);
	let pollfd = alloc([
		poll::pollfd {
			fd = sock,
			events = event::POLLIN,
			...
		},
		poll::pollfd {
			fd = signalfd,
			events = event::POLLIN,
			...
		},
		poll::pollfd {
			fd = wait_pipes.1,
			events = event::POLLOUT,
			...
		}
	]);

	return server {
		signalfd = signalfd,
		pollfd = pollfd,
		daemonized = daemonize,
		sock = sock,
		voyager = voyager,
		...
	};
};


@@ 105,6 116,12 @@ fn dispatch(serv: *server) bool = {
			signal::read(serv.signalfd)!;
			return false;
		};
		if (serv.pollfd[2].revents & event::POLLOUT != 0) {
			if (tree::sync_back_wait_child(&serv.voyager, false)) {
				tree::voyager_forward_available_branches(&serv.voyager);
				tree::trigger_delay_branch(&serv.voyager);
			};
		};
		for (let i = POLLFD_RESERVED; i < len(serv.pollfd); i += 1) {
			dispatch_client(serv, &serv.clients[i - POLLFD_RESERVED]);
			if (serv.disconnected) {