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