|
5 | 5 | * file in the root directory of this source tree.
|
6 | 6 | */
|
7 | 7 | #include "event.h"
|
| 8 | +#include <atomic> |
8 | 9 | #include <memory>
|
9 | 10 | #include <stdexcept>
|
10 |
| -#include <mutex> |
11 |
| - |
12 |
| -#include <iostream> |
13 | 11 |
|
14 | 12 | namespace facebook {
|
15 | 13 | namespace yoga {
|
16 | 14 |
|
17 | 15 | namespace {
|
18 | 16 |
|
19 |
| -std::mutex& eventSubscribersMutex() { |
20 |
| - static std::mutex subscribersMutex; |
21 |
| - return subscribersMutex; |
22 |
| -} |
| 17 | +struct Node { |
| 18 | + std::function<Event::Subscriber> subscriber = nullptr; |
| 19 | + Node* next = nullptr; |
| 20 | + |
| 21 | + Node(std::function<Event::Subscriber>&& subscriber) |
| 22 | + : subscriber{std::move(subscriber)} {} |
| 23 | +}; |
23 | 24 |
|
24 |
| -std::shared_ptr<Event::Subscribers>& eventSubscribers() { |
25 |
| - static auto subscribers = std::make_shared<Event::Subscribers>(); |
26 |
| - return subscribers; |
| 25 | +std::atomic<Node*> subscribers{nullptr}; |
| 26 | + |
| 27 | +Node* push(Node* newHead) { |
| 28 | + Node* oldHead; |
| 29 | + do { |
| 30 | + oldHead = subscribers.load(std::memory_order_relaxed); |
| 31 | + if (newHead != nullptr) { |
| 32 | + newHead->next = oldHead; |
| 33 | + } |
| 34 | + } while (!subscribers.compare_exchange_weak( |
| 35 | + oldHead, newHead, std::memory_order_release, std::memory_order_relaxed)); |
| 36 | + return oldHead; |
27 | 37 | }
|
28 | 38 |
|
29 | 39 | } // namespace
|
30 | 40 |
|
31 | 41 | void Event::reset() {
|
32 |
| - eventSubscribers() = std::make_shared<Event::Subscribers>(); |
| 42 | + auto head = push(nullptr); |
| 43 | + while (head != nullptr) { |
| 44 | + auto current = head; |
| 45 | + head = head->next; |
| 46 | + delete current; |
| 47 | + } |
33 | 48 | }
|
34 | 49 |
|
35 | 50 | void Event::subscribe(std::function<Subscriber>&& subscriber) {
|
36 |
| - std::lock_guard<std::mutex> guard(eventSubscribersMutex()); |
37 |
| - eventSubscribers() = |
38 |
| - std::make_shared<Event::Subscribers>(*eventSubscribers()); |
39 |
| - eventSubscribers()->push_back(subscriber); |
| 51 | + push(new Node{std::move(subscriber)}); |
40 | 52 | }
|
41 | 53 |
|
42 | 54 | void Event::publish(const YGNode& node, Type eventType, const Data& eventData) {
|
43 |
| - std::shared_ptr<Event::Subscribers> subscribers; |
44 |
| - { |
45 |
| - std::lock_guard<std::mutex> guard(eventSubscribersMutex()); |
46 |
| - subscribers = eventSubscribers(); |
47 |
| - } |
48 |
| - |
49 |
| - for (auto& subscriber : *subscribers) { |
50 |
| - if (subscriber) { |
51 |
| - subscriber(node, eventType, eventData); |
52 |
| - } |
| 55 | + for (auto subscriber = subscribers.load(std::memory_order_relaxed); |
| 56 | + subscriber != nullptr; |
| 57 | + subscriber = subscriber->next) { |
| 58 | + subscriber->subscriber(node, eventType, eventData); |
53 | 59 | }
|
54 | 60 | }
|
55 | 61 |
|
|
0 commit comments