]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/factory
1bb4ebfcdbdf79c7f8b8e16a34f008dd94d2d05d
[l4.git] / l4 / pkg / l4sys / include / factory
1 // vi:ft=cpp
2 /**
3  * \file
4  * \brief Common factory related definitions.
5  * \ingroup l4_api
6  */
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  *               Alexander Warg <warg@os.inf.tu-dresden.de>
10  *     economic rights: Technische Universität Dresden (Germany)
11  *
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  *
16  * As a special exception, you may use this file as part of a free software
17  * library without restriction.  Specifically, if other files instantiate
18  * templates or use macros or inline functions from this file, or you compile
19  * this file and link it with other files to produce an executable, this
20  * file does not by itself cause the resulting executable to be covered by
21  * the GNU General Public License.  This exception does not however
22  * invalidate any other reasons why the executable file might be covered by
23  * the GNU General Public License.
24  */
25
26 #pragma once
27
28 #include <l4/sys/factory.h>
29 #include <l4/sys/capability>
30
31 namespace L4 {
32
33 /**
34  * \brief C++ L4 Factory, to create all kinds of kernel objects.
35  * \ingroup l4_factory_api
36  *
37  * <c>\#include <l4/sys/factory></c>
38  *
39  * \see \ref l4_factory_api for an overview and C bindings.
40  */
41 class Factory : public Kobject_t<Factory, Kobject, L4_PROTO_FACTORY>
42 {
43   L4_KOBJECT(Factory)
44
45 public:
46
47   typedef l4_mword_t Proto;
48
49   /**
50    * \brief Special type to add a void argument into the factory create
51    *        stream.
52    */     
53   struct Nil {};
54
55   /**
56    * \brief Special type to add a pascal string into the factory create
57    *        stream.
58    *
59    * This encapsulates a string that has an explicit length.
60    */
61   struct Lstr
62   {
63     /**
64      * \brief The character buffer.
65      */
66     char const *s;
67
68     /**
69      * \brief The number of characters in the buffer.
70      */
71     int len;
72
73     Lstr(char const *s, int len) : s(s), len(len) {}
74   };
75
76   /**
77    * \brief Stream class for the create() argument stream.
78    *
79    * This stream allows a variable number of arguments to be
80    * added to a create() call.
81    */
82   class S
83   {
84   private:
85     l4_utcb_t *u;
86     l4_msgtag_t t;
87     l4_cap_idx_t f;
88
89   public:
90     /**
91      * \brief create a copy.
92      */
93     S(S const &o)
94     : u(o.u), t(o.t), f(o.f)
95     { const_cast<S&>(o).t.raw = 0; }
96
97     /**
98      * \brief create a stream for a specific create() call.
99      * \param f is the capability for the factory object (L4::Factory).
100      * \param obj is the protocol ID to describe the type of the object that
101      *            shall be created.
102      * \param target is the capabilit selector for the new object.
103      * \param utcb is the UTCB that shall be used for the operation.
104      */
105     S(l4_cap_idx_t f, long obj, L4::Cap<L4::Kobject> target,
106       l4_utcb_t *utcb) throw()
107     : u(utcb), t(l4_factory_create_start_u(obj, target.cap(), u)), f(f)
108     {}
109
110     /**
111      * \brief Commit the operation in the destructor to have a cool syntax
112      *        for create().
113      */
114     ~S()
115     {
116       if (t.raw)
117         l4_factory_create_commit_u(f, t, u);
118     }
119
120     /**
121      * \brief Explicitely commits the operation and returns the result.
122      * \return The result of the create() operation.
123      */
124     operator l4_msgtag_t ()
125     {
126       l4_msgtag_t r = l4_factory_create_commit_u(f, t, u);
127       t.raw = 0;
128       return r;
129     }
130
131     /**
132      * \brief Put a single l4_mword_t as next argument.
133      * \param i is the value to add as next argument.
134      */
135     S &operator  << (l4_mword_t i)
136     {
137       l4_factory_create_add_int_u(i, &t, u);
138       return *this;
139     }
140
141     /**
142      * \brief Put a single l4_umword_t as next argument.
143      * \param i is the value to add as next argument.
144      */
145     S &operator  << (l4_umword_t i)
146     {
147       l4_factory_create_add_uint_u(i, &t, u);
148       return *this;
149     }
150
151     /**
152      * \brief Add a zero-terminated string as next argument.
153      * \param s is the string to add as next argument.
154      */
155     S &operator << (char const *s)
156     {
157       l4_factory_create_add_str_u(s, &t, u);
158       return *this;
159     }
160
161     /**
162      * \brief Add a pascal string as next argument.
163      * \param s is the string to add as next argument.
164      */
165     S &operator << (Lstr const &s)
166     {
167       l4_factory_create_add_lstr_u(s.s, s.len, &t, u);
168       return *this;
169     }
170
171     /**
172      * \brief Add an empty argument.
173      */
174     S &operator << (Nil)
175     {
176       l4_factory_create_add_nil_u(&t, u);
177       return *this;
178     }
179
180     /**
181      * \brief Add a flex page as next argument.
182      * \param d is the flex page to add (there will be no map operation).
183      */
184     S &operator << (l4_fpage_t d)
185     {
186       l4_factory_create_add_fpage_u(d, &t, u);
187       return *this;
188     }
189   };
190
191
192 public:
193
194   /**
195    * \brief Generic create call to the factory.
196    * \param target is the target capability selector where the new
197    *               object shall be received.
198    * \param obj is the protocol ID that specifies which kind of object
199    *            shall be created.
200    * \param utcb is the UTCB to use for the operation.
201    * \return a create stream that allows adding additional arguments to the
202    *         create() call.
203    *
204    * This method does currently not directly invoke the factory. It returns a
205    * stream that shall invoke the factory after adding all additional arguments.
206    *
207    * Usage:
208    * \code
209    * L4::Cap<L4Re::Namespace> ns = L4Re::Util::cap_alloc.alloc<L4Re::Namespace>();
210    * factory->create(ns, L4Re::Namespace::Protocol) << "Argument text";
211    * \endcode
212    */
213   S create(Cap<Kobject> target, long obj, l4_utcb_t *utcb = l4_utcb()) throw()
214   {
215     return S(cap(), obj, target, utcb);
216   }
217
218   /**
219    * \copydoc l4_factory_create_task()
220    * \note \a factory is the implicit \a this pointer.
221    */
222   l4_msgtag_t create_task(Cap<Task> const & target_cap,
223                           l4_fpage_t const &utcb_area,
224                           l4_utcb_t *utcb = l4_utcb()) throw()
225   { return l4_factory_create_task_u(cap(), target_cap.cap(), utcb_area, utcb); }
226
227   /**
228    * \copydoc l4_factory_create_thread()
229    * \note \a factory is the implicit \a this pointer.
230    */
231   l4_msgtag_t create_thread(Cap<Thread> const &target_cap,
232                             l4_utcb_t *utcb = l4_utcb()) throw()
233   { return l4_factory_create_thread_u(cap(), target_cap.cap(), utcb); }
234
235   /**
236    * \copydoc l4_factory_create_factory()
237    * \note \a factory is the implicit \a this pointer.
238    */
239   l4_msgtag_t create_factory(Cap<Factory> const &target_cap,
240                              unsigned long limit,
241                              l4_utcb_t *utcb = l4_utcb()) throw()
242   { return l4_factory_create_factory_u(cap(), target_cap.cap(), limit, utcb); }
243
244   /**
245    * \copydoc l4_factory_create_gate()
246    * \note \a factory is the implicit \a this pointer.
247    */
248   l4_msgtag_t create_gate(Cap<Kobject> const &target_cap,
249                           Cap<Thread> const &thread_cap, l4_umword_t label,
250                           l4_utcb_t *utcb = l4_utcb()) throw()
251   { return l4_factory_create_gate_u(cap(), target_cap.cap(), thread_cap.cap(), label, utcb); }
252
253   /**
254    * \copydoc l4_factory_create_semaphore()
255    * \note \a factory is the implicit \a this pointer.
256    */
257   l4_msgtag_t create_semaphore(Cap<K_semaphore> const &target_cap,
258                                l4_utcb_t *utcb = l4_utcb()) throw()
259   { return l4_factory_create_semaphore_u(cap(), target_cap.cap(), utcb); }
260
261   /**
262    * \copydoc l4_factory_create_irq()
263    * \note \a factory is the implicit \a this pointer.
264    */
265   l4_msgtag_t create_irq(Cap<Irq>const &target_cap,
266                          l4_utcb_t *utcb = l4_utcb()) throw()
267   { return l4_factory_create_irq_u(cap(), target_cap.cap(), utcb); }
268
269   /**
270    * \copydoc l4_factory_create_vm()
271    * \note \a factory is the implicit \a this pointer.
272    */
273   l4_msgtag_t create_vm(Cap<Vm>const &target_cap,
274                         l4_utcb_t *utcb = l4_utcb()) throw()
275   { return l4_factory_create_vm_u(cap(), target_cap.cap(), utcb); }
276 };
277
278 }