Skip to content

Commit b67ed92

Browse files
author
Bret Ambrose
committed
Merge branch 'FB-AndroidStringBuf' of github.com:awslabs/aws-sdk-cpp-staging into FB-AndroidStringBuf
2 parents 0d39900 + c0126bd commit b67ed92

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ namespace Aws
2828
#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__)
2929

3030
/*
31-
using std::string with shared libraries is broken on android due to the platform-level decision to set _GLIBCXX_FULLY_DYNAMIC_STRING to 0
31+
using std::string with shared libraries is broken on android when using gnustl
32+
due to the platform-level decision to set _GLIBCXX_FULLY_DYNAMIC_STRING to 0
3233
3334
The problem:
3435
35-
(1) gnustl is the only usable c++11-compliant c++ standard library on Android; it is our only choice
36-
(2) _GLIBCXX_FULLY_DYNAMIC_STRING is set to 0 in Android's c++config.h for gnustl
37-
(3) The optimization that this enables is completely broken if using shared libraries and there is no way to opt out of using it.
36+
(1) _GLIBCXX_FULLY_DYNAMIC_STRING is set to 0 in Android's c++config.h for gnustl
37+
(2) The optimization that this enables is completely broken if using shared libraries and there is no way to opt out of using it.
3838
An optimization that uses a comparison to a static memory address is death for shared libraries.
3939
4040
Supposing you have a shared library B that depends on another shared library A. There are a variety of inocuous scenarios where you end up crashing
@@ -50,18 +50,28 @@ Lessons (with the empty string optimization forced on you):
5050
(1) You can't move std::strings across shared libraries (as a part of another class, Outcome in our case)
5151
(2) If you default initialize a std::string member variable, you can't have a mismatched constructor/destructor pair such that one is in a cpp file and the other
5252
is missing/implicit or defined in the header file
53-
54-
After much trouble, we have the following ghetto solution that has stopped all of the crashes so far without having to scour our entire codebase for every Lesson violation above:
53+
54+
Solutions:
55+
56+
Use libc++ rather than gnustl
57+
58+
For those who must use gnustl, we have provided a working solution by cobbling together a set of hacks:
5559
5660
We prevent the empty string optimization from ever being run on our strings by:
5761
(1) Make Aws::Allocator always fail equality checks with itself; this check is part of the empty string optimization in several std::basic_string constructors
5862
(2) All other cases are prevented by turning Aws::String into a subclass whose default constructor and move operations go to baseclass versions which will not
5963
perform the empty string optimization
6064
65+
Those changes prevent crashes, but lead to very poor performance when using a string stream; every character added will result in multiple copies of the entire
66+
string (ie, quadratic).
6167
62-
This does not prevent problems with Aws::StringBuf and Aws::StringStream. We do not appear to be violating any of the lessons with our usage of them though.
68+
To fix the performance problems, we have put together a set of replacement classes, SimpleStreamBuf and SimpleStringStream, that
69+
replace std::stringstream and std::stringbuf in SDK code. These replacements use raw buffers rather than strings in order to
70+
avoid the performance issues.
6371
72+
This solution is only enabled if using gnustl on Android. In all other situations, normal STL types are used.
6473
*/
74+
6575
using AndroidBasicString = std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > >;
6676

6777
class String : public AndroidBasicString

aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStringStream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace Aws
3434

3535
#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__)
3636

37+
// see the large comment block in AWSString.h for an explanation
3738
typedef Aws::SimpleStringStream StringStream;
3839
typedef Aws::SimpleIStringStream IStringStream;
3940
typedef Aws::SimpleOStringStream OStringStream;

0 commit comments

Comments
 (0)