/* * Copyright 2016 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
// This ignores the SIGPIPE signal on the calling thread. // This signal can be fired when trying to write() to a pipe that's being // closed or while closing a pipe that's being written to. // We can run into that situation so we ignore this signal and continue as // normal. // As a side note for this implementation, it would be great if we could safely // restore the sigmask, but unfortunately the operation of restoring it, can // itself actually cause SIGPIPE to be signaled :-| (e.g. on MacOS) // The SIGPIPE signal by default causes the process to be terminated, so we // don't want to risk that. // An alternative to this approach is to ignore the signal for the whole // process: // signal(SIGPIPE, SIG_IGN); void IgnoreSigPipeSignalOnCurrentThread() {
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &sigpipe_mask, nullptr);
}
// TODO(tommi): This is a hack to support two versions of libevent that we're // compatible with. The method we really want to call is event_assign(), // since event_set() has been marked as deprecated (and doesn't accept // passing event_base__ as a parameter). However, the version of libevent // that we have in Chromium, doesn't have event_assign(), so we need to call // event_set() there. void EventAssign(struct event* ev, struct event_base* base, int fd, short events, void (*callback)(int, short, void*), void* arg) { #ifdefined(_EVENT2_EVENT_H_)
RTC_CHECK_EQ(0, event_assign(ev, base, fd, events, callback, arg)); #else
event_set(ev, fd, events, callback, arg);
RTC_CHECK_EQ(0, event_base_set(base, ev)); #endif
}
rtc::ThreadPriority TaskQueuePriorityToThreadPriority(Priority priority) { switch (priority) { case Priority::HIGH: return rtc::ThreadPriority::kRealtime; case Priority::LOW: return rtc::ThreadPriority::kLow; case Priority::NORMAL: return rtc::ThreadPriority::kNormal;
}
}
class TaskQueueLibevent final : public TaskQueueBase { public:
TaskQueueLibevent(absl::string_view queue_name, rtc::ThreadPriority priority);
// Ensure remaining deleted tasks are destroyed with Current() set up // to this task queue.
absl::InlinedVector<absl::AnyInvocable<void() &&>, 4> pending;
MutexLock lock(&pending_lock_);
pending_.swap(pending);
} for (TimerEvent* timer : pending_timers_) delete timer;
void TaskQueueLibevent::Delete() {
RTC_DCHECK(!IsCurrent()); struct timespec ts; char message = kQuit; while (write(wakeup_pipe_in_, &message, sizeof(message)) != sizeof(message)) { // The queue is full, so we have no choice but to wait and retry.
RTC_CHECK_EQ(EAGAIN, errno);
ts.tv_sec = 0;
ts.tv_nsec = 1000000;
nanosleep(&ts, nullptr);
}
// Only write to the pipe if there were no pending tasks before this one // since the thread could be sleeping. If there were already pending tasks // then we know there's either a pending write in the pipe or the thread has // not yet processed the pending tasks. In either case, the thread will // eventually wake up and process all pending tasks including this one. if (had_pending_tasks) { return;
}
}
// Note: This behvior outlined above ensures we never fill up the pipe write // buffer since there will only ever be 1 byte pending. char message = kRunTasks;
RTC_CHECK_EQ(write(wakeup_pipe_in_, &message, sizeof(message)), sizeof(message));
}
void TaskQueueLibevent::PostDelayedTaskOnTaskQueue(
absl::AnyInvocable<void() &&> task,
TimeDelta delay) { // libevent api is not thread safe by default, thus event_add need to be // called on the `thread_`.
RTC_DCHECK(IsCurrent());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.