Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi::perform() references a mysterious "info", which doesn't appear to exist – how to get the result for an individual #498

Open
nabijaczleweli opened this issue May 10, 2023 · 0 comments

Comments

@nabijaczleweli
Copy link
Contributor

Quoth https://docs.rs/curl/latest/curl/multi/struct.Multi.html#method.perform at 0.4.44:

If the amount of running handles is changed from the previous call (or is less than the amount of easy handles you’ve added to the multi handle), you know that there is one or more transfers less “running”. You can then call info to get information about each individual completed transfer, and that returned info includes Error and more. If an added handle fails very quickly, it may never be counted as a running handle.

and

This function only returns errors etc regarding the whole multi stack. Problems still might have occurred on individual transfers even when this function returns Ok. Use info to figure out how individual transfers did.

And yet!

curl-rust$ git grep '\binfo('
curl-rust$ git grep '\binfo<'
curl-rust$ git grep '\binfo:'
curl-sys/lib.rs:    pub fn curl_easy_getinfo(curl: *mut CURL, info: CURLINFO, ...) -> CURLcode;
src/easy/handler.rs:    /// More info: <https://curl.se/libcurl/c/CURLOPT_EXPECT_100_TIMEOUT_MS.html>

and rustdoc search unsurprisingly returns nothing as well.

Indeed, it appears I'm actually hitting this in nabijaczleweli/cargo-update#234 where response_code() returns 0, i.e. "no server response code has been received". To that end – how do I get the individual results?

https://curl.se/libcurl/c/curl_multi_perform.html says

This function returns errors regarding the whole multi stack. Problems on individual transfers may have occurred even when this function returns CURLM_OK. Use curl_multi_info_read to figure out how individual transfers did.

which is obviously what the rustdoc is copied from, and indeed

$ git grep curl_multi_info_read
curl-sys/lib.rs:    pub fn curl_multi_info_read(
src/multi.rs:                let ptr = curl_sys::curl_multi_info_read(self.raw.handle, &mut queue);

which is

    /// Read multi stack informationals
    ///
    /// Ask the multi handle if there are any messages/informationals from the
    /// individual transfers. Messages may include informationals such as an
    /// error code from the transfer or just the fact that a transfer is
    /// completed. More details on these should be written down as well.
    pub fn messages<F>(&self, mut f: F)
    where
        F: FnMut(Message),
    {
        self._messages(&mut f)
    }

    fn _messages(&self, f: &mut dyn FnMut(Message)) {
        let mut queue = 0;
        unsafe {
            loop {
                let ptr = curl_sys::curl_multi_info_read(self.raw.handle, &mut queue);
                if ptr.is_null() {
                    break;
                }
                f(Message { ptr, _multi: self })
            }
        }
    }

This had also confused me originally when using the multi API. To that end: instead of referencing a mystical "info", please just point to messages() :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant