Line data Source code
1 : /********************************************************************************
2 : * Copyright (c) 2024 Accenture
3 : *
4 : * This program and the accompanying materials are made available under the
5 : * terms of the Apache License Version 2.0 which is available at
6 : * https://www.apache.org/licenses/LICENSE-2.0
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : ********************************************************************************/
10 :
11 : /**
12 : * \ingroup async
13 : */
14 : #pragma once
15 :
16 : #include "interrupts/suspendResumeAllInterrupts.h"
17 :
18 : namespace async
19 : {
20 : /**
21 : * A synchronization mechanism that blocks threads from accessing a resource.
22 : *
23 : * The `ModifiableLock` class ensures mutual exclusion,
24 : * allowing only one thread to access a protected
25 : * resource or function at a time. When a thread acquires the lock,
26 : * any other thread attempting to acquire it is blocked until the lock is released.
27 : * The lock can be acquired either in the constructor or on demand using the `lock` function.
28 : * Similarly, the lock can be released either in the destructor or on demand using the `unlock`
29 : * function.
30 : */
31 : class ModifiableLock final
32 : {
33 : public:
34 : ModifiableLock();
35 : ~ModifiableLock();
36 :
37 : void unlock();
38 : void lock();
39 :
40 : private:
41 : ::OldIntEnabledStatusValueType _oldIntEnabledStatusValue;
42 : bool _isLocked;
43 : };
44 :
45 : /**
46 : * Inline implementations.
47 : */
48 3 : inline ModifiableLock::ModifiableLock()
49 3 : : _oldIntEnabledStatusValue(::getOldIntEnabledStatusValueAndSuspendAllInterrupts()), _isLocked(true)
50 3 : {}
51 :
52 3 : inline ModifiableLock::~ModifiableLock()
53 : {
54 3 : if (_isLocked)
55 : {
56 2 : ::resumeAllInterrupts(_oldIntEnabledStatusValue);
57 : }
58 3 : }
59 :
60 3 : inline void ModifiableLock::unlock()
61 : {
62 3 : if (_isLocked)
63 : {
64 2 : ::resumeAllInterrupts(_oldIntEnabledStatusValue);
65 2 : _isLocked = false;
66 : }
67 3 : }
68 :
69 2 : inline void ModifiableLock::lock()
70 : {
71 2 : if (!_isLocked)
72 : {
73 1 : _oldIntEnabledStatusValue = ::getOldIntEnabledStatusValueAndSuspendAllInterrupts();
74 1 : _isLocked = true;
75 : }
76 2 : }
77 :
78 : } // namespace async
|