| 177 | } |
| 178 | |
| 179 | void MapDefunOp::ComputeAsync(OpKernelContext* ctx, DoneCallback done) { |
| 180 | ComputeOptions* compute_opts = nullptr; |
| 181 | |
| 182 | OP_REQUIRES_OK_ASYNC(ctx, SetupArgs(ctx, &compute_opts), done); |
| 183 | |
| 184 | Status s = SetupOutputs(ctx, compute_opts); |
| 185 | if (!s.ok()) delete compute_opts; |
| 186 | OP_REQUIRES_OK_ASYNC(ctx, s, done); |
| 187 | |
| 188 | FunctionLibraryRuntime::Options opts; |
| 189 | SetRunOptions(ctx, &opts, compute_opts, /*always_collect_stats=*/false); |
| 190 | |
| 191 | // Run loop |
| 192 | StatusCallback callback = std::bind( |
| 193 | [](OpKernelContext* ctx, ComputeOptions* compute_opts, DoneCallback& done, |
| 194 | const Status& status) { |
| 195 | delete compute_opts; |
| 196 | ctx->SetStatus(status); |
| 197 | done(); |
| 198 | }, |
| 199 | ctx, compute_opts, std::move(done), std::placeholders::_1); |
| 200 | |
| 201 | auto* refcounted = new ReffedStatusCallback(std::move(callback)); |
| 202 | |
| 203 | CancellationManager* parent_mgr = ctx->cancellation_manager(); |
| 204 | |
| 205 | for (size_t i = 0; i < static_cast<size_t>(compute_opts->batch_size); ++i) { |
| 206 | // We use a different cancellation manager each time the function is run |
| 207 | // to avoid the race condition between a function run error and other |
| 208 | // functions being cancelled as a result. |
| 209 | CancellationManager* c_mgr = new CancellationManager(); |
| 210 | CancellationToken token = parent_mgr->get_cancellation_token(); |
| 211 | const bool success = parent_mgr->RegisterCallback( |
| 212 | token, [c_mgr]() { c_mgr->StartCancel(); }); |
| 213 | |
| 214 | opts.cancellation_manager = c_mgr; |
| 215 | if (!success) { |
| 216 | delete c_mgr; |
| 217 | refcounted->UpdateStatus(errors::Cancelled( |
| 218 | "MapDefunOp functions cancelled because parent graph cancelled")); |
| 219 | break; |
| 220 | } |
| 221 | |
| 222 | auto* call_frame = new MapFunctionCallFrame(compute_opts, this, i); |
| 223 | |
| 224 | refcounted->Ref(); |
| 225 | ctx->function_library()->Run(opts, func_handle_, call_frame, |
| 226 | [call_frame, refcounted, c_mgr, parent_mgr, |
| 227 | token](const Status& func_status) { |
| 228 | parent_mgr->DeregisterCallback(token); |
| 229 | delete c_mgr; |
| 230 | delete call_frame; |
| 231 | refcounted->UpdateStatus(func_status); |
| 232 | refcounted->Unref(); |
| 233 | }); |
| 234 | } |
| 235 | |
| 236 | // Unref 1 because refcounted is initialized with refcount = 1 |
nothing calls this directly
no test coverage detected