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