<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -50,7 +50,9 @@ data EventLoop = forall a. Backend a =&gt; EventLoop
 new :: IO EventLoop
 new = do
 #ifdef BACKEND_KQUEUE
-    be &lt;- KQueue.new  -- TODO: Detect backend to use.
+    be &lt;- KQueue.new
+#elif  BACKEND_EPOLL
+    be &lt;- EPoll.new
 #endif
     cbs &lt;- stToIO V.empty
     return $ EventLoop be cbs</diff>
      <filename>src/System/Event.hs</filename>
    </modified>
    <modified>
      <diff>@@ -2,31 +2,51 @@
 
 module System.Event.EPoll where
 
+#include &lt;sys/epoll.h&gt;
+
+import Control.Monad (liftM2, when)
 import Data.Bits ((.|.))
 import Foreign.C.Error (throwErrnoIfMinus1)
 import Foreign.C.Types (CInt, CUInt)
+import Foreign.Marshal.Error (void)
+import Foreign.Marshal.Utils (with)
 import Foreign.Ptr (Ptr)
+import Foreign.Storable (Storable(..))
 
-#include &lt;sys/epoll.h&gt;
+import qualified System.Event.Array    as A
+import qualified System.Event.Internal as E
 
 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
 newtype EPollFd = EPollFd
     { unEPollFd :: CInt
-    } deriving (Eq, Show)
+    }
 
 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
 data Event = Event
     { eventTypes :: EventType
-    , eventData  :: Ptr ()
-    } deriving Show
+    , eventFd    :: CInt
+    }
+
+instance Storable Event where
+    sizeOf    _ = #size struct epoll_event
+    alignment _ = alignment (undefined :: CInt)
+
+    peek ptr = do
+        ets &lt;- #{peek struct epoll_event, events} ptr
+        ed  &lt;- #{peek struct epoll_event, data}   ptr
+        return $ Event (EventType ets) ed
+
+    poke ptr e = do
+        #{poke struct epoll_event, events} ptr (unEventType $ eventTypes e)
+        #{poke struct epoll_event, data}   ptr (eventFd e)
 
 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
 newtype ControlOp = ControlOp
     { unControlOp :: CInt
-    } deriving (Eq, Show)
+    }
 
 #{enum ControlOp, ControlOp
  , controlOpAdd    = EPOLL_CTL_ADD
@@ -38,7 +58,7 @@ newtype ControlOp = ControlOp
 
 newtype EventType = EventType
     { unEventType :: CUInt
-    } deriving (Eq, Show)
+    }
 
 #{enum EventType, EventType
  , eventTypeReadyForRead           = EPOLLIN
@@ -56,41 +76,83 @@ combineEventTypes = EventType . foldr ((.|.) . unEventType) 0
 
 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
-foreign import ccall unsafe &quot;epoll.h epoll_create&quot;
-    c_epoll_create :: CInt -&gt; IO EPollFd
+foreign import ccall unsafe &quot;ep.h epoll_create&quot;
+    c_epoll_create :: CInt -&gt; IO CInt
 
-foreign import ccall unsafe &quot;epoll.h epoll_ctl&quot;
-    c_epoll_ctl :: EPollFd -&gt; CInt -&gt; CInt -&gt; Ptr Event -&gt; IO CInt
+foreign import ccall unsafe &quot;ep.h epoll_ctl&quot;
+    c_epoll_ctl :: CInt -&gt; CInt -&gt; CInt -&gt; Ptr Event -&gt; IO CInt
 
-foreign import ccall unsafe &quot;epoll.h epoll_wait&quot;
-    c_epoll_wait :: EPollFd -&gt; Ptr Event -&gt; CInt -&gt; CInt -&gt; IO CInt
+foreign import ccall unsafe &quot;ep.h epoll_wait&quot;
+    c_epoll_wait :: CInt -&gt; Ptr Event -&gt; CInt -&gt; CInt -&gt; IO CInt
 
 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
 epollCreate :: IO EPollFd
 epollCreate =
