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
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user