]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/io/server/src/inhibitor_mux.cc
Update
[l4.git] / l4 / pkg / io / io / server / src / inhibitor_mux.cc
1 #include "inhibitor_mux.h"
2 #include <l4/sys/err.h>
3 #include <cstring>
4
5 Inhibitor_provider::Inhibitor_provider(Inhibitor_mux *mux)
6 : _mux(mux)
7 {
8   _mux->_clients.add(this);
9   for (unsigned i = 0; i < L4VBUS_INHIBITOR_MAX; ++i)
10     {
11       _inhibitor_acquired[i] = false;
12       _inhibitor_reason[i][0] = 0;
13     }
14 }
15
16 Inhibitor_provider::~Inhibitor_provider()
17 {
18   _mux->_clients.remove(this);
19
20   for (unsigned i = 0; i < L4VBUS_INHIBITOR_MAX; ++i)
21     if (_inhibitor_acquired[i])
22       _mux->inhibitor_release(i);
23 }
24
25 void
26 Inhibitor_provider::inhibitor_acquire(l4_umword_t id, char const *reason)
27 {
28   if (id >= L4VBUS_INHIBITOR_MAX)
29     throw -L4_ERANGE;
30
31   if (_inhibitor_acquired[id])
32     return; // already acquired, just ignore
33
34   unsigned long len = sizeof (_inhibitor_reason[id]);
35   strncpy(_inhibitor_reason[id], reason, len);
36   _inhibitor_reason[id][len - 1] = 0;
37   _inhibitor_acquired[id] = true;
38   _mux->inhibitor_acquire(id);
39 }
40
41 /**
42  * \brief Release an inhibitor lock and unsubscribe the client from the
43  *        corresponding signal.
44  *
45  * \param id Id of inhibitor lock to release.
46  */
47 void
48 Inhibitor_provider::inhibitor_release(l4_umword_t id)
49 {
50   if (id >= L4VBUS_INHIBITOR_MAX)
51     throw -L4_ERANGE;
52
53   if (!_inhibitor_acquired[id])
54     return; // not acquired, just ignore
55
56   _inhibitor_acquired[id] = false;
57   _inhibitor_reason[id][0] = 0;
58   _mux->inhibitor_release(id);
59 }
60
61 /**
62  * \brief Tell the mux that a client has taken a lock.
63  *
64  * Called by the Inhibitor_provider.
65  *
66  * \param id Id of lock that was taken.
67  */
68 void
69 Inhibitor_mux::inhibitor_acquire(l4_umword_t id)
70 {
71   if (id >= L4VBUS_INHIBITOR_MAX)
72     throw -L4_ERANGE;
73
74   ++_inhibitors_acquired[id];
75 }
76
77 /**
78  * \brief Tell the mux that a client released a lock.
79  *
80  * Called by the Inhibitor_provider. If the released lock was the last of its
81  * kind being held, all_inhibitors_free(type) will be called.
82  *
83  * \param id ID of the inhibitor_lock that was released.
84  */
85 void
86 Inhibitor_mux::inhibitor_release(l4_umword_t id)
87 {
88   if (id >= L4VBUS_INHIBITOR_MAX)
89     throw -L4_ERANGE;
90
91   if (!--_inhibitors_acquired[id])
92     all_inhibitors_free(id);
93 }
94