| 195 | } |
| 196 | |
| 197 | void PriorityQueue::TryDequeue(OpKernelContext* ctx, |
| 198 | CallbackWithTuple callback) { |
| 199 | CancellationManager* cm = ctx->cancellation_manager(); |
| 200 | CancellationToken token = cm->get_cancellation_token(); |
| 201 | bool already_cancelled; |
| 202 | { |
| 203 | mutex_lock l(mu_); |
| 204 | already_cancelled = !cm->RegisterCallback( |
| 205 | token, [this, cm, token]() { Cancel(kDequeue, cm, token); }); |
| 206 | if (!already_cancelled) { |
| 207 | // TODO(josh11b): This makes two copies of callback, avoid this if possible. |
| 208 | dequeue_attempts_.emplace_back( |
| 209 | 1, [callback]() { callback(Tuple()); }, ctx, cm, token, |
| 210 | [callback, this](Attempt* attempt) EXCLUSIVE_LOCKS_REQUIRED(mu_) { |
| 211 | const int32 s = queues_[0].size(); |
| 212 | if (closed_ && s == 0) { |
| 213 | attempt->context->SetStatus(errors::OutOfRange( |
| 214 | "PriorityQueue '", name_, "' is closed and has ", |
| 215 | "insufficient elements (requested ", 1, ", current size ", s, |
| 216 | ")")); |
| 217 | return kComplete; |
| 218 | } |
| 219 | if (s > 0) { |
| 220 | Tuple tuple; |
| 221 | DequeueLocked(attempt->context, &tuple); |
| 222 | attempt->done_callback = [callback, tuple]() { callback(tuple); }; |
| 223 | return kComplete; |
| 224 | } else { |
| 225 | return kNoProgress; |
| 226 | } |
| 227 | }); |
| 228 | } |
| 229 | } |
| 230 | if (!already_cancelled) { |
| 231 | FlushUnlocked(); |
| 232 | } else { |
| 233 | ctx->SetStatus(errors::Cancelled("Dequeue operation was cancelled")); |
| 234 | callback(Tuple()); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | void PriorityQueue::TryDequeueMany(int num_elements, OpKernelContext* ctx, |
| 239 | bool allow_small_batch, |
nothing calls this directly
no test coverage detected