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:
parent
f9ecf455ba
commit
97828a8e4e
@ -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<void(const void* data, size_t numbytes)> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<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:
|
||||
SGPath _filename;
|
||||
sg_ofstream _file;
|
||||
bool _append;
|
||||
std::function<void(const void* data, size_t numbytes)> _callback;
|
||||
Callback _callback;
|
||||
void* _callback_ref;
|
||||
|
||||
virtual void responseHeadersComplete();
|
||||
virtual void gotBodyData(const char* s, int n);
|
||||
|
Loading…
Reference in New Issue
Block a user