| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iosfwd> | 5 #include <iosfwd> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/platform_thread.h" | 12 #include "base/platform_thread.h" |
| 13 #include "base/port.h" | 13 #include "base/port.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "chrome/common/deprecated/event_sys-inl.h" | 15 #include "chrome/common/deprecated/event_sys-inl.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using std::endl; | |
| 19 using std::ostream; | |
| 20 using std::string; | |
| 21 using std::stringstream; | |
| 22 using std::vector; | |
| 23 | |
| 24 namespace { | 18 namespace { |
| 25 | 19 |
| 26 class Pair; | 20 class Pair; |
| 27 | 21 |
| 28 struct TestEvent { | 22 struct TestEvent { |
| 29 Pair* source; | 23 Pair* source; |
| 30 enum { | 24 enum { |
| 31 A_CHANGED, B_CHANGED, PAIR_BEING_DELETED, | 25 A_CHANGED, B_CHANGED, PAIR_BEING_DELETED, |
| 32 } what_happened; | 26 } what_happened; |
| 33 int old_value; | 27 int old_value; |
| 34 }; | 28 }; |
| 35 | 29 |
| 36 struct TestEventTraits { | 30 struct TestEventTraits { |
| 37 typedef TestEvent EventType; | 31 typedef TestEvent EventType; |
| 38 static bool IsChannelShutdownEvent(const TestEvent& event) { | 32 static bool IsChannelShutdownEvent(const TestEvent& event) { |
| 39 return TestEvent::PAIR_BEING_DELETED == event.what_happened; | 33 return TestEvent::PAIR_BEING_DELETED == event.what_happened; |
| 40 } | 34 } |
| 41 }; | 35 }; |
| 42 | 36 |
| 43 class Pair { | 37 class Pair { |
| 44 public: | 38 public: |
| 45 typedef EventChannel<TestEventTraits> Channel; | 39 typedef EventChannel<TestEventTraits> Channel; |
| 46 explicit Pair(const string& name) : name_(name), a_(0), b_(0) { | 40 explicit Pair(const std::string& name) : name_(name), a_(0), b_(0) { |
| 47 TestEvent shutdown = { this, TestEvent::PAIR_BEING_DELETED, 0 }; | 41 TestEvent shutdown = { this, TestEvent::PAIR_BEING_DELETED, 0 }; |
| 48 event_channel_ = new Channel(shutdown); | 42 event_channel_ = new Channel(shutdown); |
| 49 } | 43 } |
| 50 ~Pair() { | 44 ~Pair() { |
| 51 delete event_channel_; | 45 delete event_channel_; |
| 52 } | 46 } |
| 53 void set_a(int n) { | 47 void set_a(int n) { |
| 54 TestEvent event = { this, TestEvent::A_CHANGED, a_ }; | 48 TestEvent event = { this, TestEvent::A_CHANGED, a_ }; |
| 55 a_ = n; | 49 a_ = n; |
| 56 event_channel_->NotifyListeners(event); | 50 event_channel_->NotifyListeners(event); |
| 57 } | 51 } |
| 58 void set_b(int n) { | 52 void set_b(int n) { |
| 59 TestEvent event = { this, TestEvent::B_CHANGED, b_ }; | 53 TestEvent event = { this, TestEvent::B_CHANGED, b_ }; |
| 60 b_ = n; | 54 b_ = n; |
| 61 event_channel_->NotifyListeners(event); | 55 event_channel_->NotifyListeners(event); |
| 62 } | 56 } |
| 63 int a() const { return a_; } | 57 int a() const { return a_; } |
| 64 int b() const { return b_; } | 58 int b() const { return b_; } |
| 65 const string& name() { return name_; } | 59 const std::string& name() { return name_; } |
| 66 Channel* event_channel() const { return event_channel_; } | 60 Channel* event_channel() const { return event_channel_; } |
| 67 | 61 |
| 68 protected: | 62 protected: |
| 69 const string name_; | 63 const std::string name_; |
| 70 int a_; | 64 int a_; |
| 71 int b_; | 65 int b_; |
| 72 Channel* event_channel_; | 66 Channel* event_channel_; |
| 73 }; | 67 }; |
| 74 | 68 |
| 75 class EventLogger { | 69 class EventLogger { |
| 76 public: | 70 public: |
| 77 explicit EventLogger(ostream& out) : out_(out) { } | 71 explicit EventLogger(std::ostream* out) : out_(out) { } |
| 78 ~EventLogger() { | 72 ~EventLogger() { |
| 79 for (Hookups::iterator i = hookups_.begin(); i != hookups_.end(); ++i) | 73 for (Hookups::iterator i = hookups_.begin(); i != hookups_.end(); ++i) |
| 80 delete *i; | 74 delete *i; |
| 81 } | 75 } |
| 82 | 76 |
| 83 void Hookup(const string name, Pair::Channel* channel) { | 77 void Hookup(const std::string name, Pair::Channel* channel) { |
| 84 hookups_.push_back(NewEventListenerHookup(channel, this, | 78 hookups_.push_back(NewEventListenerHookup(channel, this, |
| 85 &EventLogger::HandlePairEvent, | 79 &EventLogger::HandlePairEvent, |
| 86 name)); | 80 name)); |
| 87 } | 81 } |
| 88 | 82 |
| 89 void HandlePairEvent(const string& name, const TestEvent& event) { | 83 void HandlePairEvent(const std::string& name, const TestEvent& event) { |
| 90 const char* what_changed = NULL; | 84 const char* what_changed = NULL; |
| 91 int new_value = 0; | 85 int new_value = 0; |
| 92 Hookups::iterator dead; | 86 Hookups::iterator dead; |
| 93 switch (event.what_happened) { | 87 switch (event.what_happened) { |
| 94 case TestEvent::A_CHANGED: | 88 case TestEvent::A_CHANGED: |
| 95 what_changed = "A"; | 89 what_changed = "A"; |
| 96 new_value = event.source->a(); | 90 new_value = event.source->a(); |
| 97 break; | 91 break; |
| 98 case TestEvent::B_CHANGED: | 92 case TestEvent::B_CHANGED: |
| 99 what_changed = "B"; | 93 what_changed = "B"; |
| 100 new_value = event.source->b(); | 94 new_value = event.source->b(); |
| 101 break; | 95 break; |
| 102 case TestEvent::PAIR_BEING_DELETED: | 96 case TestEvent::PAIR_BEING_DELETED: |
| 103 out_ << name << " heard " << event.source->name() << " being deleted." | 97 *out_ << name << " heard " << event.source->name() << " being deleted." |
| 104 << endl; | 98 << std::endl; |
| 105 return; | 99 return; |
| 106 default: | 100 default: |
| 107 FAIL() << "Bad event.what_happened: " << event.what_happened; | 101 FAIL() << "Bad event.what_happened: " << event.what_happened; |
| 108 break; | 102 break; |
| 109 } | 103 } |
| 110 out_ << name << " heard " << event.source->name() << "'s " << what_changed | 104 *out_ << name << " heard " << event.source->name() << "'s " << what_changed |
| 111 << " change from " | 105 << " change from " << event.old_value |
| 112 << event.old_value << " to " << new_value << endl; | 106 << " to " << new_value << std::endl; |
| 113 } | 107 } |
| 114 | 108 |
| 115 typedef vector<EventListenerHookup*> Hookups; | 109 typedef std::vector<EventListenerHookup*> Hookups; |
| 116 Hookups hookups_; | 110 Hookups hookups_; |
| 117 ostream& out_; | 111 std::ostream* out_; |
| 118 }; | 112 }; |
| 119 | 113 |
| 120 const char golden_result[] = "Larry heard Sally's B change from 0 to 2\n" | 114 const char golden_result[] = "Larry heard Sally's B change from 0 to 2\n" |
| 121 "Larry heard Sally's A change from 1 to 3\n" | 115 "Larry heard Sally's A change from 1 to 3\n" |
| 122 "Lewis heard Sam's B change from 0 to 5\n" | 116 "Lewis heard Sam's B change from 0 to 5\n" |
| 123 "Larry heard Sally's A change from 3 to 6\n" | 117 "Larry heard Sally's A change from 3 to 6\n" |
| 124 "Larry heard Sally being deleted.\n"; | 118 "Larry heard Sally being deleted.\n"; |
| 125 | 119 |
| 126 TEST(EventSys, Basic) { | 120 TEST(EventSys, Basic) { |
| 127 Pair sally("Sally"), sam("Sam"); | 121 Pair sally("Sally"), sam("Sam"); |
| 128 sally.set_a(1); | 122 sally.set_a(1); |
| 129 stringstream log; | 123 std::stringstream log; |
| 130 EventLogger logger(log); | 124 EventLogger logger(&log); |
| 131 logger.Hookup("Larry", sally.event_channel()); | 125 logger.Hookup("Larry", sally.event_channel()); |
| 132 sally.set_b(2); | 126 sally.set_b(2); |
| 133 sally.set_a(3); | 127 sally.set_a(3); |
| 134 sam.set_a(4); | 128 sam.set_a(4); |
| 135 logger.Hookup("Lewis", sam.event_channel()); | 129 logger.Hookup("Lewis", sam.event_channel()); |
| 136 sam.set_b(5); | 130 sam.set_b(5); |
| 137 sally.set_a(6); | 131 sally.set_a(6); |
| 138 // Test that disconnect within callback doesn't deadlock. | 132 // Test that disconnect within callback doesn't deadlock. |
| 139 TestEvent event = {&sally, TestEvent::PAIR_BEING_DELETED, 0 }; | 133 TestEvent event = {&sally, TestEvent::PAIR_BEING_DELETED, 0 }; |
| 140 sally.event_channel()->NotifyListeners(event); | 134 sally.event_channel()->NotifyListeners(event); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 FAIL() << "A test thread exited too early."; | 223 FAIL() << "A test thread exited too early."; |
| 230 completed_mutex_.Release(); | 224 completed_mutex_.Release(); |
| 231 } | 225 } |
| 232 | 226 |
| 233 Pair* pair_; | 227 Pair* pair_; |
| 234 ConditionVariable remove_event_; | 228 ConditionVariable remove_event_; |
| 235 Lock remove_event_mutex_; | 229 Lock remove_event_mutex_; |
| 236 bool remove_event_bool_; | 230 bool remove_event_bool_; |
| 237 Lock completed_mutex_; | 231 Lock completed_mutex_; |
| 238 bool completed_; | 232 bool completed_; |
| 239 vector<ThreadInfo> threads_; | 233 std::vector<ThreadInfo> threads_; |
| 240 ThreadArgs args_; | 234 ThreadArgs args_; |
| 241 }; | 235 }; |
| 242 | 236 |
| 243 TEST(EventSys, Multithreaded) { | 237 TEST(EventSys, Multithreaded) { |
| 244 Pair sally("Sally"); | 238 Pair sally("Sally"); |
| 245 ThreadTester a(&sally); | 239 ThreadTester a(&sally); |
| 246 for (int i = 0; i < 3; ++i) | 240 for (int i = 0; i < 3; ++i) |
| 247 a.Go(); | 241 a.Go(); |
| 248 sally.set_b(99); | 242 sally.set_b(99); |
| 249 } | 243 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 261 Pair sally("Sally"); | 255 Pair sally("Sally"); |
| 262 HookupDeleter deleter; | 256 HookupDeleter deleter; |
| 263 deleter.hookup_ = NewEventListenerHookup(sally.event_channel(), | 257 deleter.hookup_ = NewEventListenerHookup(sally.event_channel(), |
| 264 &deleter, | 258 &deleter, |
| 265 &HookupDeleter::HandleEvent); | 259 &HookupDeleter::HandleEvent); |
| 266 sally.set_a(1); | 260 sally.set_a(1); |
| 267 ASSERT_TRUE(NULL == deleter.hookup_); | 261 ASSERT_TRUE(NULL == deleter.hookup_); |
| 268 } | 262 } |
| 269 | 263 |
| 270 } // namespace | 264 } // namespace |
| OLD | NEW |