[using C socket calls via FFI aycan.irican@core.gen.tr**20080929120538] { hunk ./Network/Libev.hsc 12 + , IoCallback (..) hunk ./Network/Libev.hsc 23 + , c_accept + , c_close + , c_read + , c_write hunk ./Network/Libev.hsc 100 +foreign import ccall unsafe "unistd.h close" c_close :: CInt -> IO (CInt) +foreign import ccall unsafe "unistd.h read" c_read :: CInt -> CString -> CSize -> IO (CSize) +foreign import ccall unsafe "unistd.h write" c_write :: CInt -> CString -> CSize -> IO (CSize) +foreign import ccall unsafe "c_accept" c_accept :: CInt -> IO (CInt) + addfile ./README hunk ./README 1 +An FFI interface to libev. hunk ./hlibev.cabal 16 -ghc-options: -Wall +ghc-options: -Wall -fvia-C -O2 hunk ./test.hs 1 +{-# OPTIONS -ffi -fvia-C -O2 #-} hunk ./test.hs 7 +import Foreign.C hunk ./test.hs 14 -import Network.Socket hiding (send, sendTo, recv, recvFrom) -import Network.Socket.ByteString -import qualified Data.ByteString as B +import Network.Socket -- hiding (send, sendTo, recv, recvFrom) +-- import Network.Socket.ByteString +-- import qualified Data.ByteString as B hunk ./test.hs 39 -testData = B.pack $ map (fromIntegral . ord) "HTTP/1.1 200 OK\nContent-Type:text/html;charset=UTF-8\n\n

Haskell and libev working together...

\n" +-- testData = B.pack $ map (fromIntegral . ord) "HTTP/1.1 200 OK\nContent-Type:text/html;charset=UTF-8\n\n

Haskell and libev working together...

\n" +testData = "HTTP/1.1 200 OK\nContent-Type:text/html;charset=UTF-8\n\n

Haskell and libev working together...

\n" hunk ./test.hs 42 -connectorCB :: Socket -> IoCallback -connectorCB s l w _ = do +processSocket fd = do + _ <- allocaBytes 1024 $ \ptr -> c_read fd ptr 1024 + _ <- withCString testData $ \str -> c_write fd str 125 + c_close fd + return () + +connectorCB :: CInt -> IoCallback +connectorCB fd l w _ = do hunk ./test.hs 53 - _ <- recv s 1024 - _ <- send s testData - sClose s + forkIO (processSocket fd) hunk ./test.hs 60 - (sock, _) <- accept s + fd <- c_accept (fdSocket s) hunk ./test.hs 63 - ioCB <- mkIoCallback $ connectorCB sock - evIoInit ioW ioCB (fdSocket sock) ev_read + ioCB <- mkIoCallback $ connectorCB fd + evIoInit ioW ioCB fd ev_read hunk ./test.hs 86 - runInBoundThread (start servSock) `finally` sClose servSock + start servSock `finally` sClose servSock hunk ./wrapper.c 9 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + hunk ./wrapper.c 47 +void set_nonblocking(int fd) +{ + int flags; + /* If they have O_NONBLOCK, use the Posix way to do it */ + if (-1 == (flags = fcntl(fd, F_GETFL, 0))) flags = 0; + int res = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + assert(res==0); +} + +int c_accept(int server_fd) { + int fd = accept(server_fd, NULL, NULL); + if (fd == -1 && ( errno == EAGAIN || errno == EWOULDBLOCK) ) return -2; + if (fd > 0) { + set_nonblocking(fd); + return fd; + } else { + return -1; + } +} + }