diff options
author | 2021-12-30 21:12:32 -0800 | |
---|---|---|
committer | 2021-12-30 21:12:32 -0800 | |
commit | e75c711c68896f5952793601f156c921c814caab (patch) | |
tree | f3b30e2281c7231d480bb84503d17b2370866ff9 /src/network_thread.zig | |
parent | 8d031f13c0e04629d431176e211a31224b7618c0 (diff) | |
download | bun-e75c711c68896f5952793601f156c921c814caab.tar.gz bun-e75c711c68896f5952793601f156c921c814caab.tar.zst bun-e75c711c68896f5952793601f156c921c814caab.zip |
Upgrade to latest Zig, remove dependency on patched version of Zig (#96)
* Prepare to upgrade zig
* zig fmt
* AllocGate
* Update data_url.zig
* wip
* few files
* just headers now?
* I think everything works?
* Update mimalloc
* Update hash_map.zig
* Perf improvements to compensate for Allocgate
* Bump
* :camera:
* Update bun.lockb
* Less branching
* [js parser] Slightly reduce memory usage
* Update js_parser.zig
* WIP remove unused
* [JS parser] WIP support for `with` keyword
* Remove more dead code
* Fix all the build errors!
* cleanup
* Move `network_thread` up
* Bump peechy
* Update README.md
Diffstat (limited to 'src/network_thread.zig')
-rw-r--r-- | src/network_thread.zig | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/network_thread.zig b/src/network_thread.zig new file mode 100644 index 000000000..0f24e8f35 --- /dev/null +++ b/src/network_thread.zig @@ -0,0 +1,87 @@ +const ThreadPool = @import("thread_pool"); +pub const Batch = ThreadPool.Batch; +pub const Task = ThreadPool.Task; +const std = @import("std"); +const AsyncIO = @import("io"); +const Output = @import("./global.zig").Output; +const IdentityContext = @import("./identity_context.zig").IdentityContext; + +const NetworkThread = @This(); + +/// Single-thread in this pool +pool: ThreadPool, + +pub var global: NetworkThread = undefined; +pub var global_loaded: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0); + +const CachedAddressList = struct { + address_list: *std.net.AddressList, + expire_after: u64, + key: u64, + index: ?u32 = null, + invalidated: bool = false, + pub fn hash(name: []const u8, port: u16) u64 { + var hasher = std.hash.Wyhash.init(0); + hasher.update(name); + hasher.update(":"); + hasher.update(std.mem.asBytes(&port)); + return hasher.final(); + } + + pub fn init(key: u64, address_list: *std.net.AddressList, now: u64) CachedAddressList { + return CachedAddressList{ + .address_list = address_list, + .expire_after = now + std.time.ms_per_hour, + .key = key, + }; + } + + pub fn invalidate(this: *CachedAddressList) void { + this.invalidated = true; + this.address_list.deinit(); + _ = address_list_cached.remove(this.key); + } +}; + +const AddressListCache = std.HashMap(u64, CachedAddressList, IdentityContext(u64), 80); +var address_list_cached: AddressListCache = undefined; +pub fn getAddressList(allocator: std.mem.Allocator, name: []const u8, port: u16) !*CachedAddressList { + const hash = CachedAddressList.hash(name, port); + const now = @intCast(u64, @maximum(0, std.time.milliTimestamp())); + if (address_list_cached.getPtr(hash)) |cached| { + if (cached.expire_after > now) { + return cached; + } + + cached.address_list.deinit(); + } + + const address_list = try std.net.getAddressList(allocator, name, port); + var entry = try address_list_cached.getOrPut(hash); + entry.value_ptr.* = CachedAddressList.init(hash, address_list, now); + return entry.value_ptr; +} + +pub fn init() !void { + if ((global_loaded.swap(1, .Monotonic)) == 1) return; + AsyncIO.global = AsyncIO.init(1024, 0) catch |err| { + Output.prettyErrorln("<r><red>error<r>: Failed to initialize network thread: <red><b>{s}<r>.\nHTTP requests will not work. Please file an issue and run strace().", .{@errorName(err)}); + Output.flush(); + + global = NetworkThread{ + .pool = ThreadPool.init(.{ .max_threads = 0, .stack_size = 64 * 1024 * 1024 }), + }; + global.pool.max_threads = 0; + AsyncIO.global_loaded = true; + return; + }; + + AsyncIO.global_loaded = true; + + global = NetworkThread{ + .pool = ThreadPool.init(.{ .max_threads = 1, .stack_size = 64 * 1024 * 1024 }), + }; + + global.pool.io = &AsyncIO.global; + address_list_cached = AddressListCache.init(@import("./global.zig").default_allocator); +} |