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 
17 #ifndef BERBERIS_GUEST_OS_PRIMITIVES_SCOPED_PENDING_SIGNALS_H_
18 #define BERBERIS_GUEST_OS_PRIMITIVES_SCOPED_PENDING_SIGNALS_H_
19 
20 #include "berberis/base/checks.h"
21 #include "berberis/base/macros.h"
22 #include "berberis/guest_os_primitives/guest_thread.h"
23 
24 namespace berberis {
25 
26 // Can be used when pending signals are disabled or enabled.
27 class ScopedPendingSignalsEnabler {
28  public:
ScopedPendingSignalsEnabler(GuestThread * thread)29   explicit ScopedPendingSignalsEnabler(GuestThread* thread) : thread_(thread) {
30     prev_pending_signals_enabled_ = thread_->TestAndEnablePendingSignals();
31   }
32 
~ScopedPendingSignalsEnabler()33   ~ScopedPendingSignalsEnabler() {
34     if (!prev_pending_signals_enabled_) {
35       CHECK_EQ(true, thread_->ProcessAndDisablePendingSignals());
36     }
37   }
38 
39  private:
40   GuestThread* thread_;
41   bool prev_pending_signals_enabled_;
42 
43   DISALLOW_COPY_AND_ASSIGN(ScopedPendingSignalsEnabler);
44 };
45 
46 // Can be used when pending signals are disabled or enabled.
47 class ScopedPendingSignalsDisabler {
48  public:
ScopedPendingSignalsDisabler(GuestThread * thread)49   explicit ScopedPendingSignalsDisabler(GuestThread* thread) : thread_(thread) {
50     prev_pending_signals_enabled_ = thread_->ProcessAndDisablePendingSignals();
51   }
52 
~ScopedPendingSignalsDisabler()53   ~ScopedPendingSignalsDisabler() {
54     if (prev_pending_signals_enabled_) {
55       CHECK_EQ(false, thread_->TestAndEnablePendingSignals());
56     }
57   }
58 
59  private:
60   GuestThread* thread_;
61   bool prev_pending_signals_enabled_;
62 
63   DISALLOW_COPY_AND_ASSIGN(ScopedPendingSignalsDisabler);
64 };
65 
66 }  // namespace berberis
67 
68 #endif  // BERBERIS_GUEST_OS_PRIMITIVES_SCOPED_PENDING_SIGNALS_H_
69