1 // 2 // Copyright (C) 2023 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #pragma once 17 18 #include <thread> 19 20 #include "common/libs/fs/shared_fd.h" 21 #include "common/libs/utils/result.h" 22 #include "host/libs/command_util/runner/defs.h" 23 24 namespace cuttlefish { 25 26 // `SnapshotCommandHandler` can request threads to suspend and resume using the 27 // following protocol. Each message on the socket is 1 byte. 28 // 29 // Suspend flow: 30 // 31 // 1. `SnapshotCommandHandler` writes `kSuspend` to the socket. 32 // 2. When the worker thread sees the socket is readable, it should assume the 33 // incoming message is `kSuspend`, finish all non-blocking work, read the 34 // `kSuspend` message, write a `kSuspendAck` message back into the socket, 35 // and then, finally, block until it receives another message from the 36 // socket (which will always be `kResume`). 37 // 3. `SnapshotCommandHandler` waits for the `kSuspendAck` to ensure the 38 // worker thread is actually suspended and then proceeds. 39 // 40 // Resume flow: 41 // 42 // 1. The worker thread is already blocked waiting for a `kResume` from the 43 // socket. 44 // 2. `SnapshotCommandHandler` sends a `kResume`. 45 // 3. The worker thread sees it and goes back to normal operation. 46 // 47 // WARNING: Keep in sync with the `SNAPSHOT_SOCKET_MESSAGE_*` constants in 48 // secure_env/rust/lib.rs. 49 enum SnapshotSocketMessage : uint8_t { 50 kSuspend = 1, 51 kSuspendAck = 2, 52 kResume = 3, 53 }; 54 55 class SnapshotCommandHandler { 56 public: 57 struct SnapshotSockets { 58 SharedFD rust; 59 SharedFD keymaster; 60 SharedFD gatekeeper; 61 SharedFD oemlock; 62 }; 63 64 ~SnapshotCommandHandler(); 65 SnapshotCommandHandler(SharedFD channel_to_run_cvd, 66 SnapshotSockets snapshot_sockets); 67 68 private: 69 Result<void> SuspendResumeHandler(); 70 void Join(); 71 72 SharedFD channel_to_run_cvd_; 73 SnapshotSockets snapshot_sockets_; 74 std::thread handler_thread_; 75 }; 76 77 } // namespace cuttlefish 78