forked from OSchip/llvm-project
[MainLoop] Fix possible use of an invalid iterator
Store file descriptors from loop.m_read_fds (if FORCE_PSELECT is defined) and signals from loop.m_signals that need to be processed in MainLoop::RunImpl::ProcessEvents() into a separate vector and then iterate over this container to invoke the callbacks. This prevents a problem where when the code iterated directly over m_read_fds/m_signals, a callback invoked from within the loop could modify these variables and invalidate the loop iterator. This would then result in an assertion failure in llvm::DenseMapIterator::operator++(). Differential Revision: https://reviews.llvm.org/D35298 llvm-svn: 307782
This commit is contained in:
parent
293b4fc04e
commit
8c5dafde49
|
@ -193,10 +193,16 @@ Status MainLoop::RunImpl::Poll() {
|
|||
|
||||
void MainLoop::RunImpl::ProcessEvents() {
|
||||
#ifdef FORCE_PSELECT
|
||||
for (const auto &fd : loop.m_read_fds) {
|
||||
if (!FD_ISSET(fd.first, &read_fd_set))
|
||||
continue;
|
||||
IOObject::WaitableHandle handle = fd.first;
|
||||
// Collect first all readable file descriptors into a separate vector and then
|
||||
// iterate over it to invoke callbacks. Iterating directly over
|
||||
// loop.m_read_fds is not possible because the callbacks can modify the
|
||||
// container which could invalidate the iterator.
|
||||
std::vector<IOObject::WaitableHandle> fds;
|
||||
for (const auto &fd : loop.m_read_fds)
|
||||
if (FD_ISSET(fd.first, &read_fd_set))
|
||||
fds.push_back(fd.first);
|
||||
|
||||
for (const auto &handle : fds) {
|
||||
#else
|
||||
for (const auto &fd : read_fds) {
|
||||
if ((fd.revents & POLLIN) == 0)
|
||||
|
@ -209,13 +215,16 @@ void MainLoop::RunImpl::ProcessEvents() {
|
|||
loop.ProcessReadObject(handle);
|
||||
}
|
||||
|
||||
for (const auto &entry : loop.m_signals) {
|
||||
std::vector<int> signals;
|
||||
for (const auto &entry : loop.m_signals)
|
||||
if (g_signal_flags[entry.first] != 0)
|
||||
signals.push_back(entry.first);
|
||||
|
||||
for (const auto &signal : signals) {
|
||||
if (loop.m_terminate_request)
|
||||
return;
|
||||
if (g_signal_flags[entry.first] == 0)
|
||||
continue; // No signal
|
||||
g_signal_flags[entry.first] = 0;
|
||||
loop.ProcessSignal(entry.first);
|
||||
g_signal_flags[signal] = 0;
|
||||
loop.ProcessSignal(signal);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue