forked from mitchellh/zig-libuv
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
22,239 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
zig-cache/ | ||
zig-out/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "vendor/libuv"] | ||
path = vendor/libuv | ||
url = https://github.com/libuv/libuv.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
const std = @import("std"); | ||
|
||
/// Directories with our includes. | ||
const root = thisDir() ++ "/vendor/libuv/"; | ||
const include_path = root ++ "include"; | ||
|
||
pub const pkg = std.build.Pkg{ | ||
.name = "libuv", | ||
.source = .{ .path = thisDir() ++ "/src/main.zig" }, | ||
}; | ||
|
||
fn thisDir() []const u8 { | ||
return std.fs.path.dirname(@src().file) orelse "."; | ||
} | ||
|
||
pub fn build(b: *std.build.Builder) !void { | ||
const target = b.standardTargetOptions(.{}); | ||
const optimize = b.standardOptimizeOption(.{}); | ||
|
||
const tests = b.addTest(.{ | ||
.name = "pixman-test", | ||
.kind = .test_exe, | ||
.root_source_file = .{ .path = "src/main.zig" }, | ||
.target = target, | ||
.optimize = optimize, | ||
}); | ||
_ = try link(b, tests); | ||
tests.install(); | ||
|
||
const test_step = b.step("test", "Run tests"); | ||
const tests_run = tests.run(); | ||
test_step.dependOn(&tests_run.step); | ||
} | ||
|
||
pub fn link(b: *std.build.Builder, step: *std.build.LibExeObjStep) !*std.build.LibExeObjStep { | ||
const libuv = try buildLibuv(b, step); | ||
step.linkLibrary(libuv); | ||
step.addIncludePath(include_path); | ||
return libuv; | ||
} | ||
|
||
pub fn buildLibuv( | ||
b: *std.build.Builder, | ||
step: *std.build.LibExeObjStep, | ||
) !*std.build.LibExeObjStep { | ||
const target = step.target; | ||
const lib = b.addStaticLibrary(.{ | ||
.name = "uv", | ||
.target = target, | ||
.optimize = step.optimize, | ||
}); | ||
|
||
// Include dirs | ||
lib.addIncludePath(include_path); | ||
lib.addIncludePath(root ++ "src"); | ||
|
||
// Links | ||
if (target.isWindows()) { | ||
lib.linkSystemLibrary("psapi"); | ||
lib.linkSystemLibrary("user32"); | ||
lib.linkSystemLibrary("advapi32"); | ||
lib.linkSystemLibrary("iphlpapi"); | ||
lib.linkSystemLibrary("userenv"); | ||
lib.linkSystemLibrary("ws2_32"); | ||
} | ||
if (target.isLinux()) { | ||
lib.linkSystemLibrary("pthread"); | ||
} | ||
lib.linkLibC(); | ||
|
||
// Compilation | ||
var flags = std.ArrayList([]const u8).init(b.allocator); | ||
defer flags.deinit(); | ||
// try flags.appendSlice(&.{}); | ||
|
||
if (!target.isWindows()) { | ||
try flags.appendSlice(&.{ | ||
"-D_FILE_OFFSET_BITS=64", | ||
"-D_LARGEFILE_SOURCE", | ||
}); | ||
} | ||
|
||
if (target.isLinux()) { | ||
try flags.appendSlice(&.{ | ||
"-D_GNU_SOURCE", | ||
"-D_POSIX_C_SOURCE=200112", | ||
}); | ||
} | ||
|
||
if (target.isDarwin()) { | ||
try flags.appendSlice(&.{ | ||
"-D_DARWIN_UNLIMITED_SELECT=1", | ||
"-D_DARWIN_USE_64_BIT_INODE=1", | ||
}); | ||
} | ||
|
||
// C files common to all platforms | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/fs-poll.c", | ||
root ++ "src/idna.c", | ||
root ++ "src/inet.c", | ||
root ++ "src/random.c", | ||
root ++ "src/strscpy.c", | ||
root ++ "src/strtok.c", | ||
root ++ "src/threadpool.c", | ||
root ++ "src/timer.c", | ||
root ++ "src/uv-common.c", | ||
root ++ "src/uv-data-getter-setters.c", | ||
root ++ "src/version.c", | ||
}, flags.items); | ||
|
||
if (!target.isWindows()) { | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/async.c", | ||
root ++ "src/unix/core.c", | ||
root ++ "src/unix/dl.c", | ||
root ++ "src/unix/fs.c", | ||
root ++ "src/unix/getaddrinfo.c", | ||
root ++ "src/unix/getnameinfo.c", | ||
root ++ "src/unix/loop-watcher.c", | ||
root ++ "src/unix/loop.c", | ||
root ++ "src/unix/pipe.c", | ||
root ++ "src/unix/poll.c", | ||
root ++ "src/unix/process.c", | ||
root ++ "src/unix/random-devurandom.c", | ||
root ++ "src/unix/signal.c", | ||
root ++ "src/unix/stream.c", | ||
root ++ "src/unix/tcp.c", | ||
root ++ "src/unix/thread.c", | ||
root ++ "src/unix/tty.c", | ||
root ++ "src/unix/udp.c", | ||
}, flags.items); | ||
} | ||
|
||
if (target.isLinux() or target.isDarwin()) { | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/proctitle.c", | ||
}, flags.items); | ||
} | ||
|
||
if (target.isLinux()) { | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/linux.c", | ||
root ++ "src/unix/procfs-exepath.c", | ||
root ++ "src/unix/random-getrandom.c", | ||
root ++ "src/unix/random-sysctl-linux.c", | ||
}, flags.items); | ||
} | ||
|
||
if (target.isDarwin() or | ||
target.isOpenBSD() or | ||
target.isNetBSD() or | ||
target.isFreeBSD() or | ||
target.isDragonFlyBSD()) | ||
{ | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/bsd-ifaddrs.c", | ||
root ++ "src/unix/kqueue.c", | ||
}, flags.items); | ||
} | ||
|
||
if (target.isDarwin() or target.isOpenBSD()) { | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/random-getentropy.c", | ||
}, flags.items); | ||
} | ||
|
||
if (target.isDarwin()) { | ||
lib.addCSourceFiles(&.{ | ||
root ++ "src/unix/darwin-proctitle.c", | ||
root ++ "src/unix/darwin.c", | ||
root ++ "src/unix/fsevents.c", | ||
}, flags.items); | ||
} | ||
|
||
return lib; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
//! Async handles allow the user to “wakeup” the event loop and get a callback | ||
//! called from another thread. | ||
const Async = @This(); | ||
|
||
const std = @import("std"); | ||
const Allocator = std.mem.Allocator; | ||
const testing = std.testing; | ||
const c = @import("c.zig"); | ||
const errors = @import("error.zig"); | ||
const Loop = @import("Loop.zig"); | ||
const Handle = @import("handle.zig").Handle; | ||
|
||
handle: *c.uv_async_t, | ||
|
||
pub usingnamespace Handle(Async); | ||
|
||
pub fn init(alloc: Allocator, loop: Loop, comptime cb: fn (*Async) void) !Async { | ||
var handle = try alloc.create(c.uv_async_t); | ||
errdefer alloc.destroy(handle); | ||
|
||
const Wrapper = struct { | ||
pub fn callback(arg: [*c]c.uv_async_t) callconv(.C) void { | ||
var newSelf: Async = .{ .handle = arg }; | ||
@call(.always_inline, cb, .{&newSelf}); | ||
} | ||
}; | ||
|
||
try errors.convertError(c.uv_async_init(loop.loop, handle, Wrapper.callback)); | ||
return Async{ .handle = handle }; | ||
} | ||
|
||
pub fn deinit(self: *Async, alloc: Allocator) void { | ||
alloc.destroy(self.handle); | ||
self.* = undefined; | ||
} | ||
|
||
/// Wake up the event loop and call the async handle’s callback. | ||
pub fn send(self: Async) !void { | ||
try errors.convertError(c.uv_async_send(self.handle)); | ||
} | ||
|
||
test "Async" { | ||
var loop = try Loop.init(testing.allocator); | ||
defer loop.deinit(testing.allocator); | ||
var h = try init(testing.allocator, loop, (struct { | ||
fn callback(v: *Async) void { | ||
v.close(null); | ||
} | ||
}).callback); | ||
defer h.deinit(testing.allocator); | ||
|
||
try h.send(); | ||
_ = try loop.run(.default); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//! Condition variables implemented via libuv. | ||
const Cond = @This(); | ||
|
||
const std = @import("std"); | ||
const Allocator = std.mem.Allocator; | ||
const testing = std.testing; | ||
const c = @import("c.zig"); | ||
const errors = @import("error.zig"); | ||
const Mutex = @import("Mutex.zig"); | ||
|
||
cond: *c.uv_cond_t, | ||
|
||
pub fn init(alloc: Allocator) !Cond { | ||
const cond = try alloc.create(c.uv_cond_t); | ||
try errors.convertError(c.uv_cond_init(cond)); | ||
return Cond{ .cond = cond }; | ||
} | ||
|
||
pub fn deinit(self: *Cond, alloc: Allocator) void { | ||
c.uv_cond_destroy(self.cond); | ||
alloc.destroy(self.cond); | ||
self.* = undefined; | ||
} | ||
|
||
pub fn signal(self: Cond) void { | ||
c.uv_cond_signal(self.cond); | ||
} | ||
|
||
pub fn broadcast(self: Cond) void { | ||
c.uv_cond_broadcast(self.cond); | ||
} | ||
|
||
pub fn wait(self: Cond, mutex: Mutex) void { | ||
c.uv_cond_wait(self.cond, mutex.mutex); | ||
} | ||
|
||
pub fn timedwait(self: Cond, mutex: Mutex, timeout: u64) c_int { | ||
return c.uv_cond_timedwait(self.cond, mutex.mutex, timeout); | ||
} | ||
|
||
test { | ||
var cond = try init(testing.allocator); | ||
defer cond.deinit(testing.allocator); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
//! Idle handles will run the given callback once per loop iteration, right | ||
//! before the uv_prepare_t handles. | ||
const Idle = @This(); | ||
|
||
const std = @import("std"); | ||
const Allocator = std.mem.Allocator; | ||
const testing = std.testing; | ||
const c = @import("c.zig"); | ||
const errors = @import("error.zig"); | ||
const Loop = @import("Loop.zig"); | ||
const Handle = @import("handle.zig").Handle; | ||
|
||
handle: *c.uv_idle_t, | ||
|
||
pub usingnamespace Handle(Idle); | ||
|
||
pub fn init(alloc: Allocator, loop: Loop) !Idle { | ||
var handle = try alloc.create(c.uv_idle_t); | ||
errdefer alloc.destroy(handle); | ||
|
||
try errors.convertError(c.uv_idle_init(loop.loop, handle)); | ||
return Idle{ .handle = handle }; | ||
} | ||
|
||
pub fn deinit(self: *Idle, alloc: Allocator) void { | ||
alloc.destroy(self.handle); | ||
self.* = undefined; | ||
} | ||
|
||
/// Start the handle with the given callback. This function always succeeds, | ||
/// except when cb is NULL. | ||
pub fn start(self: Idle, comptime cb: fn (*Idle) void) !void { | ||
const Wrapper = struct { | ||
pub fn callback(arg: [*c]c.uv_idle_t) callconv(.C) void { | ||
var newSelf: Idle = .{ .handle = arg }; | ||
@call(.always_inline, cb, .{&newSelf}); | ||
} | ||
}; | ||
|
||
try errors.convertError(c.uv_idle_start(self.handle, Wrapper.callback)); | ||
} | ||
|
||
/// Stop the handle, the callback will no longer be called. | ||
pub fn stop(self: Idle) !void { | ||
try errors.convertError(c.uv_idle_stop(self.handle)); | ||
} | ||
|
||
test "Idle" { | ||
var loop = try Loop.init(testing.allocator); | ||
defer loop.deinit(testing.allocator); | ||
var h = try init(testing.allocator, loop); | ||
defer h.deinit(testing.allocator); | ||
|
||
var called: bool = false; | ||
h.setData(&called); | ||
try h.start((struct { | ||
fn callback(t: *Idle) void { | ||
t.getData(bool).?.* = true; | ||
t.close(null); | ||
} | ||
}).callback); | ||
|
||
_ = try loop.run(.default); | ||
|
||
try testing.expect(called); | ||
} |
Oops, something went wrong.