Lindenii Project Forge
Login

hare-ev

Temporary fork of hare-ev for... reasons

Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.

/ev/+linux/poll.ha (raw)

use rt;

// A callback for a [[readable]] operation.
export type readablecb = fn(file: *file) (void | nomem);

// Executes the callback when a given file is readable. Cannot be combined with
// [[read]] or [[readv]].
export fn readable(
	file: *file,
	cb: *readablecb,
) (req  | nomem)= {
	assert(file.op & op::READABLE == 0 && file.op & op::READV == 0);
	if (file.flags & fflags::BLOCKING != 0) {
		cb(file)?;
		return req { ... };
	};

	file.op |= op::READABLE;
	file.cb = cb;
	file_epoll_ctl(file);
	return mkreq(&readable_cancel, file);
};

fn readable_ready(file: *file, ev: *rt::epoll_event) (void | nomem) = {
	assert(file.op & op::READABLE != 0);
	assert(file.cb != null);
	const cb = file.cb: *readablecb;
	file.op &= ~op::READABLE;
	file_epoll_ctl(file);
	cb(file)?;
};

fn readable_cancel(req: *req) void = {
	const file = req.user: *file;
	assert(file.op & op::READABLE != 0);
	file.op &= ~op::READABLE;
	file_epoll_ctl(file);
};

// A callback for a [[writable]] operation.
export type writablecb = fn(file: *file) (void | nomem);

// Executes the callback when a given file is writable. Cannot be combined with
// [[write]] or [[writev]].
export fn writable(
	file: *file,
	cb: *writablecb,
) (req  | nomem)= {
	assert(file.op & op::WRITABLE == 0 && file.op & op::WRITEV == 0);
	if (file.flags & fflags::BLOCKING != 0) {
		cb(file)?;
		return req { ... };
	};

	file.op |= op::WRITABLE;
	file.cb = cb;
	file_epoll_ctl(file);
	return mkreq(&writable_cancel, file);
};

fn writable_ready(file: *file, ev: *rt::epoll_event) (void | nomem) = {
	assert(file.op & op::WRITABLE != 0);
	assert(file.cb != null);
	const cb = file.cb: *writablecb;
	file.op &= ~op::WRITABLE;
	file_epoll_ctl(file);
	cb(file)?;
};

fn writable_cancel(req: *req) void = {
	const file = req.user: *file;
	assert(file.op & op::WRITABLE != 0);
	file.op &= ~op::WRITABLE;
	file_epoll_ctl(file);
};