Skip to content

Commit

Permalink
feat: init multi
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Jan 30, 2024
1 parent 424b8fd commit 504d540
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .fdignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/libs/curl
/libs/mbedtls
/libs/zlib
1 change: 1 addition & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn build(b: *Build) void {

try addExample(b, "basic", module, libcurl, target, optimize);
try addExample(b, "advanced", module, libcurl, target, optimize);
try addExample(b, "multi", module, libcurl, target, optimize);

const main_tests = b.addTest(.{
.root_source_file = .{ .path = "src/root.zig" },
Expand Down
35 changes: 35 additions & 0 deletions examples/multi.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const std = @import("std");
const println = @import("util.zig").println;
const mem = std.mem;
const Allocator = mem.Allocator;
const curl = @import("curl");
const Easy = curl.Easy;
const Multi = curl.Multi;
const c = curl.libcurl;

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

const easy = try Easy.init(allocator, .{});
try easy.set_url("http://httpbin.org/headers");
defer easy.deinit();

const multi = try Multi.init();
// defer multi.deinit();

try multi.addHandle(easy.handle);

var running = true;
const transfer = try multi.perform();
std.debug.print("num of transfer {any}\n", .{transfer});

while (running) {
const info = try multi.readInfo();
running = info.msgs_in_queue != 0;
try multi.removeHandle(info.msg.easy_handle.?);
c.curl_easy_cleanup(info.msg.easy_handle.?);
std.debug.print("{any}\n", .{info});
}
}
14 changes: 14 additions & 0 deletions src/errors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@ pub fn checkCode(code: c.CURLcode) !void {

return error.Unexpected;
}

pub fn checkMCode(code: c.CURLMcode) !void {
if (code == c.CURLM_OK) {
return;
}

// https://curl.se/libcurl/c/libcurl-errors.html
std.log.debug("curlm err code:{d}, msg:{s}\n", .{
code,
c.curl_multi_strerror(code),
});

return error.Unexpected;
}
64 changes: 64 additions & 0 deletions src/multi.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const std = @import("std");
const errors = @import("errors.zig");
const util = @import("util.zig");
const Easy = @import("easy.zig");
const c = util.c;

const mem = std.mem;
const fmt = std.fmt;
const Allocator = mem.Allocator;
const checkMCode = errors.checkMCode;
const Self = @This();

multi: *c.CURLM,

pub fn init() !Self {
const core = c.curl_multi_init();
if (core == null) {
return error.InitMulti;
}
return .{ .multi = core.? };
}

pub fn deinit() void {}

/// Adds the easy handle to the multi_handle.
/// https://curl.se/libcurl/c/curl_multi_add_handle.html
pub fn addHandle(self: Self, handle: *c.CURL) !void {
return checkMCode(c.curl_multi_add_handle(self.multi, handle));
}

/// Removes a given easy_handle from the multi_handle.
/// https://curl.se/libcurl/c/curl_multi_remove_handle.html
pub fn removeHandle(self: Self, handle: *c.CURL) !void {
return checkMCode(c.curl_multi_remove_handle(self.multi, handle));
}

/// This function performs transfers on all the added handles that need attention in a non-blocking fashion.
/// Returns the number of handles that still transfer data. When that reaches zero, all transfers are done.
/// https://curl.se/libcurl/c/curl_multi_perform.html
pub fn perform(self: Self) !c_int {
var still_running: c_int = undefined;
try checkMCode(c.curl_multi_perform(self.multi, &still_running));

return still_running;
}

const Info = struct {
msgs_in_queue: c_int,
msg: *c.CURLMsg,
};

pub fn readInfo(self: Self) !Info {
var msgs_in_queue: c_int = undefined;

const msg = c.curl_multi_info_read(self.multi, &msgs_in_queue);
if (msg == null) {
return error.OutOfStruct;
}

return Info{
.msg = msg.?,
.msgs_in_queue = msgs_in_queue,
};
}
1 change: 1 addition & 0 deletions src/root.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const util = @import("util.zig");
const checkCode = @import("errors.zig").checkCode;

pub const Easy = @import("easy.zig");
pub const Multi = @import("multi.zig");
pub const print_libcurl_version = util.print_libcurl_version;
pub const url_encode = util.url_encode;
pub const libcurl = util.c;
Expand Down

0 comments on commit 504d540

Please sign in to comment.