| 119 | }; |
| 120 | |
| 121 | void AcquireAsync( |
| 122 | OpKernelContext* c, |
| 123 | std::function<void(const Status& s, SharedLockReleaser lock)> fn) { |
| 124 | CancellationManager* cm = c->cancellation_manager(); |
| 125 | CancellationToken token{}; |
| 126 | bool* cancelled = nullptr; |
| 127 | if (cm) { |
| 128 | cancelled = new bool(false); // GUARDED_BY(mu_); |
| 129 | token = cm->get_cancellation_token(); |
| 130 | const bool already_cancelled = |
| 131 | !cm->RegisterCallback(token, [this, cancelled]() { |
| 132 | mutex_lock lock(mu_); |
| 133 | *cancelled = true; |
| 134 | cv_.notify_all(); |
| 135 | }); |
| 136 | if (already_cancelled) { |
| 137 | delete cancelled; |
| 138 | fn(errors::Cancelled("Lock acquisition cancelled."), |
| 139 | SharedLockReleaser{nullptr}); |
| 140 | return; |
| 141 | } |
| 142 | } |
| 143 | thread_pool_->Schedule(std::bind( |
| 144 | [this, cm, cancelled, |
| 145 | token](std::function<void(const Status& s, SharedLockReleaser&& lock)> |
| 146 | fn_) { |
| 147 | bool local_locked; |
| 148 | { |
| 149 | mutex_lock lock(mu_); |
| 150 | while (locked_ && !(cancelled && *cancelled)) { |
| 151 | cv_.wait(lock); |
| 152 | } |
| 153 | local_locked = locked_ = !(cancelled && *cancelled); |
| 154 | } |
| 155 | if (cm) { |
| 156 | cm->DeregisterCallback(token); |
| 157 | delete cancelled; |
| 158 | } |
| 159 | if (local_locked) { // Not cancelled. |
| 160 | fn_(Status::OK(), |
| 161 | SharedLockReleaser{std::make_shared<LockReleaser>(this)}); |
| 162 | } else { |
| 163 | fn_(errors::Cancelled("Lock acquisition cancelled."), |
| 164 | SharedLockReleaser{nullptr}); |
| 165 | } |
| 166 | }, |
| 167 | std::move(fn))); |
| 168 | } |
| 169 | |
| 170 | private: |
| 171 | mutex mu_; |
no test coverage detected