Skip to content

[libcurl] Returning from a write callback with error does not immediately return from curl_easy_perform #4487

@Bylon2

Description

@Bylon2

The bug does NOT occur on x86/amd64 version, but is visible on armV7 (Raspbian Buster 32 bits on Raspberry Pi 4)

I have a fuse driver using libcurl underneath : https://gitlab.com/BylonAkila/astreamfs/blob/master/1fichierfs.c

What it does is read chunks of file as instructed in background process (read-ahead stream optimised). When no read request arrives, the background processes are just sleeping inside the curl callback.
In the case a request arrives out of the currently opened streams, we pick a sleeping process, terminate the current curl operation (sending CURLE_WRITE_ERROR from the callback) and start a new curl_easy_perform with the new range.

What is expected:

So what can happen in the background:

  • curl_easy_perform (range offset-end_of_file)
    -- callback read bytes and return them, when no more bytes are needed we sit in the callback
    -- wait for some time
    -- A new request arrives and we need to reuse that thread, so we send the new range to it (with semaphores), the callback then returns CURLE_WRITE_ERROR to terminate the current stream-read
  • on x86, curl_easy_perform IMMEDIATELY terminates (with error 23 as expected) and returns to the caller. The caller will then start a new curl_easy_perform with the new range.

What happens instead

And that is specific to armhf 32 bits apparently, is that in spite of the callback returning CURLE_WRITE_ERROR, curl_easy_perform does not return immediately to its caller. The return delay to the caller, after curl_easy_perform receives the error code from the callback can be anything from zero to 3 minutes!

Versions

$ uname -a
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster

$ 1fichierfs -V
1fichierfs: version 1.5.0
libcurl/7.64.0 (arm-unknown-linux-gnueabihf) GnuTLS/3.6.7
FUSE library version: 2.9.9
fusermount version: 2.9.9
using FUSE kernel interface version 7.19

So the libcurl version is 7.64.0 with GnutTLS/3.6.7
(I need reentrance since it is mutlithreaded use)

TODO

I'll try to build a smaller program to demonstrate the bug, since it is impractical with this driver because you need a 1fichier.com subscription to use it.

In the mean time... if you have an idea where that comes from...

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions