1 /**
2 * \file
3 * \brief Namespace client stub implementation
4 */
5 /*
6 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7 * Alexander Warg <warg@os.inf.tu-dresden.de>
8 * economic rights: Technische Universität Dresden (Germany)
9 *
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
13 *
14 * As a special exception, you may use this file as part of a free software
15 * library without restriction. Specifically, if other files instantiate
16 * templates or use macros or inline functions from this file, or you compile
17 * this file and link it with other files to produce an executable, this
18 * file does not by itself cause the resulting executable to be covered by
19 * the GNU General Public License. This exception does not however
20 * invalidate any other reasons why the executable file might be covered by
21 * the GNU General Public License.
22 */
23 #include <l4/re/namespace>
24
25 #include <l4/util/util.h>
26 #include <l4/sys/cxx/ipc_client>
27 #include <l4/sys/assert.h>
28
29 #include <cstring>
30
31 L4_RPC_DEF(L4Re::Namespace::query);
32 L4_RPC_DEF(L4Re::Namespace::register_obj);
33 L4_RPC_DEF(L4Re::Namespace::unlink);
34
35 namespace L4Re {
36
37 long
_query(char const * name,unsigned len,L4::Cap<void> const & target,l4_umword_t * local_id,bool iterate)38 Namespace::_query(char const *name, unsigned len,
39 L4::Cap<void> const &target,
40 l4_umword_t *local_id, bool iterate) const noexcept
41 {
42 l4_assert(target.is_valid());
43
44 L4::Cap<Namespace> ns = c();
45 L4::Ipc::Array<char const, unsigned long> _name(len, name);
46
47 while (_name.length > 0)
48 {
49 L4::Ipc::Snd_fpage cap;
50 L4::Opcode dummy;
51 int err = query_t::call(ns, _name,
52 L4::Ipc::Small_buf(target.cap(),
53 local_id
54 ? L4_RCV_ITEM_LOCAL_ID
55 : 0),
56 cap, dummy, _name);
57 if (err < 0)
58 return err;
59
60 bool const partly = err & Partly_resolved;
61 if (cap.id_received())
62 {
63 *local_id = cap.data();
64 return _name.length;
65 }
66
67 if (partly && iterate)
68 ns = L4::cap_cast<Namespace>(target);
69 else
70 return err;
71 }
72
73 return _name.length;
74 }
75
76 long
query(char const * name,unsigned len,L4::Cap<void> const & target,int timeout,l4_umword_t * local_id,bool iterate)77 Namespace::query(char const *name, unsigned len, L4::Cap<void> const &target,
78 int timeout, l4_umword_t *local_id, bool iterate) const noexcept
79 {
80 if (L4_UNLIKELY(len == 0))
81 return -L4_EINVAL;
82
83 long ret;
84 long rem = timeout;
85 long to = 0;
86
87 if (rem)
88 to = 10;
89 do
90 {
91 ret = _query(name, len, target, local_id, iterate);
92
93 if (ret >= 0)
94 return ret;
95
96 if (L4_UNLIKELY(ret != -L4_EAGAIN))
97 return ret;
98
99 if (rem == to)
100 return ret;
101
102 l4_sleep(to);
103
104 if (rem > 0)
105 {
106 rem -= to;
107 if (to > rem)
108 to = rem;
109 }
110
111 if (to < 100)
112 to += to;
113 }
114 while (486);
115 }
116
117 long
query(char const * name,L4::Cap<void> const & target,int timeout,l4_umword_t * local_id,bool iterate)118 Namespace::query(char const *name, L4::Cap<void> const &target,
119 int timeout, l4_umword_t *local_id,
120 bool iterate) const noexcept
121 {
122 return query(name, __builtin_strlen(name), target,
123 timeout, local_id, iterate);
124 }
125
126 }
127