| 181 | } |
| 182 | |
| 183 | void TaskQueue::PostTask(std::unique_ptr<QueuedTask> task) { |
| 184 | RTC_DCHECK(task.get()); |
| 185 | // libevent isn't thread safe. This means that we can't use methods such |
| 186 | // as event_base_once to post tasks to the worker thread from a different |
| 187 | // thread. However, we can use it when posting from the worker thread itself. |
| 188 | if (IsCurrent()) { |
| 189 | if (event_base_once(event_base_, -1, EV_TIMEOUT, &TaskQueue::RunTask, |
| 190 | task.get(), nullptr) == 0) { |
| 191 | task.release(); |
| 192 | } |
| 193 | } else { |
| 194 | QueuedTask* task_id = task.get(); // Only used for comparison. |
| 195 | { |
| 196 | CritScope lock(&pending_lock_); |
| 197 | pending_.push_back(std::move(task)); |
| 198 | } |
| 199 | char message = kRunTask; |
| 200 | if (write(wakeup_pipe_in_, &message, sizeof(message)) != sizeof(message)) { |
| 201 | LOG(WARNING) << "Failed to queue task."; |
| 202 | CritScope lock(&pending_lock_); |
| 203 | pending_.remove_if([task_id](std::unique_ptr<QueuedTask>& t) { |
| 204 | return t.get() == task_id; |
| 205 | }); |
| 206 | } |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | void TaskQueue::PostDelayedTask(std::unique_ptr<QueuedTask> task, |
| 211 | uint32_t milliseconds) { |