]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re/util/include/event_buffer
d4a256baace52a7186b6e58fc68ed8b70e35f4c9
[l4.git] / l4 / pkg / l4re / util / include / event_buffer
1 // set vi:ft=cpp:
2 /*
3  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  *               Alexander Warg <warg@os.inf.tu-dresden.de>
5  *     economic rights: Technische Universität Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  *
11  * As a special exception, you may use this file as part of a free software
12  * library without restriction.  Specifically, if other files instantiate
13  * templates or use macros or inline functions from this file, or you compile
14  * this file and link it with other files to produce an executable, this
15  * file does not by itself cause the resulting executable to be covered by
16  * the GNU General Public License.  This exception does not however
17  * invalidate any other reasons why the executable file might be covered by
18  * the GNU General Public License.
19  */
20
21 #pragma once
22
23 #include <l4/re/event>
24 #include <l4/re/event-sys.h>
25 #include <l4/re/rm>
26
27 #include <cstring>
28
29 namespace L4Re { namespace Util {
30
31 /**
32  * \brief Event_buffer utility class.
33  * \ingroup api_l4re_util
34  */
35 template< typename PAYLOAD >
36 class Event_buffer_t : public L4Re::Event_buffer_t<PAYLOAD>
37 {
38 private:
39   void *_buf;
40 public:
41   /**
42    * \brief Return the buffer.
43    *
44    * \return Pointer to the event buffer.
45    */
46   void *buf() const throw() { return _buf; }
47
48   /**
49    * \brief Attach event buffer from address space.
50    *
51    * \param ds   Dataspace of the event buffer.
52    * \param rm   Region manager to attach buffer to.
53    *
54    * \return 0 on success, negative error code otherwise.
55    */
56   long attach(L4::Cap<L4Re::Dataspace> ds, L4::Cap<L4Re::Rm> rm) throw()
57   {
58     l4_addr_t sz = ds->size();
59     _buf = 0;
60
61     long r = rm->attach(&_buf, sz, L4Re::Rm::Search_addr, ds);
62     if (r < 0)
63       return r;
64
65     *(L4Re::Event_buffer_t<PAYLOAD>*)this = L4Re::Event_buffer_t<PAYLOAD>(_buf, sz);
66     return 0;
67   }
68
69   /**
70    * \brief Detach event buffer from address space.
71    *
72    * \param rm   Region manager to detach buffer from.
73    * \param buf  Buffer pointer.
74    *
75    * \return 0 on success, negative error code otherwise.
76    */
77   long detach(L4::Cap<L4Re::Rm> rm, void *buf) throw()
78   {
79     L4::Cap<L4Re::Dataspace> ds;
80     return rm->detach(buf, &ds);
81   }
82
83 };
84
85 /**
86  * \brief An event buffer consumer.
87  * \ingroup api_l4re_util
88  */
89 template< typename PAYLOAD >
90 class Event_buffer_consumer_t : public Event_buffer_t<PAYLOAD>
91 {
92 public:
93
94   /**
95    * \brief Call function on every available event.
96    *
97    * \param cb  Function callback.
98    */
99   template< typename CB >
100   void foreach_available_event(CB const &cb) throw()
101   {
102     typename Event_buffer_t<PAYLOAD>::Event *e;
103     while ((e = Event_buffer_t<PAYLOAD>::next()))
104       {
105         cb(e);
106         e->free();
107       }
108   }
109
110   /**
111    * \brief Continuously wait for events and process them.
112    *
113    * \param irq    Event signal to wait for.
114    * \param thread Thread capability of the thread calling this function.
115    * \param cb     Callback function that is called for each received event.
116    *
117    * \note This function never returns.
118    */
119   template< typename CB >
120   void process(L4::Cap<L4::Irq> irq,
121                L4::Cap<L4::Thread> thread,
122                CB const &cb) throw()
123   {
124
125     if (l4_error(irq->attach(0, thread)))
126       return;
127
128     while (1)
129       {
130         long r;
131         r = l4_ipc_error(l4_irq_receive(irq.cap(), L4_IPC_NEVER),
132                          l4_utcb());
133         if (r)
134           continue;
135
136         foreach_available_event(cb);
137       }
138   }
139 };
140
141 typedef Event_buffer_t<Default_event_payload> Event_buffer;
142 typedef Event_buffer_consumer_t<Default_event_payload> Event_buffer_consumer;
143
144 }}