-    EPollFd `fmap` throwErrnoIfMinus1
-                     &quot;epollCreate&quot;
-                     (unEPollFd `fmap` c_epoll_create size)
+    EPollFd `fmap` throwErrnoIfMinus1 &quot;epollCreate&quot; (c_epoll_create size)
   where
     -- From manpage EPOLL_CREATE(2): &quot;Since Linux 2.6.8, the size argument is
     -- unused. (The kernel dynamically sizes the required data structures without
     -- needing this initial hint.)&quot; We pass 256 because libev does.
     size = 256 :: CInt
 
-epollControl :: EPollFd -&gt; ControlOp -&gt; CInt -&gt; Ptr Event -&gt; IO CInt
-epollControl epfd op fd events =
-    throwErrnoIfMinus1
-      &quot;epollControl&quot;
-      (c_epoll_ctl epfd (unControlOp op) fd events)
+epollControl :: EPollFd -&gt; ControlOp -&gt; CInt -&gt; Ptr Event -&gt; IO ()
+epollControl epfd op fd event =
+    void $
+      throwErrnoIfMinus1
+        &quot;epollControl&quot;
+        (c_epoll_ctl (unEPollFd epfd) (unControlOp op) fd event)
 
-epollWait :: EPollFd -&gt; Ptr Event -&gt; Int -&gt; Int -&gt; IO CInt
+epollWait :: EPollFd -&gt; Ptr Event -&gt; Int -&gt; Int -&gt; IO Int
 epollWait epfd events maxNumEvents maxNumMilliseconds =
-    throwErrnoIfMinus1
-      &quot;epollWait&quot;
-      (c_epoll_wait
-         epfd
-         events
-         (fromIntegral maxNumEvents)
-         (fromIntegral maxNumMilliseconds)
-      )
+    fmap fromIntegral $
+      throwErrnoIfMinus1
+        &quot;epollWait&quot;
+        (c_epoll_wait
+           (unEPollFd epfd)
+           events
+           (fromIntegral maxNumEvents)
+           (fromIntegral maxNumMilliseconds)
+        )
+
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+data EPoll = EPoll
+    { epollEpfd   :: !EPollFd
+    , epollEvents :: !(A.Array Event)
+    }
+
+instance E.Backend EPoll where
+    new  = new
+    set  = set
+    poll = poll
+
+new :: IO EPoll
+new = liftM2 EPoll epollCreate (A.new 64)
+
+set :: EPoll -&gt; CInt -&gt; [E.Event] -&gt; IO ()
+set ep fd events =
+    with e $ \ePtr -&gt;
+      epollControl (epollEpfd ep) controlOpAdd fd ePtr
+  where
+    e   = Event ets fd
+    ets = combineEventTypes (map fromEvent events)
+
+poll :: EPoll -&gt; (CInt -&gt; [E.Event] -&gt; IO ()) -&gt; IO ()
+poll ep f = do
+    let epfd   = epollEpfd   ep
+    let events = epollEvents ep
+
+    A.useAsPtr events $ \eventsPtr eventsLen -&gt; do
+        n &lt;- epollWait epfd eventsPtr eventsLen maxNumMilliseconds
+        when (n &gt; 0) $ putStrLn &quot;events!&quot;
+        when (n == eventsLen) $ A.ensureCapacity events (2 * eventsLen)
+        A.mapM_ events $ \e -&gt; f (eventFd e) []
+  where
+    maxNumMilliseconds = 1000
+
+-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+
+fromEvent :: E.Event -&gt; EventType
+fromEvent E.Read  = eventTypeReadyForRead
+fromEvent E.Write = eventTypeReadyForWrite</diff>
      <filename>src/System/Event/EPoll.hsc</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>67fafdad40e7c2d55b397d03202d93dfd0b01d58</id>
    </parent>
  </parents>
  <author>
    <name>Brian Lewis</name>
    <email>brian@lorf.org</email>
  </author>
  <url>http://github.com/tibbe/event/commit/a2ef202325df1e414839c2e5edff678d1f0ab6a4</url>
  <id>a2ef202325df1e414839c2e5edff678d1f0ab6a4</id>
  <committed-date>2009-08-03T15:57:10-07:00</committed-date>
  <authored-date>2009-08-03T15:57:10-07:00</authored-date>
  <message>Added more epoll basics</message>
  <tree>2bfdc0be5bd5b9eab8d472353835eb7b2286cd9d</tree>
  <committer>
    <name>Brian Lewis</name>
    <email>brian@lorf.org</email>
  </committer>
</commit>
