scheduler: Make sleep cancellable
This commit is contained in:
+27
-1
@@ -428,6 +428,7 @@ fn writeFile(node: *Node, file: File, offset: ?usize, header: []const u8, data:
|
|||||||
return node.writeFile(file.handle, offset, header, data) catch |err| switch (err) {
|
return node.writeFile(file.handle, offset, header, data) catch |err| switch (err) {
|
||||||
error.InvalidHandle => error.NotOpenForWriting,
|
error.InvalidHandle => error.NotOpenForWriting,
|
||||||
error.OutOfMemory => error.SystemResources,
|
error.OutOfMemory => error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,6 +468,7 @@ fn dirCreateDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissio
|
|||||||
Node.CreateDirError.ComponentNotDirectory => Dir.CreateDirError.NotDir,
|
Node.CreateDirError.ComponentNotDirectory => Dir.CreateDirError.NotDir,
|
||||||
Node.CreateDirError.ComponentNotFound => Dir.CreateDirError.FileNotFound,
|
Node.CreateDirError.ComponentNotFound => Dir.CreateDirError.FileNotFound,
|
||||||
Node.CreateDirError.OutOfMemory => Dir.CreateDirError.SystemResources,
|
Node.CreateDirError.OutOfMemory => Dir.CreateDirError.SystemResources,
|
||||||
|
Node.CreateDirError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -506,6 +508,7 @@ fn dirOpenDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Di
|
|||||||
Node.OpenDirError.ResolutionLimit => Dir.OpenError.NameTooLong,
|
Node.OpenDirError.ResolutionLimit => Dir.OpenError.NameTooLong,
|
||||||
Node.OpenDirError.ComponentNotDirectory => Dir.OpenError.NotDir,
|
Node.OpenDirError.ComponentNotDirectory => Dir.OpenError.NotDir,
|
||||||
Node.OpenDirError.ComponentNotFound => Dir.OpenError.FileNotFound,
|
Node.OpenDirError.ComponentNotFound => Dir.OpenError.FileNotFound,
|
||||||
|
Node.OpenDirError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -551,6 +554,7 @@ fn dirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: D
|
|||||||
Node.CreateFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
Node.CreateFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
||||||
Node.CreateFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
Node.CreateFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
||||||
Node.CreateFileError.OutOfMemory => File.OpenError.SystemResources,
|
Node.CreateFileError.OutOfMemory => File.OpenError.SystemResources,
|
||||||
|
Node.CreateFileError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -566,6 +570,7 @@ fn dirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: D
|
|||||||
Node.OpenFileError.ResolutionLimit => File.OpenError.NameTooLong,
|
Node.OpenFileError.ResolutionLimit => File.OpenError.NameTooLong,
|
||||||
Node.OpenFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
Node.OpenFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
||||||
Node.OpenFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
Node.OpenFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
||||||
|
Node.OpenFileError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -601,6 +606,7 @@ fn dirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: Dir
|
|||||||
Node.OpenFileError.ResolutionLimit => File.OpenError.NameTooLong,
|
Node.OpenFileError.ResolutionLimit => File.OpenError.NameTooLong,
|
||||||
Node.OpenFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
Node.OpenFileError.ComponentNotDirectory => File.OpenError.NotDir,
|
||||||
Node.OpenFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
Node.OpenFileError.ComponentNotFound => File.OpenError.FileNotFound,
|
||||||
|
Node.OpenFileError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -628,6 +634,7 @@ fn dirRead(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Read
|
|||||||
if (dr.state == .reset) {
|
if (dr.state == .reset) {
|
||||||
node.resetDir(dr.dir.handle) catch |e| switch (e) {
|
node.resetDir(dr.dir.handle) catch |e| switch (e) {
|
||||||
error.InvalidHandle => return Dir.Reader.Error.AccessDenied,
|
error.InvalidHandle => return Dir.Reader.Error.AccessDenied,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
dr.state = .reading;
|
dr.state = .reading;
|
||||||
}
|
}
|
||||||
@@ -636,6 +643,7 @@ fn dirRead(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Read
|
|||||||
while (count < buffer.len) {
|
while (count < buffer.len) {
|
||||||
const entry = node.readDir(dr.dir.handle) catch |e| switch (e) {
|
const entry = node.readDir(dr.dir.handle) catch |e| switch (e) {
|
||||||
error.InvalidHandle => return Dir.Reader.Error.AccessDenied,
|
error.InvalidHandle => return Dir.Reader.Error.AccessDenied,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
error.NoMoreItems => {
|
error.NoMoreItems => {
|
||||||
dr.state = .finished;
|
dr.state = .finished;
|
||||||
return count;
|
return count;
|
||||||
@@ -686,6 +694,7 @@ fn dirDeleteFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.Dele
|
|||||||
Node.DeleteFileError.ComponentNotFound => Dir.DeleteFileError.FileNotFound,
|
Node.DeleteFileError.ComponentNotFound => Dir.DeleteFileError.FileNotFound,
|
||||||
Node.DeleteFileError.NotFound => Dir.DeleteFileError.FileNotFound,
|
Node.DeleteFileError.NotFound => Dir.DeleteFileError.FileNotFound,
|
||||||
Node.DeleteFileError.IsDirectory => Dir.DeleteFileError.IsDir,
|
Node.DeleteFileError.IsDirectory => Dir.DeleteFileError.IsDir,
|
||||||
|
Node.DeleteFileError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -706,6 +715,7 @@ fn dirDeleteDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.Delet
|
|||||||
Node.DeleteDirError.NotFound => Dir.DeleteDirError.FileNotFound,
|
Node.DeleteDirError.NotFound => Dir.DeleteDirError.FileNotFound,
|
||||||
Node.DeleteDirError.NotDirectory => Dir.DeleteDirError.NotDir,
|
Node.DeleteDirError.NotDirectory => Dir.DeleteDirError.NotDir,
|
||||||
Node.DeleteDirError.DirNotEmpty => Dir.DeleteDirError.DirNotEmpty,
|
Node.DeleteDirError.DirNotEmpty => Dir.DeleteDirError.DirNotEmpty,
|
||||||
|
Node.DeleteDirError.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -807,6 +817,7 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {
|
|||||||
const node: *Node = @ptrCast(@alignCast(userdata.?));
|
const node: *Node = @ptrCast(@alignCast(userdata.?));
|
||||||
return node.fileSize(file.handle) catch |e| switch (e) {
|
return node.fileSize(file.handle) catch |e| switch (e) {
|
||||||
error.InvalidHandle => File.LengthError.Streaming,
|
error.InvalidHandle => File.LengthError.Streaming,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,6 +844,7 @@ fn fileWritePositional(
|
|||||||
const written = node.writeFile(file.handle, cursor, header, &.{}) catch |err| switch (err) {
|
const written = node.writeFile(file.handle, cursor, header, &.{}) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
||||||
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
||||||
copied += written;
|
copied += written;
|
||||||
@@ -845,6 +857,7 @@ fn fileWritePositional(
|
|||||||
const written = node.writeFile(file.handle, cursor, bytes, &.{}) catch |err| switch (err) {
|
const written = node.writeFile(file.handle, cursor, bytes, &.{}) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
||||||
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
||||||
copied += written;
|
copied += written;
|
||||||
@@ -857,6 +870,7 @@ fn fileWritePositional(
|
|||||||
const written = node.writeFile(file.handle, cursor, pattern, &.{}) catch |err| switch (err) {
|
const written = node.writeFile(file.handle, cursor, pattern, &.{}) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
error.InvalidHandle => return File.WritePositionalError.NotOpenForWriting,
|
||||||
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
error.OutOfMemory => return File.WritePositionalError.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
cursor = std.math.add(usize, cursor, written) catch return File.WritePositionalError.FileTooBig;
|
||||||
copied += written;
|
copied += written;
|
||||||
@@ -893,6 +907,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: File, data: []const []u8, off
|
|||||||
const bytes_read = node.readFile(file.handle, @intCast(offset + copied), buffer) catch |e| {
|
const bytes_read = node.readFile(file.handle, @intCast(offset + copied), buffer) catch |e| {
|
||||||
return switch (e) {
|
return switch (e) {
|
||||||
error.InvalidHandle => File.ReadPositionalError.NotOpenForReading,
|
error.InvalidHandle => File.ReadPositionalError.NotOpenForReading,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
copied += bytes_read;
|
copied += bytes_read;
|
||||||
@@ -907,6 +922,7 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
|
|||||||
node.seekFileBy(file.handle, offset) catch |err| switch (err) {
|
node.seekFileBy(file.handle, offset) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return File.SeekError.AccessDenied,
|
error.InvalidHandle => return File.SeekError.AccessDenied,
|
||||||
error.NegativeOffset, error.Overflow => return File.SeekError.Unseekable,
|
error.NegativeOffset, error.Overflow => return File.SeekError.Unseekable,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -916,6 +932,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!voi
|
|||||||
node.seekFileTo(file.handle, offset_usize) catch |err| switch (err) {
|
node.seekFileTo(file.handle, offset_usize) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return File.SeekError.AccessDenied,
|
error.InvalidHandle => return File.SeekError.AccessDenied,
|
||||||
error.NegativeOffset, error.Overflow => return File.SeekError.Unseekable,
|
error.NegativeOffset, error.Overflow => return File.SeekError.Unseekable,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,7 +1184,7 @@ fn sleep(userdata: ?*anyopaque, timeout: Timeout) Cancelable!void {
|
|||||||
if (delta_us == 0)
|
if (delta_us == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node.sleep(delta_us);
|
try node.sleep(delta_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random(userdata: ?*anyopaque, buffer: []u8) void {
|
fn random(userdata: ?*anyopaque, buffer: []u8) void {
|
||||||
@@ -1219,6 +1236,7 @@ fn netListenIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: ne
|
|||||||
error.AddressNotAvailable => return error.AddressUnavailable,
|
error.AddressNotAvailable => return error.AddressUnavailable,
|
||||||
error.AddressAlreadyUsed => return error.AddressInUse,
|
error.AddressAlreadyUsed => return error.AddressInUse,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
@@ -1236,6 +1254,7 @@ fn netAccept(userdata: ?*anyopaque, listen_handle: net.Socket.Handle, options: n
|
|||||||
error.InvalidHandle => return error.SocketNotListening,
|
error.InvalidHandle => return error.SocketNotListening,
|
||||||
error.AcceptQueueEmpty => return error.WouldBlock,
|
error.AcceptQueueEmpty => return error.WouldBlock,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
@@ -1267,6 +1286,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n
|
|||||||
error.UnavailableHost => return error.HostUnreachable,
|
error.UnavailableHost => return error.HostUnreachable,
|
||||||
error.PeerNotListeningOnAddress => return error.ConnectionRefused,
|
error.PeerNotListeningOnAddress => return error.ConnectionRefused,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
@@ -1304,6 +1324,7 @@ fn netSend(userdata: ?*anyopaque, handle: net.Socket.Handle, messages: []net.Out
|
|||||||
error.InvalidHandle => return .{ error.SocketUnconnected, index },
|
error.InvalidHandle => return .{ error.SocketUnconnected, index },
|
||||||
error.NotConnected => return .{ error.SocketUnconnected, index },
|
error.NotConnected => return .{ error.SocketUnconnected, index },
|
||||||
error.OutOfMemory => return .{ error.SystemResources, index },
|
error.OutOfMemory => return .{ error.SystemResources, index },
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
message.data_len = written;
|
message.data_len = written;
|
||||||
}
|
}
|
||||||
@@ -1323,6 +1344,7 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea
|
|||||||
const block = (copied == 0);
|
const block = (copied == 0);
|
||||||
const n = node.readSocket(fd, buffer, block) catch |e| switch (e) {
|
const n = node.readSocket(fd, buffer, block) catch |e| switch (e) {
|
||||||
error.InvalidHandle => return error.SocketUnconnected,
|
error.InvalidHandle => return error.SocketUnconnected,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
@@ -1345,6 +1367,7 @@ fn netWrite(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8
|
|||||||
error.InvalidHandle => return error.SocketUnconnected,
|
error.InvalidHandle => return error.SocketUnconnected,
|
||||||
error.NotConnected => return error.SocketUnconnected,
|
error.NotConnected => return error.SocketUnconnected,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (data.len != 0) {
|
if (data.len != 0) {
|
||||||
@@ -1355,6 +1378,7 @@ fn netWrite(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8
|
|||||||
error.InvalidHandle => return error.SocketUnconnected,
|
error.InvalidHandle => return error.SocketUnconnected,
|
||||||
error.NotConnected => return error.SocketUnconnected,
|
error.NotConnected => return error.SocketUnconnected,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1366,6 +1390,7 @@ fn netWrite(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8
|
|||||||
error.InvalidHandle => return error.SocketUnconnected,
|
error.InvalidHandle => return error.SocketUnconnected,
|
||||||
error.NotConnected => return error.SocketUnconnected,
|
error.NotConnected => return error.SocketUnconnected,
|
||||||
error.OutOfMemory => return error.SystemResources,
|
error.OutOfMemory => return error.SystemResources,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1396,6 +1421,7 @@ fn netShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.Shutdo
|
|||||||
|
|
||||||
node.closeSocket(handle) catch |err| switch (err) {
|
node.closeSocket(handle) catch |err| switch (err) {
|
||||||
error.InvalidHandle => return error.SocketUnconnected,
|
error.InvalidHandle => return error.SocketUnconnected,
|
||||||
|
error.Canceled => @panic("TODO"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+61
-43
@@ -135,8 +135,8 @@ pub fn processInit(self: *Node) std.process.Init {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(self: *Node, delta_us: u64) void {
|
pub fn sleep(self: *Node, delta_us: u64) !void {
|
||||||
self.scheduler.sleep(delta_us);
|
return self.scheduler.sleep(delta_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(self: *Node, entry: NestedEntryPoint, context: *const anyopaque) !TaskID {
|
pub fn spawn(self: *Node, entry: NestedEntryPoint, context: *const anyopaque) !TaskID {
|
||||||
@@ -183,6 +183,10 @@ const HandleError = error {
|
|||||||
InvalidHandle,
|
InvalidHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const CancelError = error {
|
||||||
|
Canceled,
|
||||||
|
};
|
||||||
|
|
||||||
const NUM_SPECIAL_HANDLES = 3;
|
const NUM_SPECIAL_HANDLES = 3;
|
||||||
|
|
||||||
fn handleToDesc(self: *Node, handle: Handle) HandleError!*Descriptor {
|
fn handleToDesc(self: *Node, handle: Handle) HandleError!*Descriptor {
|
||||||
@@ -216,17 +220,19 @@ fn descToHandle(self: *Node, desc: *Descriptor) Handle {
|
|||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closeDir(self: *Node, handle: Handle) HandleError!void {
|
pub const CloseDirError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(10);
|
|
||||||
|
pub fn closeDir(self: *Node, handle: Handle) CloseDirError!void {
|
||||||
|
try self.scheduler.sleep(10);
|
||||||
const desc = try self.handleToDescOfType(handle, .dir);
|
const desc = try self.handleToDescOfType(handle, .dir);
|
||||||
self.file_system.closeDir(&desc.dir, self.gpa);
|
self.file_system.closeDir(&desc.dir, self.gpa);
|
||||||
desc.kind = .unused;
|
desc.kind = .unused;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CreateDirError = HandleError || FileSystem.CreateError;
|
pub const CreateDirError = HandleError || FileSystem.CreateError || CancelError;
|
||||||
|
|
||||||
pub fn createDir(self: *Node, parent: ?Handle, path: []const u8) CreateDirError!void {
|
pub fn createDir(self: *Node, parent: ?Handle, path: []const u8) CreateDirError!void {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
return self.file_system.createDir(
|
return self.file_system.createDir(
|
||||||
path,
|
path,
|
||||||
try self.handleToOpenDirOrNULL(parent),
|
try self.handleToOpenDirOrNULL(parent),
|
||||||
@@ -236,26 +242,28 @@ pub fn createDir(self: *Node, parent: ?Handle, path: []const u8) CreateDirError!
|
|||||||
|
|
||||||
pub const OpenDirError = error {
|
pub const OpenDirError = error {
|
||||||
DescriptorLimit,
|
DescriptorLimit,
|
||||||
} || HandleError || FileSystem.OpenError;
|
} || HandleError || FileSystem.OpenError || CancelError;
|
||||||
|
|
||||||
pub fn openDir(self: *Node, parent: ?Handle, path: []const u8) OpenDirError!Handle {
|
pub fn openDir(self: *Node, parent: ?Handle, path: []const u8) OpenDirError!Handle {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = self.unusedDesc() orelse return OpenDirError.DescriptorLimit;
|
const desc = self.unusedDesc() orelse return OpenDirError.DescriptorLimit;
|
||||||
try self.file_system.openDir(path, try self.handleToOpenDirOrNULL(parent), &desc.dir);
|
try self.file_system.openDir(path, try self.handleToOpenDirOrNULL(parent), &desc.dir);
|
||||||
desc.kind = .dir;
|
desc.kind = .dir;
|
||||||
return self.descToHandle(desc);
|
return self.descToHandle(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resetDir(self: *Node, handle: Handle) HandleError!void {
|
pub const ResetDirError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(2);
|
|
||||||
|
pub fn resetDir(self: *Node, handle: Handle) ResetDirError!void {
|
||||||
|
try self.scheduler.sleep(2);
|
||||||
const desc = try self.handleToDescOfType(handle, .dir);
|
const desc = try self.handleToDescOfType(handle, .dir);
|
||||||
self.file_system.resetDir(&desc.dir);
|
self.file_system.resetDir(&desc.dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ReadDirError = HandleError || FileSystem.ReadDirError;
|
pub const ReadDirError = HandleError || FileSystem.ReadDirError || CancelError;
|
||||||
|
|
||||||
pub fn readDir(self: *Node, handle: Handle) ReadDirError!FileSystem.ReadDir {
|
pub fn readDir(self: *Node, handle: Handle) ReadDirError!FileSystem.ReadDir {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = try self.handleToDescOfType(handle, .dir);
|
const desc = try self.handleToDescOfType(handle, .dir);
|
||||||
return self.file_system.readDir(&desc.dir);
|
return self.file_system.readDir(&desc.dir);
|
||||||
}
|
}
|
||||||
@@ -269,10 +277,10 @@ fn handleToOpenDirOrNULL(self: *Node, handle: ?Handle) HandleError!?*FileSystem.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CreateFileError = HandleError || FileSystem.CreateError;
|
pub const CreateFileError = HandleError || FileSystem.CreateError || CancelError;
|
||||||
|
|
||||||
pub fn createFile(self: *Node, parent: ?Handle, path: []const u8) CreateFileError!void {
|
pub fn createFile(self: *Node, parent: ?Handle, path: []const u8) CreateFileError!void {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
return self.file_system.createFile(
|
return self.file_system.createFile(
|
||||||
path,
|
path,
|
||||||
try self.handleToOpenDirOrNULL(parent),
|
try self.handleToOpenDirOrNULL(parent),
|
||||||
@@ -280,10 +288,10 @@ pub fn createFile(self: *Node, parent: ?Handle, path: []const u8) CreateFileErro
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DeleteFileError = HandleError || FileSystem.DeleteFileError;
|
pub const DeleteFileError = HandleError || FileSystem.DeleteFileError || CancelError;
|
||||||
|
|
||||||
pub fn deleteFile(self: *Node, parent: ?Handle, path: []const u8) DeleteFileError!void {
|
pub fn deleteFile(self: *Node, parent: ?Handle, path: []const u8) DeleteFileError!void {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
return self.file_system.deleteFile(
|
return self.file_system.deleteFile(
|
||||||
path,
|
path,
|
||||||
try self.handleToOpenDirOrNULL(parent),
|
try self.handleToOpenDirOrNULL(parent),
|
||||||
@@ -291,10 +299,10 @@ pub fn deleteFile(self: *Node, parent: ?Handle, path: []const u8) DeleteFileErro
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DeleteDirError = HandleError || FileSystem.DeleteDirError;
|
pub const DeleteDirError = HandleError || FileSystem.DeleteDirError || CancelError;
|
||||||
|
|
||||||
pub fn deleteDir(self: *Node, parent: ?Handle, path: []const u8) DeleteDirError!void {
|
pub fn deleteDir(self: *Node, parent: ?Handle, path: []const u8) DeleteDirError!void {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
return self.file_system.deleteDir(
|
return self.file_system.deleteDir(
|
||||||
path,
|
path,
|
||||||
try self.handleToOpenDirOrNULL(parent),
|
try self.handleToOpenDirOrNULL(parent),
|
||||||
@@ -304,31 +312,37 @@ pub fn deleteDir(self: *Node, parent: ?Handle, path: []const u8) DeleteDirError!
|
|||||||
|
|
||||||
pub const OpenFileError = error {
|
pub const OpenFileError = error {
|
||||||
DescriptorLimit,
|
DescriptorLimit,
|
||||||
} || HandleError || FileSystem.OpenError;
|
} || HandleError || FileSystem.OpenError || CancelError;
|
||||||
|
|
||||||
pub fn openFile(self: *Node, parent: ?Handle, path: []const u8) OpenFileError!Handle {
|
pub fn openFile(self: *Node, parent: ?Handle, path: []const u8) OpenFileError!Handle {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = self.unusedDesc() orelse return OpenFileError.DescriptorLimit;
|
const desc = self.unusedDesc() orelse return OpenFileError.DescriptorLimit;
|
||||||
try self.file_system.openFile(path, try self.handleToOpenDirOrNULL(parent), &desc.file);
|
try self.file_system.openFile(path, try self.handleToOpenDirOrNULL(parent), &desc.file);
|
||||||
desc.kind = .file;
|
desc.kind = .file;
|
||||||
return self.descToHandle(desc);
|
return self.descToHandle(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closeFile(self: *Node, handle: Handle) HandleError!void {
|
pub const CloseFileError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(10);
|
|
||||||
|
pub fn closeFile(self: *Node, handle: Handle) CloseFileError!void {
|
||||||
|
try self.scheduler.sleep(10);
|
||||||
const desc = try self.handleToDescOfType(handle, .file);
|
const desc = try self.handleToDescOfType(handle, .file);
|
||||||
self.file_system.closeFile(&desc.file, self.gpa);
|
self.file_system.closeFile(&desc.file, self.gpa);
|
||||||
desc.kind = .unused;
|
desc.kind = .unused;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fileSize(self: *Node, handle: Handle) HandleError!u64 {
|
pub const FileSizeError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(2);
|
|
||||||
|
pub fn fileSize(self: *Node, handle: Handle) FileSizeError!u64 {
|
||||||
|
try self.scheduler.sleep(2);
|
||||||
const desc = try self.handleToDescOfType(handle, .file);
|
const desc = try self.handleToDescOfType(handle, .file);
|
||||||
return @intCast(self.file_system.fileSize(&desc.file));
|
return @intCast(self.file_system.fileSize(&desc.file));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readFile(self: *Node, handle: Handle, offset: ?usize, target: []u8) HandleError!usize {
|
pub const ReadFileError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(100);
|
|
||||||
|
pub fn readFile(self: *Node, handle: Handle, offset: ?usize, target: []u8) ReadFileError!usize {
|
||||||
|
try self.scheduler.sleep(100);
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
@panic("Not implemented yet"); // TODO: stdin
|
@panic("Not implemented yet"); // TODO: stdin
|
||||||
} else if (handle == 1) {
|
} else if (handle == 1) {
|
||||||
@@ -355,7 +369,7 @@ fn writeToStderr(self: *Node, source: []const u8) void {
|
|||||||
self.stderr_writer.interface.flush() catch {};
|
self.stderr_writer.interface.flush() catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const WriteFileError = HandleError || Allocator.Error;
|
pub const WriteFileError = HandleError || Allocator.Error || CancelError;
|
||||||
|
|
||||||
pub fn writeFile(
|
pub fn writeFile(
|
||||||
self : *Node,
|
self : *Node,
|
||||||
@@ -365,7 +379,7 @@ pub fn writeFile(
|
|||||||
source: []const []const u8
|
source: []const []const u8
|
||||||
) WriteFileError!usize {
|
) WriteFileError!usize {
|
||||||
|
|
||||||
self.scheduler.sleep(100);
|
try self.scheduler.sleep(100);
|
||||||
|
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
return HandleError.InvalidHandle;
|
return HandleError.InvalidHandle;
|
||||||
@@ -400,16 +414,16 @@ pub fn writeFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const SeekFileError = HandleError || FileSystem.SeekError;
|
pub const SeekFileError = HandleError || FileSystem.SeekError || CancelError;
|
||||||
|
|
||||||
pub fn seekFileTo(self: *Node, handle: Handle, offset: usize) SeekFileError!void {
|
pub fn seekFileTo(self: *Node, handle: Handle, offset: usize) SeekFileError!void {
|
||||||
self.scheduler.sleep(2);
|
try self.scheduler.sleep(2);
|
||||||
const desc = try self.handleToDescOfType(handle, .file);
|
const desc = try self.handleToDescOfType(handle, .file);
|
||||||
self.file_system.seekFileTo(&desc.file, offset);
|
self.file_system.seekFileTo(&desc.file, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seekFileBy(self: *Node, handle: Handle, offset: i64) SeekFileError!void {
|
pub fn seekFileBy(self: *Node, handle: Handle, offset: i64) SeekFileError!void {
|
||||||
self.scheduler.sleep(2);
|
try self.scheduler.sleep(2);
|
||||||
const desc = try self.handleToDescOfType(handle, .file);
|
const desc = try self.handleToDescOfType(handle, .file);
|
||||||
try self.file_system.seekFileBy(&desc.file, offset);
|
try self.file_system.seekFileBy(&desc.file, offset);
|
||||||
}
|
}
|
||||||
@@ -417,10 +431,10 @@ pub fn seekFileBy(self: *Node, handle: Handle, offset: i64) SeekFileError!void {
|
|||||||
pub const Address = Network.Address;
|
pub const Address = Network.Address;
|
||||||
pub const ListenError = error {
|
pub const ListenError = error {
|
||||||
DescriptorLimit,
|
DescriptorLimit,
|
||||||
} || Network.ListenError;
|
} || Network.ListenError || CancelError;
|
||||||
|
|
||||||
pub fn listen(self: *Node, address: Address) ListenError!Handle {
|
pub fn listen(self: *Node, address: Address) ListenError!Handle {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = self.unusedDesc() orelse return ListenError.DescriptorLimit;
|
const desc = self.unusedDesc() orelse return ListenError.DescriptorLimit;
|
||||||
try self.network_host.listen(address, &desc.listen);
|
try self.network_host.listen(address, &desc.listen);
|
||||||
desc.kind = .listen;
|
desc.kind = .listen;
|
||||||
@@ -429,10 +443,10 @@ pub fn listen(self: *Node, address: Address) ListenError!Handle {
|
|||||||
|
|
||||||
pub const AcceptError = error {
|
pub const AcceptError = error {
|
||||||
DescriptorLimit,
|
DescriptorLimit,
|
||||||
} || HandleError || Network.AcceptError;
|
} || HandleError || Network.AcceptError || CancelError;
|
||||||
|
|
||||||
pub fn accept(self: *Node, handle: Handle) AcceptError!Handle {
|
pub fn accept(self: *Node, handle: Handle) AcceptError!Handle {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const old_desc = try self.handleToDescOfType(handle, .listen);
|
const old_desc = try self.handleToDescOfType(handle, .listen);
|
||||||
const new_desc = self.unusedDesc() orelse return AcceptError.DescriptorLimit;
|
const new_desc = self.unusedDesc() orelse return AcceptError.DescriptorLimit;
|
||||||
try self.network_host.accept(&old_desc.listen, &new_desc.conn);
|
try self.network_host.accept(&old_desc.listen, &new_desc.conn);
|
||||||
@@ -442,17 +456,19 @@ pub fn accept(self: *Node, handle: Handle) AcceptError!Handle {
|
|||||||
|
|
||||||
pub const ConnectError = error {
|
pub const ConnectError = error {
|
||||||
DescriptorLimit,
|
DescriptorLimit,
|
||||||
} || Network.ConnectError;
|
} || Network.ConnectError || CancelError;
|
||||||
|
|
||||||
pub fn connect(self: *Node, address: Address) ConnectError!Handle {
|
pub fn connect(self: *Node, address: Address) ConnectError!Handle {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = self.unusedDesc() orelse return ConnectError.DescriptorLimit;
|
const desc = self.unusedDesc() orelse return ConnectError.DescriptorLimit;
|
||||||
try self.network_host.connect(address, &desc.conn);
|
try self.network_host.connect(address, &desc.conn);
|
||||||
desc.kind = .conn;
|
desc.kind = .conn;
|
||||||
return self.descToHandle(desc);
|
return self.descToHandle(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readSocket(self: *Node, handle: Handle, target: []u8, block: bool) HandleError!usize {
|
pub const ReadSocketError = HandleError || CancelError;
|
||||||
|
|
||||||
|
pub fn readSocket(self: *Node, handle: Handle, target: []u8, block: bool) ReadSocketError!usize {
|
||||||
if (target.len == 0)
|
if (target.len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -460,7 +476,7 @@ pub fn readSocket(self: *Node, handle: Handle, target: []u8, block: bool) Handle
|
|||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
while (true) {
|
while (true) {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
|
|
||||||
const num = self.network_host.read(&desc.conn, target);
|
const num = self.network_host.read(&desc.conn, target);
|
||||||
|
|
||||||
@@ -478,16 +494,18 @@ pub fn readSocket(self: *Node, handle: Handle, target: []u8, block: bool) Handle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const WriteSocketError = HandleError || Network.SendError;
|
pub const WriteSocketError = HandleError || Network.SendError || CancelError;
|
||||||
|
|
||||||
pub fn writeSocket(self: *Node, handle: Handle, source: []const u8) WriteSocketError!usize {
|
pub fn writeSocket(self: *Node, handle: Handle, source: []const u8) WriteSocketError!usize {
|
||||||
self.scheduler.sleep(10);
|
try self.scheduler.sleep(10);
|
||||||
const desc = try self.handleToDescOfType(handle, .conn);
|
const desc = try self.handleToDescOfType(handle, .conn);
|
||||||
return self.network_host.send(&desc.conn, source);
|
return self.network_host.send(&desc.conn, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closeSocket(self: *Node, handle: Handle) HandleError!void {
|
pub const CloseSocketError = HandleError || CancelError;
|
||||||
self.scheduler.sleep(10);
|
|
||||||
|
pub fn closeSocket(self: *Node, handle: Handle) CloseSocketError!void {
|
||||||
|
try self.scheduler.sleep(10);
|
||||||
const desc = try self.handleToDesc(handle);
|
const desc = try self.handleToDesc(handle);
|
||||||
if (desc.kind == .conn) {
|
if (desc.kind == .conn) {
|
||||||
self.network_host.closeConnSocket(&desc.conn);
|
self.network_host.closeConnSocket(&desc.conn);
|
||||||
|
|||||||
+2
-1
@@ -316,13 +316,14 @@ fn taskReturned() callconv(.c) noreturn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called by the current task to return control to the scheduler
|
// Called by the current task to return control to the scheduler
|
||||||
pub fn sleep(self: *Scheduler, delta_us: u64) void {
|
pub fn sleep(self: *Scheduler, delta_us: u64) !void {
|
||||||
const current = self.findTaskByID(self.current_id.?).?;
|
const current = self.findTaskByID(self.current_id.?).?;
|
||||||
current.state = .blocked;
|
current.state = .blocked;
|
||||||
current.wakeup_time = self.current_time + delta_us;
|
current.wakeup_time = self.current_time + delta_us;
|
||||||
current.wakeup_tasks = null;
|
current.wakeup_tasks = null;
|
||||||
current.wakeup_futex = null;
|
current.wakeup_futex = null;
|
||||||
contextSwitch(¤t.regs, &self.regs);
|
contextSwitch(¤t.regs, &self.regs);
|
||||||
|
try self.checkCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn futexWait(self: *Scheduler, ptr: *const u32, expected: u32) void {
|
pub fn futexWait(self: *Scheduler, ptr: *const u32, expected: u32) void {
|
||||||
|
|||||||
Reference in New Issue
Block a user