Add unit test for timeout=0
[folly.git] / folly / io / async / EventBaseManager.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/io/async/EventBaseManager.h>
18
19 namespace folly {
20
21 std::atomic<EventBaseManager*> globalManager(nullptr);
22
23 EventBaseManager* EventBaseManager::get() {
24   EventBaseManager* mgr = globalManager;
25   if (mgr) {
26     return mgr;
27   }
28
29   EventBaseManager* new_mgr = new EventBaseManager;
30   bool exchanged = globalManager.compare_exchange_strong(mgr, new_mgr);
31   if (!exchanged) {
32     delete new_mgr;
33     return mgr;
34   } else {
35     return new_mgr;
36   }
37
38 }
39
40 /*
41  * EventBaseManager methods
42  */
43
44 void EventBaseManager::setEventBase(EventBase *eventBase,
45                                      bool takeOwnership) {
46   EventBaseInfo *info = localStore_.get();
47   if (info != nullptr) {
48     throw std::runtime_error("EventBaseManager: cannot set a new EventBase "
49                              "for this thread when one already exists");
50   }
51
52   info = new EventBaseInfo(eventBase, takeOwnership);
53   localStore_.reset(info);
54   this->trackEventBase(eventBase);
55 }
56
57 void EventBaseManager::clearEventBase() {
58   EventBaseInfo *info = localStore_.get();
59   if (info != nullptr) {
60     this->untrackEventBase(info->eventBase);
61     this->localStore_.reset(nullptr);
62   }
63 }
64
65 // XXX should this really be "const"?
66 EventBase * EventBaseManager::getEventBase() const {
67   // have one?
68   auto *info = localStore_.get();
69   if (! info) {
70     info = new EventBaseInfo();
71     localStore_.reset(info);
72
73     if (observer_) {
74       info->eventBase->setObserver(observer_);
75     }
76
77     // start tracking the event base
78     // XXX
79     // note: ugly cast because this does something mutable
80     // even though this method is defined as "const".
81     // Simply removing the const causes trouble all over fbcode;
82     // lots of services build a const EventBaseManager and errors
83     // abound when we make this non-const.
84     (const_cast<EventBaseManager *>(this))->trackEventBase(info->eventBase);
85   }
86
87   return info->eventBase;
88 }
89
90 } // namespace folly