simgear/io/HTTPFileRequest.*: Use fnptr rather than std::function to avoid SEGVs with g++ on Linux.

Previous code sometimes gave a SEGV in _callback's destructor when
setCallback() was called; this is on Linux with g++-8.3.0. Have tried various
alternative ways to initialise _callback but the problem persistend.

So have switched to an old-style function-pointer plus void* approach.
This commit is contained in:
Julian Smith 2021-02-18 23:12:01 +00:00
parent f9ecf455ba
commit 97828a8e4e
2 changed files with 17 additions and 9 deletions

View File

@ -26,13 +26,13 @@ namespace simgear
{ {
namespace HTTP namespace HTTP
{ {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
FileRequest::FileRequest(const std::string& url, const std::string& path, bool append): FileRequest::FileRequest(const std::string& url, const std::string& path, bool append):
Request(url, "GET"), Request(url, "GET"),
_filename(path), _filename(path),
_append(append), _append(append),
_callback() _callback(nullptr),
_callback_ref(nullptr)
{ {
if (append && _filename.isFile()) { if (append && _filename.isFile()) {
size_t size = _filename.sizeInBytes(); size_t size = _filename.sizeInBytes();
@ -45,9 +45,10 @@ namespace HTTP
} }
} }
void FileRequest::setCallback(std::function<void(const void* data, size_t numbytes)> callback) void FileRequest::setCallback(Callback callback, void* ref)
{ {
_callback = callback; _callback = callback;
_callback_ref = ref;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -115,7 +116,7 @@ namespace HTTP
_file.write(s, n); _file.write(s, n);
if (_callback) { if (_callback) {
_callback(s, n); _callback(_callback_ref, s, n);
} }
} }
@ -124,7 +125,7 @@ namespace HTTP
{ {
_file.close(); _file.close();
if (_callback) { if (_callback) {
_callback(nullptr, 0); _callback(_callback_ref, nullptr, 0);
} }
} }

View File

@ -53,16 +53,23 @@ namespace HTTP
FileRequest(const std::string& url, const std::string& path, bool append=false); FileRequest(const std::string& url, const std::string& path, bool append=false);
/* /*
* Set callback for each chunk of data we receive. Called with (nullptr, * Function pointer type for use with setCallback().
* 0) when download has completed (successfully or unsuccesfully).
*/ */
void setCallback(std::function<void (const void* data, size_t numbytes)> callback); typedef void (*Callback)(void* ref, const void* data, size_t numbytes);
/*
* Set callback for each chunk of data we receive. Called with
* (ref, nullptr, 0) when download has completed (successfully or
* unsuccesfully).
*/
void setCallback(Callback callback, void* ref);
protected: protected:
SGPath _filename; SGPath _filename;
sg_ofstream _file; sg_ofstream _file;
bool _append; bool _append;
std::function<void(const void* data, size_t numbytes)> _callback; Callback _callback;
void* _callback_ref;
virtual void responseHeadersComplete(); virtual void responseHeadersComplete();
virtual void gotBodyData(const char* s, int n); virtual void gotBodyData(const char* s, int n);