add support for python threads (python threads are just running when the mainloop
[enigma2.git] / lib / base / message.h
1 #ifndef __lib_base_message_h
2 #define __lib_base_message_h
3
4 #include <lib/base/ebase.h>
5 #include <lib/python/connections.h>
6 #include <lib/python/swig.h>
7 #include <unistd.h>
8 #include <lib/base/elock.h>
9
10
11 /**
12  * \brief A generic messagepump.
13  *
14  * You can send and receive messages with this class. Internally a fifo is used,
15  * so you can use them together with a \c eMainloop.
16  */
17 #ifndef SWIG
18 class eMessagePump
19 {
20         int fd[2];
21         eLock content;
22         int ismt;
23 public:
24         eMessagePump(int mt=0);
25         virtual ~eMessagePump();
26 protected:
27         int send(const void *data, int len);
28         int recv(void *data, int len); // blockierend
29         int getInputFD() const;
30         int getOutputFD() const;
31 };
32
33 /**
34  * \brief A messagepump with fixed-length packets.
35  *
36  * Based on \ref eMessagePump, with this class you can send and receive fixed size messages.
37  * Automatically creates a eSocketNotifier and gives you a callback.
38  */
39 template<class T>
40 class eFixedMessagePump: private eMessagePump, public Object
41 {
42         eSocketNotifier *sn;
43         void do_recv(int)
44         {
45                 T msg;
46                 recv(&msg, sizeof(msg));
47                 /*emit*/ recv_msg(msg);
48         }
49 public:
50         Signal1<void,const T&> recv_msg;
51         void send(const T &msg)
52         {
53                 eMessagePump::send(&msg, sizeof(msg));
54         }
55         eFixedMessagePump(eMainloop *context, int mt): eMessagePump(mt)
56         {
57                 sn=new eSocketNotifier(context, getOutputFD(), eSocketNotifier::Read);
58                 CONNECT(sn->activated, eFixedMessagePump<T>::do_recv);
59                 sn->start();
60         }
61         ~eFixedMessagePump()
62         {
63                 delete sn;
64                 sn=0;
65         }
66         void start() { if (sn) sn->start(); }
67         void stop() { if (sn) sn->stop(); }
68 };
69 #endif
70
71 class ePythonMessagePump: public eMessagePump, public Object
72 {
73         eSocketNotifier *sn;
74         void do_recv(int)
75         {
76                 int msg;
77                 recv(&msg, sizeof(msg));
78                 /*emit*/ recv_msg(msg);
79         }
80 public:
81         PSignal1<void,int> recv_msg;
82         void send(int msg)
83         {
84                 eMessagePump::send(&msg, sizeof(msg));
85         }
86         ePythonMessagePump()
87                 :eMessagePump(1)
88         {
89                 eDebug("add python messagepump %p", this);
90                 sn=new eSocketNotifier(eApp, getOutputFD(), eSocketNotifier::Read);
91                 CONNECT(sn->activated, ePythonMessagePump::do_recv);
92                 sn->start();
93         }
94         ~ePythonMessagePump()
95         {
96                 eDebug("remove python messagepump %p", this);
97                 delete sn;
98                 sn=0;
99         }
100         void start() { if (sn) sn->start(); }
101         void stop() { if (sn) sn->stop(); }
102 };
103
104 #endif