| 316 | } |
| 317 | |
| 318 | Status SingleMachine::ShutdownSession() { |
| 319 | TF_RETURN_IF_ERROR(CloseSession(true /*use_timeout*/)); |
| 320 | |
| 321 | // Delete the threadpool: this ensures that all the pending closures complete |
| 322 | // before we return. Note that if TF deadlocked on us, the closures will |
| 323 | // never complete, and the call to thread_pool_.reset() will never return: |
| 324 | // therefore we need to delete the threadpool with the background thread. |
| 325 | // That thread itself will also never complete, so the user should |
| 326 | // abort the process to avoid leaking too many resources. |
| 327 | auto n = std::make_shared<Notification>(); |
| 328 | Env::Default()->SchedClosure([this, n]() { |
| 329 | thread_pool_.reset(); |
| 330 | n->Notify(); |
| 331 | }); |
| 332 | int64 timeout_us = 1000000ll * timeout_s_; |
| 333 | const bool notified = WaitForNotificationWithTimeout(n.get(), timeout_us); |
| 334 | if (!notified) { |
| 335 | // Let the caller know that we can't shutdown the session properly since |
| 336 | // there are calls to Session::Run() still running. |
| 337 | return errors::Unavailable("The session is still running graphs after ", |
| 338 | timeout_s_, " seconds"); |
| 339 | } |
| 340 | |
| 341 | return Status::OK(); |
| 342 | } |
| 343 | |
| 344 | Status SingleMachine::ResetSession() { |
| 345 | if (session_) { |
nothing calls this directly
no test coverage detected