Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(857)

Side by Side Diff: src/vm/event_handler_posix.cc

Issue 1375373004: Use the event-handler for timers. (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/vm/event_handler_macos.cc ('k') | src/vm/heap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE.md file. 3 // BSD-style license that can be found in the LICENSE.md file.
4 4
5 #if defined(FLETCH_TARGET_OS_POSIX) 5 #if defined(FLETCH_TARGET_OS_POSIX)
6 6
7 #include "src/vm/event_handler.h" 7 #include "src/vm/event_handler.h"
8 8
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include "src/shared/flags.h" 12 #include "src/shared/flags.h"
13 13
14 #include "src/vm/object.h" 14 #include "src/vm/object.h"
15 #include "src/vm/port.h" 15 #include "src/vm/port.h"
16 #include "src/vm/process.h" 16 #include "src/vm/process.h"
17 #include "src/vm/scheduler.h" 17 #include "src/vm/scheduler.h"
18 #include "src/vm/thread.h" 18 #include "src/vm/thread.h"
19 19
20 namespace fletch { 20 namespace fletch {
21 21
22 EventHandler::EventHandler() 22 EventHandler::EventHandler()
23 : monitor_(Platform::CreateMonitor()), 23 : monitor_(Platform::CreateMonitor()),
24 fd_(-1), 24 fd_(-1),
25 next_timeout_(INT64_MAX),
25 read_fd_(-1), 26 read_fd_(-1),
26 write_fd_(-1) { 27 write_fd_(-1) {
27 } 28 }
28 29
29 EventHandler::~EventHandler() { 30 EventHandler::~EventHandler() {
30 if (fd_ != -1) { 31 if (fd_ != -1) {
31 // TODO(runtime-developers): This is pretty nasty, inside the destructor we 32 // TODO(runtime-developers): This is pretty nasty, inside the destructor we
32 // notify the other thread (via close()) to shut down. The other thread will 33 // notify the other thread (via close()) to shut down. The other thread will
33 // then access members of the [EventHandler] object which is in the middle 34 // then access members of the [EventHandler] object which is in the middle
34 // of destruction. 35 // of destruction.
(...skipping 26 matching lines...) Expand all
61 int status = fcntl(fds[0], F_SETFD, FD_CLOEXEC); 62 int status = fcntl(fds[0], F_SETFD, FD_CLOEXEC);
62 if (status == -1) FATAL("Failed making read pipe close on exec."); 63 if (status == -1) FATAL("Failed making read pipe close on exec.");
63 status = fcntl(fds[1], F_SETFD, FD_CLOEXEC); 64 status = fcntl(fds[1], F_SETFD, FD_CLOEXEC);
64 if (status == -1) FATAL("Failed making write pipe close on exec."); 65 if (status == -1) FATAL("Failed making write pipe close on exec.");
65 read_fd_ = fds[0]; 66 read_fd_ = fds[0];
66 write_fd_ = fds[1]; 67 write_fd_ = fds[1];
67 thread_ = Thread::Run(RunEventHandler, reinterpret_cast<void*>(this)); 68 thread_ = Thread::Run(RunEventHandler, reinterpret_cast<void*>(this));
68 return fd_; 69 return fd_;
69 } 70 }
70 71
72 void EventHandler::ScheduleTimeout(int64 timeout, Port* port) {
73 ASSERT(timeout != INT64_MAX);
74
75 // Be sure it's running.
76 GetEventHandler();
77
78 ScopedMonitorLock scoped_lock(monitor_);
79
80 auto it = timeouts_.Find(port);
81 if (it == timeouts_.End()) {
82 if (timeout == -1) return;
83 timeouts_[port] = timeout;
84 next_timeout_ = Utils::Minimum(next_timeout_, timeout);
85 // Be sure to mark the port as referenced.
86 port->IncrementRef();
87 } else if (timeout == -1) {
88 timeouts_.Erase(it);
89 // TODO(ajohnsen): We could consider a heap structure to avoid O(n) in this
90 // case?
91 int64 next_timeout = INT64_MAX;
92 for (auto it = timeouts_.Begin(); it != timeouts_.End(); ++it) {
93 next_timeout = Utils::Minimum(next_timeout, it->second);
94 }
95 next_timeout_ = next_timeout;
96 // The port is no longer "referenced" by the event manager.
97 port->DecrementRef();
98 } else {
99 timeouts_[port] = timeout;
100 next_timeout_ = Utils::Minimum(next_timeout_, timeout);
101 }
102 char b = 0;
103 write(write_fd_, &b, 1);
104 }
105
106 void EventHandler::HandleTimeouts() {
107 // Check timeouts.
108 int64 current_time = Platform::GetMicroseconds() / 1000;
109
110 ScopedMonitorLock scoped_lock(monitor_);
111 if (next_timeout_ > current_time) return;
112
113 int64 next_timeout = INT64_MAX;
114
115 // TODO(ajohnsen): We could consider a heap structure to avoid O(n^2) in
116 // this case?
117 // The following is O(n^2), because we can't continue iterating a hash-map
118 // once we have removed from it.
119 while (true) {
120 bool found = false;
121 for (auto it = timeouts_.Begin(); it != timeouts_.End(); ++it) {
122 if (it->second <= current_time) {
123 Send(it->first, 0);
124 timeouts_.Erase(it);
125 found = true;
126 break;
127 } else {
128 next_timeout = Utils::Minimum(next_timeout, it->second);
129 }
130 }
131 if (!found) break;
132 }
133
134 next_timeout_ = next_timeout;
135 }
136
71 void EventHandler::Send(Port* port, uword mask) { 137 void EventHandler::Send(Port* port, uword mask) {
72 Object* message = Smi::FromWord(mask); 138 Object* message = Smi::FromWord(mask);
73 port->Lock(); 139 port->Lock();
74 Process* port_process = port->process(); 140 Process* port_process = port->process();
75 if (port_process != NULL) { 141 if (port_process != NULL) {
76 port_process->mailbox()->Enqueue(port, message); 142 port_process->mailbox()->Enqueue(port, message);
77 port_process->program()->scheduler()->ResumeProcess(port_process); 143 port_process->program()->scheduler()->ResumeProcess(port_process);
78 } 144 }
79 port->Unlock(); 145 port->Unlock();
80 port->DecrementRef(); 146 port->DecrementRef();
81 } 147 }
82 148
83 } // namespace fletch 149 } // namespace fletch
84 150
85 #endif // FLETCH_TARGET_OS_POSIX 151 #endif // FLETCH_TARGET_OS_POSIX
OLDNEW
« no previous file with comments | « src/vm/event_handler_macos.cc ('k') | src/vm/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698