Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,8 @@ common:alldebug --strategy=local
common:release --compilation_mode=opt
common:release --copt=-Ofast
common:release --@rules_zig//zig/settings:mode=release_safe

# --config=native builds everything optimized for the local CPU
common:native --copt=-march=native
common:native --@rules_zig//zig/settings:zigopt=-mcpu=native
common:native --@rules_rust//rust/settings:extra_rustc_flag=-Ctarget-cpu=native
36 changes: 18 additions & 18 deletions zml2/io/vfs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub const VFS = struct {
const ROOT_DIR_HANDLE: std.Io.Dir.Handle = 0;

allocator: std.mem.Allocator,
mutex: std.Thread.Mutex,
mutex: std.Io.Mutex,

backends: std.StringHashMapUnmanaged(std.Io),
// Maps virtual file and dir handles to backend handles
Expand Down Expand Up @@ -105,7 +105,7 @@ pub const VFS = struct {

return .{
.allocator = allocator,
.mutex = .{},
.mutex = .init,
.backends = .{},
.files = .{},
.dirs = .{},
Expand Down Expand Up @@ -133,15 +133,15 @@ pub const VFS = struct {
}

pub fn register(self: *VFS, scheme: []const u8, backend: std.Io) std.mem.Allocator.Error!void {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

try self.backends.put(self.allocator, scheme, backend);
}

pub fn unregister(self: *VFS, scheme: []const u8) bool {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

return self.backends.remove(scheme);
}
Expand All @@ -167,8 +167,8 @@ pub const VFS = struct {
.handle = handle,
};

self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

const virtual_handle = self.next_file_handle;
self.next_file_handle += 1;
Expand All @@ -179,9 +179,9 @@ pub const VFS = struct {
}

fn closeFile(self: *VFS, virtual_handle: std.Io.File.Handle) void {
self.mutex.lock();
self.mutex.lockUncancelable(self.base_io);
const entry = self.files.fetchRemove(virtual_handle);
self.mutex.unlock();
self.mutex.unlock(self.base_io);

if (entry) |kv| {
const fs_file = kv.value;
Expand All @@ -191,8 +191,8 @@ pub const VFS = struct {
}

fn fsFile(self: *VFS, virtual_handle: std.Io.File.Handle) FileEntryError!FsFile {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

const entry = self.files.get(virtual_handle) orelse return FileEntryError.MissingVirtualFileHandle;
return entry.*;
Expand All @@ -207,8 +207,8 @@ pub const VFS = struct {
.handle = handle,
};

self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

const virtual_handle = self.next_dir_handle;
self.next_dir_handle += 1;
Expand All @@ -220,9 +220,9 @@ pub const VFS = struct {
fn closeDir(self: *VFS, virtual_handle: std.Io.Dir.Handle) void {
if (virtual_handle == ROOT_DIR_HANDLE) return;

self.mutex.lock();
self.mutex.lockUncancelable(self.base_io);
const entry = self.dirs.fetchRemove(virtual_handle);
self.mutex.unlock();
self.mutex.unlock(self.base_io);

if (entry) |kv| {
const fs_dir = kv.value;
Expand All @@ -238,8 +238,8 @@ pub const VFS = struct {
return .{ .backend = backend, .handle = ROOT_DIR_HANDLE };
}

self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.base_io);
defer self.mutex.unlock(self.base_io);

const entry = self.dirs.get(virtual_handle) orelse return DirEntryError.MissingVirtualDirHandle;
return entry.*;
Expand Down
32 changes: 16 additions & 16 deletions zml2/io/vfs/hf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub const HF = struct {
file_handles: std.AutoHashMapUnmanaged(HandleId, *FileHandle),
dir_handles: std.AutoHashMapUnmanaged(HandleId, *DirHandle),
next_handle_id: HandleId,
mutex: std.Thread.Mutex,
mutex: std.Io.Mutex,
vtable: std.Io.VTable,

pub const HandleId = i32;
Expand Down Expand Up @@ -195,7 +195,7 @@ pub const HF = struct {
.file_handles = .{},
.dir_handles = .{},
.next_handle_id = 1,
.mutex = .{},
.mutex = .init,
.vtable = makeVTable(args.io),
};

Expand Down Expand Up @@ -232,54 +232,54 @@ pub const HF = struct {
}

fn allocateHandleId(self: *HF) HandleId {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const id = self.next_handle_id;
self.next_handle_id += 1;
return id;
}

fn registerFileHandle(self: *HF, handle: *FileHandle) std.mem.Allocator.Error!void {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

try self.file_handles.put(self.allocator, handle.id, handle);
}

fn unregisterFileHandle(self: *HF, id: HandleId) ?*FileHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const kv = self.file_handles.fetchRemove(id) orelse return null;
return kv.value;
}

fn getFileHandle(self: *HF, id: HandleId) ?*FileHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

return self.file_handles.get(id);
}

fn registerDirHandle(self: *HF, handle: *DirHandle) std.mem.Allocator.Error!void {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

try self.dir_handles.put(self.allocator, handle.id, handle);
}

fn unregisterDirHandle(self: *HF, id: HandleId) ?*DirHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const kv = self.dir_handles.fetchRemove(id) orelse return null;
return kv.value;
}

fn getDirHandle(self: *HF, id: HandleId) ?*DirHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());
return self.dir_handles.get(id);
}

Expand Down
95 changes: 37 additions & 58 deletions zml2/io/vfs/http.zig
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub const HTTP = struct {
};

allocator: std.mem.Allocator,
mutex: std.Thread.Mutex,
mutex: std.Io.Mutex,

file_handles: std.AutoHashMapUnmanaged(HandleId, *FileHandle),
dir_handles: std.AutoHashMapUnmanaged(HandleId, *DirHandle),
Expand All @@ -126,7 +126,7 @@ pub const HTTP = struct {
pub fn init(allocator: std.mem.Allocator, base_io: std.Io, http_client: *std.http.Client, config: Config) std.mem.Allocator.Error!HTTP {
var self: HTTP = .{
.allocator = allocator,
.mutex = .{},
.mutex = .init,
.file_handles = .{},
.dir_handles = .{},
.next_file_handle_id = 0,
Expand Down Expand Up @@ -170,8 +170,8 @@ pub const HTTP = struct {
}

fn registerFileHandle(self: *HTTP, handle: *FileHandle) std.mem.Allocator.Error!HandleId {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const handle_id = self.next_file_handle_id;
self.next_file_handle_id += 1;
Expand All @@ -182,15 +182,15 @@ pub const HTTP = struct {
}

fn fileHandle(self: *HTTP, file: std.Io.File) ?*FileHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

return self.file_handles.get(file.handle);
}

fn registerDirHandle(self: *HTTP, handle: *DirHandle) std.mem.Allocator.Error!HandleId {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const handle_id = self.next_dir_handle_id;
self.next_dir_handle_id += 1;
Expand All @@ -201,8 +201,8 @@ pub const HTTP = struct {
}

fn dirHandle(self: *HTTP, dir: std.Io.Dir) ?*DirHandle {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

return self.dir_handles.get(dir.handle);
}
Expand Down Expand Up @@ -253,8 +253,8 @@ pub const HTTP = struct {
}

fn closeDir(self: *HTTP, dir: std.Io.Dir) void {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const handle_kv = self.dir_handles.fetchRemove(dir.handle) orelse {
log.warn("Attempted to close non-existent dir handle: {d}", .{dir.handle});
Expand All @@ -265,8 +265,8 @@ pub const HTTP = struct {
}

fn closeFile(self: *HTTP, file: std.Io.File) void {
self.mutex.lock();
defer self.mutex.unlock();
self.mutex.lockUncancelable(self.io());
defer self.mutex.unlock(self.io());

const handle_kv = self.file_handles.fetchRemove(file.handle) orelse {
log.warn("Attempted to close non-existent file handle: {d}", .{file.handle});
Expand Down Expand Up @@ -318,31 +318,35 @@ pub const HTTP = struct {

var total_read: usize = 0;

log.debug("Starting HTTP read handle={d} pos={d} buffers={d} url={s}", .{ file.handle, handle.pos, data.len, handle.url });

for (data) |buf| {
log.debug(" buffer len={d}", .{buf.len});
}

for (data, 0..) |buf, buf_index| {
var offset: usize = 0;

while (offset < buf.len) {
const file_size = blk: {
if (handle.size) |size| break :blk size;

const stat = self.fetchFileStat(file) catch {
log.err("Failed to fetch file stat during read for handle={d} url={s}", .{ file.handle, handle.url });
return std.Io.File.Reader.Error.Unexpected;
};

handle.size = stat.size;

break :blk stat.size;
};

// Check EOF against known file size
if (handle.size) |size| {
if (handle.pos >= size) {
return total_read;
}
if (handle.pos >= file_size) {
return total_read;
}

var desired: u64 = 0;
for (data[buf_index..]) |b| desired += b.len;
desired -= offset;
const start = handle.pos;
var desired_read_len: u64 = @max(@as(u64, @intCast(buf.len)), self.config.request_range_min);
if (desired_read_len > self.config.request_range_max) desired_read_len = self.config.request_range_max;

if (desired < self.config.request_range_min) desired = self.config.request_range_min;
if (desired > self.config.request_range_max) desired = self.config.request_range_max;
const end = if (handle.size.? > 0 and start < file_size) @min(start + desired_read_len - 1, file_size - 1) else start + desired_read_len - 1;

try self.requestRead(file, desired);
try self.requestRead(file, start, end);
const reader = handle.body_reader.?;

const dest = buf[offset..];
Expand All @@ -359,43 +363,20 @@ pub const HTTP = struct {
},
};

if (n == 0) {
// log.debug("readVec returned 0 (no progress) handle={d} pos={d} buf_index={d} offset={d}", .{ file.handle, handle.pos, buf_index, offset });
continue;
}

// log.debug("readVec wrote {d} bytes for handle={d} pos(before)={d} buf_index={d} offset(before)={d}", .{ n, file.handle, handle.pos, buf_index, offset });

offset += n;
handle.pos += n;
total_read += n;
}
}

return total_read;
}

fn requestRead(self: *HTTP, file: std.Io.File, desired: u64) std.Io.File.Reader.Error!void {
fn requestRead(self: *HTTP, file: std.Io.File, start: u64, end: u64) std.Io.File.Reader.Error!void {
const handle = self.fileHandle(file) orelse return std.Io.File.Reader.Error.Unexpected;

if (handle.body_reader != null) return;

log.debug("Starting HTTP request lifecycle handle={d} pos={d} desired={d} url={s}", .{ file.handle, handle.pos, desired, handle.url });

if (handle.size == null) {
const stat = self.fetchFileStat(file) catch |err| {
log.err("Failed to fetch file stat during read: {}", .{err});
return std.Io.File.Reader.Error.SystemResources;
};
handle.size = stat.size;
}

const size = handle.size.?;

if (handle.pos >= size) return;
if (handle.request) |_| return;

const start = handle.pos;
const end = @min(start + desired, size) - 1;
std.debug.assert(start <= end);

var range_buf: [64]u8 = undefined;
const range_header = std.fmt.bufPrint(&range_buf, "bytes={d}-{d}", .{ start, end }) catch unreachable;
Expand Down Expand Up @@ -461,7 +442,6 @@ pub const HTTP = struct {
handle.request = request;
handle.response = response;
handle.body_reader = handle.response.?.reader(&.{});
log.debug("Initialized body_reader len={d} seek={d} for handle={s}", .{ handle.body_reader.?.buffer.len, handle.body_reader.?.seek, handle.url });
}

pub const FileStat = struct {
Expand Down Expand Up @@ -542,7 +522,6 @@ pub const HTTP = struct {
log.err("HTTP stat response missing Content-Length", .{});
return std.Io.File.StatError.SystemResources;
};
handle.size = size;

return .{
.inode = @intCast(file.handle),
Expand Down
Loading
Loading