Fix LIBPROTOBUF_PROTOBUF annotations for buliding protobuf as DLLs.

This commit is contained in:
Feng Xiao 2014-12-09 17:05:10 -08:00
parent 496d47c27f
commit 8d5d7cc6d0
8 changed files with 33 additions and 18 deletions

View File

@ -38,7 +38,14 @@ namespace google {
namespace protobuf {
google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_;
#ifdef PROTOBUF_USE_DLLS
Arena::ThreadCache& Arena::thread_cache() {
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL };
return thread_cache_;
}
#else
GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL };
#endif
void Arena::Init(const ArenaOptions& options) {
lifecycle_id_ = lifecycle_id_generator_.GetNext();
@ -130,18 +137,18 @@ void* Arena::AllocateAligned(size_t n) {
// If this thread already owns a block in this arena then try to use that.
// This fast path optimizes the case where multiple threads allocate from the
// same arena.
if (thread_cache_.last_lifecycle_id_seen == lifecycle_id_ &&
thread_cache_.last_block_used_ != NULL) {
if (thread_cache_.last_block_used_->avail() < n) {
if (thread_cache().last_lifecycle_id_seen == lifecycle_id_ &&
thread_cache().last_block_used_ != NULL) {
if (thread_cache().last_block_used_->avail() < n) {
return SlowAlloc(n);
}
return AllocFromBlock(thread_cache_.last_block_used_, n);
return AllocFromBlock(thread_cache().last_block_used_, n);
}
// Check whether we own the last accessed block on this arena.
// This fast path optimizes the case where a single thread uses multiple
// arenas.
void* me = &thread_cache_;
void* me = &thread_cache();
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_));
if (!b || b->owner != me || b->avail() < n) {
// If the next block to allocate from is the first block, try to claim it
@ -169,7 +176,7 @@ void* Arena::AllocFromBlock(Block* b, size_t n) {
}
void* Arena::SlowAlloc(size_t n) {
void* me = &thread_cache_;
void* me = &thread_cache();
Block* b = FindBlock(me); // Find block owned by me.
// See if allocation fits in my latest block.
if (b != NULL && b->avail() >= n) {

View File

@ -312,7 +312,12 @@ class LIBPROTOBUF_EXPORT Arena {
static const size_t kHeaderSize = sizeof(Block);
static google::protobuf::internal::SequenceNumber lifecycle_id_generator_;
#ifdef PROTOBUF_USE_DLLS
static ThreadCache& thread_cache();
#else
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
#endif
// SFINAE for skipping addition to delete list for a Type. This is mainly to
// skip proto2/proto1 message objects with cc_enable_arenas=true from being
@ -434,8 +439,8 @@ class LIBPROTOBUF_EXPORT Arena {
void CleanupList();
inline void SetThreadCacheBlock(Block* block) {
thread_cache_.last_block_used_ = block;
thread_cache_.last_lifecycle_id_seen = lifecycle_id_;
thread_cache().last_block_used_ = block;
thread_cache().last_lifecycle_id_seen = lifecycle_id_;
}
int64 lifecycle_id_; // Unique for each arena. Changes on Reset().

View File

@ -53,7 +53,7 @@ namespace google {
namespace protobuf {
namespace internal {
struct ArenaStringPtr {
struct LIBPROTOBUF_EXPORT ArenaStringPtr {
inline void Set(const ::std::string* default_value,
const ::std::string& value, ::google::protobuf::Arena* arena) {
if (ptr_ == default_value) {

View File

@ -153,6 +153,7 @@ TEST(GeneratedMessageTest, Defaults) {
&message.optional_import_message());
}
#ifndef PROTOBUF_USE_DLLS
TEST(GeneratedMessageTest, Int32StringConversion) {
EXPECT_EQ("971", Int32ToString(971));
EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min));
@ -165,6 +166,7 @@ TEST(GeneratedMessageTest, Int64StringConversion) {
EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min));
EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max));
}
#endif // !PROTOBUF_USE_DLLS
TEST(GeneratedMessageTest, FloatingPointDefaults) {
const unittest::TestExtremeDefaultValues& extreme_default =

View File

@ -110,7 +110,7 @@ class Map {
~Map() { clear(); }
// Iterators
class LIBPROTOBUF_EXPORT const_iterator
class const_iterator
: public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
const value_type*, const value_type&> {
typedef typename hash_map<Key, value_type*>::const_iterator InnerIt;
@ -139,7 +139,7 @@ class Map {
InnerIt it_;
};
class LIBPROTOBUF_EXPORT iterator : public std::iterator<std::forward_iterator_tag, value_type> {
class iterator : public std::iterator<std::forward_iterator_tag, value_type> {
typedef typename hash_map<Key, value_type*>::iterator InnerIt;
public:
@ -302,7 +302,7 @@ class Map {
template <typename K, typename V, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum>
friend class LIBPROTOBUF_EXPORT internal::MapField;
friend class internal::MapField;
};
} // namespace protobuf

View File

@ -45,7 +45,7 @@ namespace internal {
// Register all MapEntry default instances so we can delete them in
// ShutdownProtobufLibrary().
void RegisterMapEntryDefaultInstance(MessageLite* default_instance);
void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(MessageLite* default_instance);
// This is the common base class for MapEntry. It is used by MapFieldBase in
// reflection api, in which the static type of key and value is unknown.
@ -84,7 +84,7 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
// Moreover, default_enum_value is used to initialize enum field in proto2.
template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType,
FieldDescriptor::Type ValueProtoType, int default_enum_value>
class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
class MapEntry : public MapEntryBase {
// Handlers for key/value's proto field type. Used to infer internal layout
// and provide parsing/serialization support.
typedef MapProtoTypeHandler<KeyProtoType> KeyProtoHandler;
@ -363,7 +363,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
template <typename KeyNested, typename ValueNested,
FieldDescriptor::Type KeyProtoNested,
FieldDescriptor::Type ValueProtoNested, int default_enum>
class LIBPROTOBUF_EXPORT MapEntryWrapper
class MapEntryWrapper
: public MapEntry<KeyNested, ValueNested, KeyProtoNested,
ValueProtoNested, default_enum> {
typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
@ -394,7 +394,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
template <typename KeyNested, typename ValueNested,
FieldDescriptor::Type KeyProtoNested,
FieldDescriptor::Type ValueProtoNested, int default_enum>
class LIBPROTOBUF_EXPORT MapEnumEntryWrapper
class MapEnumEntryWrapper
: public MapEntry<KeyNested, ValueNested, KeyProtoNested,
ValueProtoNested, default_enum> {
typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
@ -433,7 +433,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
template <typename K, typename V,
FieldDescriptor::Type KType,
FieldDescriptor::Type VType, int default_enum>
friend class LIBPROTOBUF_EXPORT internal::MapField;
friend class internal::MapField;
friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);

View File

@ -137,7 +137,7 @@ class LIBPROTOBUF_EXPORT MapFieldBase {
template<typename Key, typename T,
FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value = 0>
class LIBPROTOBUF_EXPORT MapField : public MapFieldBase {
class MapField : public MapFieldBase {
// Handlers for key/value's proto field type.
typedef MapProtoTypeHandler<KeyProto> KeyProtoHandler;
typedef MapProtoTypeHandler<ValueProto> ValueProtoHandler;

View File

@ -967,6 +967,7 @@ const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
const Message& message, const FieldDescriptor* field) const; \
\
template<> \
LIBPROTOBUF_EXPORT \
RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
Message* message, const FieldDescriptor* field) const;