| 186 | } |
| 187 | |
| 188 | TimerThread::Bucket::ScheduleResult |
| 189 | TimerThread::Bucket::schedule(void (*fn)(void*), void* arg, |
| 190 | const timespec& abstime) { |
| 191 | butil::ResourceId<Task> slot_id; |
| 192 | Task* task = butil::get_resource<Task>(&slot_id); |
| 193 | if (task == NULL) { |
| 194 | ScheduleResult result = { INVALID_TASK_ID, false }; |
| 195 | return result; |
| 196 | } |
| 197 | task->next = NULL; |
| 198 | task->fn = fn; |
| 199 | task->arg = arg; |
| 200 | task->run_time = butil::timespec_to_microseconds(abstime); |
| 201 | uint32_t version = task->version.load(butil::memory_order_relaxed); |
| 202 | if (version == 0) { // skip 0. |
| 203 | task->version.fetch_add(2, butil::memory_order_relaxed); |
| 204 | version = 2; |
| 205 | } |
| 206 | const TaskId id = make_task_id(slot_id, version); |
| 207 | task->task_id = id; |
| 208 | bool earlier = false; |
| 209 | { |
| 210 | BAIDU_SCOPED_LOCK(_mutex); |
| 211 | task->next = _task_head; |
| 212 | _task_head = task; |
| 213 | if (task->run_time < _nearest_run_time) { |
| 214 | _nearest_run_time = task->run_time; |
| 215 | earlier = true; |
| 216 | } |
| 217 | } |
| 218 | ScheduleResult result = { id, earlier }; |
| 219 | return result; |
| 220 | } |
| 221 | |
| 222 | TimerThread::TaskId TimerThread::schedule( |
| 223 | void (*fn)(void*), void* arg, const timespec& abstime) { |
no test coverage detected