From 97828a8e4e297a5bf64bb58d92bf4deee2159887 Mon Sep 17 00:00:00 2001 From: Julian Smith Date: Thu, 18 Feb 2021 23:12:01 +0000 Subject: [PATCH] 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. --- simgear/io/HTTPFileRequest.cxx | 11 ++++++----- simgear/io/HTTPFileRequest.hxx | 15 +++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/simgear/io/HTTPFileRequest.cxx b/simgear/io/HTTPFileRequest.cxx index 018e06da..22b25b16 100644 --- a/simgear/io/HTTPFileRequest.cxx +++ b/simgear/io/HTTPFileRequest.cxx @@ -26,13 +26,13 @@ namespace simgear { namespace HTTP { - //---------------------------------------------------------------------------- FileRequest::FileRequest(const std::string& url, const std::string& path, bool append): Request(url, "GET"), _filename(path), _append(append), - _callback() + _callback(nullptr), + _callback_ref(nullptr) { if (append && _filename.isFile()) { size_t size = _filename.sizeInBytes(); @@ -45,9 +45,10 @@ namespace HTTP } } - void FileRequest::setCallback(std::function callback) + void FileRequest::setCallback(Callback callback, void* ref) { _callback = callback; + _callback_ref = ref; } //---------------------------------------------------------------------------- @@ -115,7 +116,7 @@ namespace HTTP _file.write(s, n); if (_callback) { - _callback(s, n); + _callback(_callback_ref, s, n); } } @@ -124,7 +125,7 @@ namespace HTTP { _file.close(); if (_callback) { - _callback(nullptr, 0); + _callback(_callback_ref, nullptr, 0); } } diff --git a/simgear/io/HTTPFileRequest.hxx b/simgear/io/HTTPFileRequest.hxx index 94ebecf2..3c9c463e 100644 --- a/simgear/io/HTTPFileRequest.hxx +++ b/simgear/io/HTTPFileRequest.hxx @@ -53,16 +53,23 @@ namespace HTTP FileRequest(const std::string& url, const std::string& path, bool append=false); /* - * Set callback for each chunk of data we receive. Called with (nullptr, - * 0) when download has completed (successfully or unsuccesfully). + * Function pointer type for use with setCallback(). */ - void setCallback(std::function 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: SGPath _filename; sg_ofstream _file; bool _append; - std::function _callback; + Callback _callback; + void* _callback_ref; virtual void responseHeadersComplete(); virtual void gotBodyData(const char* s, int n);