L4Re - L4 Runtime Environment
inhibitor
1 // vim:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
4  *
5  * This file is licensed under the terms of the GNU Lesser General
6  * Public License 2.1.
7  * See the file COPYING-LGPL-2.1 for details.
8  */
9 #pragma once
10 
11 #include <l4/sys/capability>
12 #include <l4/sys/cxx/ipc_iface>
13 #include <l4/sys/cxx/ipc_string>
14 #include <l4/re/protocols.h>
15 
16 namespace L4Re {
17 
18 /**
19  * \brief Set of inhibitor locks, which inhibit specific actions when held.
20  *
21  * This interface provides access to a set of inhibitor locks, each determined
22  * by an ID that is specific to the Inhibitor object. Each individual lock
23  * shall prevent, a specific (implementation defined) action to be executed, as
24  * long as the lock is held.
25  *
26  * For example there can be an inhibitor lock to prevent a transition to
27  * suspend-to-RAM state and a different one to prevent shutdown.
28  *
29  * A client shall take an inhibitor lock if it needs to execute code
30  * before the action is taken. For example a lock-screen application shall grab
31  * an inhibitor lock for the suspend action to be able to lock the screen
32  * before the system goes to sleep.
33  *
34  * Inhibitor locks are usually closely related to specific events. Usually a
35  * server automatically subscribes a client holding a lock to the corresponding
36  * event. The server shall send the event to inform the client that an action
37  * is pending. Upon reception of the event, the client is supposed to release
38  * the corresponding inhibitor lock.
39  */
40 class Inhibitor :
41  public L4::Kobject_t<Inhibitor, L4::Kobject, L4RE_PROTO_INHIBITOR>
42 {
43 public:
44  enum
45  {
46  Name_max = 20 ///< The maximum length of a lock's name.
47  };
48 
49  /**
50  * \brief Acquire a specific inhibitor lock.
51  *
52  * \param id ID of the inhibitor lock that the client intends to acquire
53  * \param reason The reason why you need the lock. Used for informing the
54  * user or debugging.
55  *
56  * \retval 0 Success
57  * \retval -L4_ENODEV The specified `id` does not exist.
58  */
59  L4_INLINE_RPC(long, acquire, (l4_umword_t id, L4::Ipc::String<> reason));
60 
61  /**
62  * \brief Release a specific inhibitor lock.
63  *
64  * \param id The ID of the inhibitor lock to release.
65  *
66  * \retval 0 Success
67  * \retval -L4_ENODEV Lock with the given `id` does not exist.
68  */
69  L4_INLINE_RPC(long, release, (l4_umword_t id));
70 
71  /**
72  * \brief Get information for the next available inhibitor lock.
73  *
74  * \param name A pointer to a buffer for the name of the lock.
75  * \param len The length of the available buffer (usually #Name_max
76  * is used)
77  * \param current_id The ID of the last available lock, use -1 to get the
78  * first lock.
79  * \param utcb The UTCB to use for the message.
80  *
81  * \retval >0 The ID of the next available lock if there is one (in
82  * this case `name` shall contain the name of the
83  * inhibitor lock).
84  * \retval -L4_ENODEV There are no more locks.
85  */
86  long next_lock_info(char *name, unsigned len, l4_mword_t current_id = -1,
87  l4_utcb_t *utcb = l4_utcb())
88  {
89  L4::Ipc::String<char> name_buf(len , name);
90  long r = next_lock_info_t::call(c(), &current_id, name_buf, utcb);
91  if (r < 0)
92  return r;
93 
94  return current_id;
95  }
96 
97  L4_INLINE_RPC_NF(long, next_lock_info, (L4::Ipc::In_out<l4_mword_t *> current_id,
98  L4::Ipc::String<char> &name));
99 
100  typedef L4::Typeid::Rpcs<acquire_t, release_t, next_lock_info_t> Rpcs;
101 };
102 
103 }