Hello,
While upgrading compilers from GCC 4.7 to GCC 7.2 on an embedded device, I
noticed a substantial increase in memory usage while parsing a file upload
request.
This seems to be caused by changed behavior in std::string. As GCC 4.7 was
using copy-on-write and refcounting for std::string, a string copy did not
cause a copy of the data. Now with GCC 7.2, a string copy also copies the data.
For some large (+30MB) requests, this now makes our application go
out-of-memory on a embedded device with only 128MB of RAM.
To bring memory usage back to the GCC 4.7 values, I patched Cgicc::parseMIME to
std::move the data to the FormFile and FormEntry (see attached patch).
As this patch is using some C++ 11 features, I was wondering if you do accept
patches that (conditionally) use C++ 11 (or higher) features?
I could rework the patch to only use those features when supported by the
__cplusplus version.
Best Regards,
Dries
Secure your future - Meet Newtec
Dialog®<http://www.newtec.eu/product/newtec-dialog>, the platform that embraces
change - with award-winning Mx-DMA®<http://www.newtec.eu/technology/mx-dma>!
***mail confidentiality footer ***
This message and any attachments thereto are confidential. They may also be
privileged or otherwise protected by work product immunity or other legal
rules. If you have received it by mistake, please let us know by e-mail reply
and delete it from your system; you may not copy this message or disclose its
contents to anyone. E-mail transmission cannot be guaranteed to be secure or
error free as information could be intercepted, corrupted, lost, destroyed,
arrive late or incomplete, or contain viruses. The sender therefore is in no
way liable for any errors or omissions in the content of this message, which
may arise as a result of e-mail transmission. If verification is required,
please request a hard copy.
diff -urN cgicc.orig/Cgicc.cpp cgicc/Cgicc.cpp
--- cgicc.orig/Cgicc.cpp 2017-06-27 21:38:02.000000000 +0200
+++ cgicc/Cgicc.cpp 2018-03-26 08:30:13.507547000 +0200
@@ -497,10 +497,10 @@
MultipartHeader head = parseHeader(data.substr(0, valueStart));
if(head.getFilename().empty())
- fFormData.push_back(FormEntry(head.getName(), value));
+ fFormData.emplace_back(head.getName(), std::move(value));
else
- fFormFiles.push_back(FormFile(head.getName(),
+ fFormFiles.emplace_back(head.getName(),
head.getFilename(),
head.getContentType(),
- value));
+ std::move(value));
}
diff -urN cgicc.orig/FormEntry.h cgicc/FormEntry.h
--- cgicc.orig/FormEntry.h 2017-06-27 21:38:02.000000000 +0200
+++ cgicc/FormEntry.h 2018-03-26 08:29:15.767638000 +0200
@@ -97,6 +97,11 @@
const std::string& value)
: fName(name), fValue(value)
{}
+ inline
+ FormEntry(std::string&& name,
+ std::string&& value)
+ : fName(std::forward<std::string>(name)), fValue(std::forward<std::string>(value))
+ {}
/*!
* \brief Copy constructor.
diff -urN cgicc.orig/FormFile.cpp cgicc/FormFile.cpp
--- cgicc.orig/FormFile.cpp 2017-06-27 21:38:02.000000000 +0200
+++ cgicc/FormFile.cpp 2018-03-26 09:14:43.750957309 +0200
@@ -39,6 +39,17 @@
fDataType = dataType.empty() ? std::string("text/plain") : dataType;
}
+cgicc::FormFile::FormFile(std::string&& name,
+ std::string&& filename,
+ std::string&& dataType,
+ std::string&& data)
+ : fName(std::forward<std::string>(name)),
+ fFilename(std::forward<std::string>(filename)),
+ fData(std::forward<std::string>(data))
+{
+ fDataType = dataType.empty() ? std::string("text/plain") : dataType;
+}
+
bool
cgicc::FormFile::operator== (const FormFile& file) const
{
diff -urN cgicc.orig/FormFile.h cgicc/FormFile.h
--- cgicc.orig/FormFile.h 2017-06-27 21:38:02.000000000 +0200
+++ cgicc/FormFile.h 2018-03-26 08:59:01.813701000 +0200
@@ -92,6 +92,10 @@
const std::string& filename,
const std::string& dataType,
const std::string& data);
+ FormFile(std::string&& name,
+ std::string&& filename,
+ std::string&& dataType,
+ std::string&& data);
/*!
* \brief Copy constructor.
_______________________________________________
help-cgicc mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-cgicc