X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fio%2Fasync%2FEventBaseLocal.h;h=8e4bdce3b77b4b98bb6b90a75e47f84db07cb8ae;hp=334cb601e40ba651da14404a0b11868da07a5d66;hb=18de341f84035f76395347f77a8cc71d0461ab37;hpb=bb7d2e02389ad07f0e0eed82501e2c5152ea47ee diff --git a/folly/io/async/EventBaseLocal.h b/folly/io/async/EventBaseLocal.h index 334cb601..8e4bdce3 100644 --- a/folly/io/async/EventBaseLocal.h +++ b/folly/io/async/EventBaseLocal.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include namespace folly { @@ -31,13 +31,12 @@ namespace detail { class EventBaseLocalBase : public EventBaseLocalBaseBase, boost::noncopyable { public: EventBaseLocalBase() {} - virtual ~EventBaseLocalBase(); + ~EventBaseLocalBase() override; void erase(EventBase& evb); void onEventBaseDestruction(EventBase& evb) override; protected: void setVoid(EventBase& evb, std::shared_ptr&& ptr); - void setVoidUnlocked(EventBase& evb, std::shared_ptr&& ptr); void* getVoid(EventBase& evb); folly::Synchronized> eventBases_; @@ -45,7 +44,7 @@ class EventBaseLocalBase : public EventBaseLocalBaseBase, boost::noncopyable { uint64_t key_{keyCounter_++}; }; -} +} // namespace detail /** * A storage abstraction for data that should be tied to an EventBase. @@ -64,13 +63,14 @@ class EventBaseLocalBase : public EventBaseLocalBaseBase, boost::noncopyable { * Foo& foo = myFoo.getOrCreateFn(evb, [] () { return new Foo(3, 4); }) * * The objects will be deleted when the EventBaseLocal or the EventBase is - * destructed (whichever comes first). All methods are thread-safe. + * destructed (whichever comes first). All methods must be called from the + * EventBase thread. * * The user is responsible for throwing away invalid references/ptrs returned * by the get() method after set/erase is called. If shared ownership is * needed, use a EventBaseLocal>. */ -template +template class EventBaseLocal : public detail::EventBaseLocalBase { public: EventBaseLocal(): EventBaseLocalBase() {} @@ -84,25 +84,21 @@ class EventBaseLocal : public detail::EventBaseLocalBase { setVoid(evb, std::move(smartPtr)); } - template - void emplace(EventBase& evb, Args... args) { - auto smartPtr = std::make_shared(args...); + template + void emplace(EventBase& evb, Args&&... args) { + auto smartPtr = std::make_shared(std::forward(args)...); setVoid(evb, smartPtr); } - template - T& getOrCreate(EventBase& evb, Args... args) { - std::lock_guard lg(evb.localStorageMutex_); - - auto it2 = evb.localStorage_.find(key_); - if (LIKELY(it2 != evb.localStorage_.end())) { - return *static_cast(it2->second.get()); - } else { - auto smartPtr = std::make_shared(args...); - auto ptr = smartPtr.get(); - setVoidUnlocked(evb, std::move(smartPtr)); - return *ptr; + template + T& getOrCreate(EventBase& evb, Args&&... args) { + if (auto ptr = getVoid(evb)) { + return *static_cast(ptr); } + auto smartPtr = std::make_shared(std::forward(args)...); + auto& ref = *smartPtr; + setVoid(evb, std::move(smartPtr)); + return ref; } template @@ -110,19 +106,14 @@ class EventBaseLocal : public detail::EventBaseLocalBase { // If this looks like it's copy/pasted from above, that's because it is. // gcc has a bug (fixed in 4.9) that doesn't allow capturing variadic // params in a lambda. - std::lock_guard lg(evb.localStorageMutex_); - - auto it2 = evb.localStorage_.find(key_); - if (LIKELY(it2 != evb.localStorage_.end())) { - return *static_cast(it2->second.get()); - } else { - std::shared_ptr smartPtr(fn()); - auto ptr = smartPtr.get(); - setVoidUnlocked(evb, std::move(smartPtr)); - return *ptr; + if (auto ptr = getVoid(evb)) { + return *static_cast(ptr); } + std::shared_ptr smartPtr(fn()); + auto& ref = *smartPtr; + setVoid(evb, std::move(smartPtr)); + return ref; } }; - -} +} // namespace folly