| 305 | } |
| 306 | |
| 307 | int |
| 308 | taskqueue_enqueue_timeout_sbt(struct taskqueue *queue, |
| 309 | struct timeout_task *timeout_task, sbintime_t sbt, sbintime_t pr, int flags) |
| 310 | { |
| 311 | int res; |
| 312 | |
| 313 | TQ_LOCK(queue); |
| 314 | KASSERT(timeout_task->q == NULL || timeout_task->q == queue, |
| 315 | ("Migrated queue")); |
| 316 | KASSERT(!queue->tq_spin, ("Timeout for spin-queue")); |
| 317 | timeout_task->q = queue; |
| 318 | res = timeout_task->t.ta_pending; |
| 319 | if (timeout_task->f & DT_DRAIN_IN_PROGRESS) { |
| 320 | /* Do nothing */ |
| 321 | TQ_UNLOCK(queue); |
| 322 | res = -1; |
| 323 | } else if (sbt == 0) { |
| 324 | taskqueue_enqueue_locked(queue, &timeout_task->t); |
| 325 | /* The lock is released inside. */ |
| 326 | } else { |
| 327 | if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) { |
| 328 | res++; |
| 329 | } else { |
| 330 | queue->tq_callouts++; |
| 331 | timeout_task->f |= DT_CALLOUT_ARMED; |
| 332 | if (sbt < 0) |
| 333 | sbt = -sbt; /* Ignore overflow. */ |
| 334 | } |
| 335 | if (sbt > 0) { |
| 336 | callout_reset_sbt(&timeout_task->c, sbt, pr, |
| 337 | taskqueue_timeout_func, timeout_task, flags); |
| 338 | } |
| 339 | TQ_UNLOCK(queue); |
| 340 | } |
| 341 | return (res); |
| 342 | } |
| 343 | |
| 344 | int |
| 345 | taskqueue_enqueue_timeout(struct taskqueue *queue, |
no test coverage detected