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

Reply via email to