PPI: Implement IOEvent error handling
g0dil [Wed, 29 Aug 2007 22:21:24 +0000 (22:21 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@417 270642c3-0616-0410-b53a-bc976706d245

PPI/IOEvent.cc
PPI/IOEvent.hh
Scheduler/Scheduler.cc
senf.dict

index 2010b6b..b63ca24 100644 (file)
@@ -52,8 +52,18 @@ prefix_ void senf::ppi::IOEvent::v_disable()
 
 prefix_ void senf::ppi::IOEvent::cb(int, Scheduler::EventId event)
 {
-    IOEventInfo info = { event };
-    callback(info);
+    if ((event & ~events_) != 0) {
+        if (event & Err)
+            throw ErrorException();
+        else if (event & Hup)
+            throw HangupException();
+        else
+            // This cannot happen.
+            BOOST_ASSERT(false);
+    } else {
+        IOEventInfo info = { event };
+        callback(info);
+    }
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index d36fcb7..ad239b8 100644 (file)
@@ -52,8 +52,6 @@ namespace ppi {
         An IOEvent is signaled, whenever the FileHandle \a handle becomes readable or writable. The
         type of event is specified using the \a events mask with values from EventFlags.
 
-        \fixme Implement error/EOF handling
-
         \see IOEventInfo
 
         \ingroup event_group
@@ -65,8 +63,14 @@ namespace ppi {
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
+        // This is stupid, however there is no way to import the Scheduler::EventId enum together
+        // with the enumeration symbols
+
         enum EventFlags { Read  = Scheduler::EV_READ, 
-                          Write = Scheduler::EV_WRITE };
+                          Prio = Scheduler::EV_PRIO,
+                          Write = Scheduler::EV_WRITE,
+                          Hup = Scheduler::EV_HUP,
+                          Err = Scheduler::EV_ERR };
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
@@ -78,11 +82,21 @@ namespace ppi {
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
+        /** \brief Unhandled error condition */
+        struct ErrorException : public std::exception
+        { virtual char const * what() const throw() 
+                { return "senf::ppi::IOEvent::ErrorException"; } };
+
+        /** \brief Unhandled hangup condition */
+        struct HangupException : public std::exception
+        { virtual char const * what() const throw() 
+                { return "senf::ppi::IOEvent::HangupException"; } };
+
     protected:
 
     private:
         virtual void v_enable();
-        virtual void v_disable();
+         virtual void v_disable();
         
         void cb(int, Scheduler::EventId event);
 
index 35155e3..c758ea9 100644 (file)
@@ -157,6 +157,9 @@ prefix_ void senf::Scheduler::process()
     eventTime_ = ClockService::now();
     while (! terminate_) {
 
+        // Since a callback may have disabled further timers, we need to check for canceled timeouts
+        // again.
+
         while (! timerQueue_.empty()) {
             TimerMap::iterator i (timerQueue_.top());
             if (! i->second.canceled)
@@ -187,7 +190,8 @@ prefix_ void senf::Scheduler::process()
 
         // We always run event handlers. This is important, even if a file-descriptor is signaled
         // since some descriptors (e.g. real files) will *always* be ready and we still may want to
-        // handle timers
+        // handle timers.
+        // Time handlers are run before file events to not delay them unnecessarily.
 
         while (! timerQueue_.empty()) {
             TimerMap::iterator i (timerQueue_.top());
index 0b1126a..6ed1733 100644 (file)
--- a/senf.dict
+++ b/senf.dict
@@ -55,7 +55,9 @@ DNS
 dontinclude
 ElementParser
 endcode
+enum
 eof
+ErrorException
 eth
 ethernet
 EthernetPacket
@@ -67,6 +69,8 @@ EUI
 EUID
 EventBinding
 EventDescriptor
+EventFlags
+EventId
 EventImplementation
 EventManager
 eventsPerInterval
@@ -87,6 +91,8 @@ ForwardingRoute
 fraunhofer
 fuer
 GlobalScope
+hangup
+HangupException
 hh
 hideinitializer
 Hmm
@@ -114,6 +120,7 @@ IntervalTimer
 IntField
 InvalidPacketChainException
 IOEvent
+IOEventInfo
 ip
 IpV
 ipv
@@ -270,6 +277,7 @@ udpReader
 udpWriter
 UInt
 UIntField
+Unhandled
 unicast
 unthrottle
 unthrottled