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 16namespace 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 */ 40class Inhibitor : 41 public L4::Kobject_t<Inhibitor, L4::Kobject, L4RE_PROTO_INHIBITOR> 42{ 43public: 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(), ¤t_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} 104