extended call manager to support monitoring I/O objects
Stefan Schuermans

Stefan Schuermans commited on 2011-10-25 21:19:00
Showing 4 changed files, with 190 additions and 6 deletions.

... ...
@@ -7,6 +7,8 @@
7 7
 #include <set>
8 8
 
9 9
 #include "CallMgr.h"
10
+#include "Io.h"
11
+#include "IoCallee.h"
10 12
 #include "Time.h"
11 13
 #include "TimeCallee.h"
12 14
 
... ...
@@ -22,6 +24,58 @@ CallMgr::~CallMgr()
22 24
 {
23 25
 }
24 26
 
27
+/**
28
+ * @brief cancel callback at read I/O event
29
+ * @param[in] callee whom not to call
30
+ * @param[in] io I/O object not to monitor for readability any more
31
+ */
32
+void CallMgr::cancelIoReadCall(IoCallee *callee, Io *io)
33
+{
34
+  // remove callee for this I/O object
35
+  IoCallees &callees = m_iosRead[io];
36
+  callees.erase(callee);
37
+
38
+  // no more callees -> remove I/O object
39
+  if (callees.empty())
40
+    m_iosRead.erase(io);
41
+}
42
+
43
+/**
44
+ * @brief request callback at read I/O event
45
+ * @param[in] callee whom to call
46
+ * @param[in] io I/O object to monitor for readability
47
+ */
48
+void CallMgr::requestIoReadCall(IoCallee *callee, Io *io)
49
+{
50
+  m_iosRead[io].insert(callee);
51
+}
52
+
53
+/**
54
+ * @brief cancel callback at write I/O event
55
+ * @param[in] callee whom not to call
56
+ * @param[in] io I/O object not to monitor for writability any more
57
+ */
58
+void CallMgr::cancelIoWriteCall(IoCallee *callee, Io *io)
59
+{
60
+  // remove callee for this I/O object
61
+  IoCallees &callees = m_iosWrite[io];
62
+  callees.erase(callee);
63
+
64
+  // no more callees -> remove I/O object
65
+  if (callees.empty())
66
+    m_iosWrite.erase(io);
67
+}
68
+
69
+/**
70
+ * @brief request callback at write I/O event
71
+ * @param[in] callee whom to call
72
+ * @param[in] io I/O object to monitor for writability
73
+ */
74
+void CallMgr::requestIoWriteCall(IoCallee *callee, Io *io)
75
+{
76
+  m_iosWrite[io].insert(callee);
77
+}
78
+
25 79
 /**
26 80
  * @brief cancel callback at certain time
27 81
  * @param[in] callee whom not to call
... ...
@@ -60,23 +114,51 @@ void CallMgr::requestTimeCall(TimeCallee *callee, const Time &time)
60 114
 /// run call manager
61 115
 void CallMgr::run()
62 116
 {
63
-  while (!m_times.empty()) {
117
+  while (!m_times.empty() || !m_iosRead.empty() || !m_iosWrite.empty()) {
118
+
119
+    // get time until first call time
120
+    Time timeout = m_times.begin()->first - Time::now();
64 121
 
65
-    // wait until next time is reached
66
-    m_times.begin()->first.sleepUntil();
122
+    // time already passed or reached
123
+    if (timeout <= Time::zero) {
67 124
 
68
-    // get callees and remove entry from time map
125
+      // get time callees and remove entry from time map
69 126
       TimeCallees timeCallees = m_times.begin()->second;
70 127
       m_times.erase(m_times.begin());
71 128
 
72
-    // call callees
129
+      // call time callees
73 130
       TimeCallees::const_iterator itTC;
74 131
       for (itTC = timeCallees.begin(); itTC != timeCallees.end(); ++itTC) {
75 132
         m_timeCallees.erase(*itTC); // first remove request from callee map
76 133
         (*itTC)->timeCall(); // then call callee
77 134
       }
78 135
 
79
-  } // while m_times
136
+    } // if timeout
137
+
138
+    // wait for I/O events
139
+    IoMap::const_iterator itM;
140
+    Io::Set rd, wr;
141
+    for (itM = m_iosRead.begin(); itM != m_iosRead.end(); ++itM)
142
+      rd.insert(itM->first);
143
+    for (itM = m_iosWrite.begin(); itM != m_iosWrite.end(); ++itM)
144
+      wr.insert(itM->first);
145
+    Io::wait(rd, wr, timeout);
146
+
147
+    // call I/O callees with pending events
148
+    Io::Set::const_iterator itS;
149
+    IoCallees::const_iterator itIC;
150
+    for (itS = rd.begin(); itS != rd.end(); ++itS) {
151
+      const IoCallees &ioCallees = m_iosRead[*itS];
152
+      for (itIC = ioCallees.begin(); itIC != ioCallees.end(); ++itIC)
153
+        (*itIC)->ioReadCall(*itS);
154
+    }
155
+    for (itS = wr.begin(); itS != wr.end(); ++itS) {
156
+      const IoCallees &ioCallees = m_iosWrite[*itS];
157
+      for (itIC = ioCallees.begin(); itIC != ioCallees.end(); ++itIC)
158
+        (*itIC)->ioWriteCall(*itS);
159
+    }
160
+
161
+  } // while m_times m_iosRead m_iosWrite
80 162
 }
81 163
 
82 164
 } // namespace Blinker
... ...
@@ -9,6 +9,8 @@
9 9
 #include <map>
10 10
 #include <set>
11 11
 
12
+#include "Io.h"
13
+#include "IoCallee.h"
12 14
 #include "Time.h"
13 15
 #include "TimeCallee.h"
14 16
 
... ...
@@ -18,6 +20,11 @@ namespace Blinker {
18 20
 class CallMgr
19 21
 {
20 22
 protected:
23
+  /// set of I/O callees to call for a certain I/O object
24
+  typedef std::set<IoCallee *> IoCallees;
25
+  /// what set of I/O callees to call for a certain I/O object
26
+  typedef std::map<Io *, IoCallees> IoMap;
27
+
21 28
   /// set of time callees to call at a certain time
22 29
   typedef std::set<TimeCallee *> TimeCallees;
23 30
   /// what set of time callees to call at a certain time
... ...
@@ -40,6 +47,34 @@ private:
40 47
   const CallMgr & operator=(const CallMgr &that);
41 48
 
42 49
 public:
50
+  /**
51
+   * @brief cancel callback at read I/O event
52
+   * @param[in] callee whom not to call
53
+   * @param[in] io I/O object not to monitor for readability any more
54
+   */
55
+  void cancelIoReadCall(IoCallee *callee, Io *io);
56
+
57
+  /**
58
+   * @brief request callback at read I/O event
59
+   * @param[in] callee whom to call
60
+   * @param[in] io I/O object to monitor for readability
61
+   */
62
+  void requestIoReadCall(IoCallee *callee, Io *io);
63
+
64
+  /**
65
+   * @brief cancel callback at write I/O event
66
+   * @param[in] callee whom not to call
67
+   * @param[in] io I/O object not to monitor for writability any more
68
+   */
69
+  void cancelIoWriteCall(IoCallee *callee, Io *io);
70
+
71
+  /**
72
+   * @brief request callback at write I/O event
73
+   * @param[in] callee whom to call
74
+   * @param[in] io I/O object to monitor for writability
75
+   */
76
+  void requestIoWriteCall(IoCallee *callee, Io *io);
77
+
43 78
   /**
44 79
    * @brief cancel callback at certain time
45 80
    * @param[in] callee whom not to call
... ...
@@ -59,6 +94,11 @@ public:
59 94
   void run();
60 95
 
61 96
 protected:
97
+  /// what I/O callees to call for readability on a certain I/O object
98
+  IoMap m_iosRead;
99
+  /// what I/O callees to call for writability on a certain I/O object
100
+  IoMap m_iosWrite;
101
+
62 102
   /// what time callees to call at a certain time
63 103
   TimeMap m_times;
64 104
   /// when to call time callees
... ...
@@ -0,0 +1,22 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include "Io.h"
7
+#include "IoCallee.h"
8
+
9
+namespace Blinker {
10
+
11
+/// constructor
12
+IoCallee::IoCallee()
13
+{
14
+}
15
+
16
+/// destructor
17
+IoCallee::~IoCallee()
18
+{
19
+}
20
+
21
+} // namespace Blinker
22
+
... ...
@@ -0,0 +1,40 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef IOCALLEE_H
7
+#define IOCALLEE_H
8
+
9
+#include "Io.h"
10
+
11
+namespace Blinker {
12
+
13
+/// I/O callee interface (i.e. called on I/O event)
14
+class IoCallee
15
+{
16
+public:
17
+  /// constructor
18
+  IoCallee();
19
+
20
+  /// destructor
21
+  virtual ~IoCallee();
22
+
23
+public:
24
+  /**
25
+   * @brief callback when I/O object is readable
26
+   * @param[in] io I/O object that is readable
27
+   */
28
+  virtual void ioReadCall(Io *io) = 0;
29
+
30
+  /**
31
+   * @brief callback when I/O object is writable
32
+   * @param[in] io I/O object that is writable
33
+   */
34
+  virtual void ioWriteCall(Io *io) = 0;
35
+}; // class IoCallee
36
+
37
+} // namespace Blinker
38
+
39
+#endif // #ifndef IOCALLEE_H
40
+
0 41