This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "snap-server".
The branch, master has been updated
via 169a966ae04fd669fc5615161ba4f246df64711c (commit)
from ad062e86ac17416d67a1fb0a5aa129b8633d9e70 (commit)
Summary of changes:
src/Snap/Internal/Http/Server/LibevBackend.hsc | 164 ++++++++++++++++++------
1 files changed, 124 insertions(+), 40 deletions(-)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 169a966ae04fd669fc5615161ba4f246df64711c
Author: Gregory Collins <[email protected]>
Date: Mon May 24 22:12:30 2010 -0400
Add a bunch of debug output for libev backend and rework things
diff --git a/src/Snap/Internal/Http/Server/LibevBackend.hsc
b/src/Snap/Internal/Http/Server/LibevBackend.hsc
index 476cbd9..0cdb0f1 100644
--- a/src/Snap/Internal/Http/Server/LibevBackend.hsc
+++ b/src/Snap/Internal/Http/Server/LibevBackend.hsc
@@ -78,38 +78,47 @@ data Backend = Backend
data Connection = Connection
- { _backend :: Backend
- , _socket :: Socket
- , _socketFd :: CInt
- , _remoteAddr :: ByteString
- , _remotePort :: Int
- , _localAddr :: ByteString
- , _localPort :: Int
- , _readAvailable :: MVar ()
- , _writeAvailable :: MVar ()
- , _timerObj :: EvTimerPtr
- , _timerCallback :: FunPtr TimerCallback
- , _openingTime :: CDouble
- , _lastActivity :: IORef CDouble
- , _connIOObj :: EvIoPtr
- , _connIOCallback :: FunPtr IoCallback
- , _connThread :: MVar ThreadId
+ { _backend :: Backend
+ , _socket :: Socket
+ , _socketFd :: CInt
+ , _remoteAddr :: ByteString
+ , _remotePort :: Int
+ , _localAddr :: ByteString
+ , _localPort :: Int
+ , _readAvailable :: MVar ()
+ , _writeAvailable :: MVar ()
+ , _timerObj :: EvTimerPtr
+ , _timerCallback :: FunPtr TimerCallback
+ , _openingTime :: CDouble
+ , _lastActivity :: IORef CDouble
+ , _readActive :: IORef Bool
+ , _writeActive :: IORef Bool
+ , _connReadIOObj :: EvIoPtr
+ , _connReadIOCallback :: FunPtr IoCallback
+ , _connWriteIOObj :: EvIoPtr
+ , _connWriteIOCallback :: FunPtr IoCallback
+ , _connThread :: MVar ThreadId
}
sendFile :: Connection -> FilePath -> IO ()
sendFile c fp = do
- withMVar lock $ \_ -> evIoStop loop io
+ withMVar lock $ \_ -> do
+ act <- readIORef $ _writeActive c
+ when act $ evIoStop loop io
+
SF.sendFile s fp
+
withMVar lock $ \_ -> do
tryPutMVar (_readAvailable c) ()
tryPutMVar (_writeAvailable c) ()
evIoStart loop io
+ writeIORef (_writeActive c) True
evAsyncSend loop asy
where
s = _socket c
- io = _connIOObj c
+ io = _connWriteIOObj c
b = _backend c
loop = _evLoop b
lock = _loopLock b
@@ -216,6 +225,7 @@ loopThread backend = do
acceptCallback :: CInt -> Chan CInt -> IoCallback
acceptCallback accFd chan _loopPtr _ioPtr _ = do
+ debug "inside acceptCallback"
r <- c_accept accFd
case r of
@@ -224,18 +234,29 @@ acceptCallback accFd chan _loopPtr _ioPtr _ = do
-- just bail out
-2 -> return ()
-1 -> debugErrno "Backend.acceptCallback:c_accept()"
- fd -> writeChan chan fd
+ fd -> do
+ debug $ "acceptCallback: accept()ed fd, writing to chan " ++ show fd
+ writeChan chan fd
-ioCallback :: MVar () -> MVar () -> IoCallback
-ioCallback ra wa _loopPtr _ioPtr event = do
+ioReadCallback :: CInt -> IORef Bool -> MVar () -> IoCallback
+ioReadCallback fd active ra _loopPtr _ioPtr _ = do
-- send notifications to the worker thread
- when isRead $ tryPutMVar ra () >> return ()
- when isWrite $ tryPutMVar wa () >> return ()
+ debug $ "ioReadCallback: notification (" ++ show fd ++ ")"
+ tryPutMVar ra ()
+ debug $ "stopping ioReadCallback (" ++ show fd ++ ")"
+ evIoStop _loopPtr _ioPtr
+ writeIORef active False
- where
- isRead = (event .&. ev_read) /= 0
- isWrite = (event .&. ev_write) /= 0
+
+ioWriteCallback :: CInt -> IORef Bool -> MVar () -> IoCallback
+ioWriteCallback fd active wa _loopPtr _ioPtr _ = do
+ -- send notifications to the worker thread
+ debug $ "ioWriteCallback: notification (" ++ show fd ++ ")"
+ tryPutMVar wa ()
+ debug $ "stopping ioWriteCallback (" ++ show fd ++ ")"
+ evIoStop _loopPtr _ioPtr
+ writeIORef active False
seconds :: Int -> Int
@@ -320,6 +341,7 @@ freeConnection :: Connection -> IO ()
freeConnection conn = ignoreException $ do
withMVar loopLock $ \_ -> block $ do
-- close socket (twice to get proper linger behaviour)
+ debug $ "freeConnection (" ++ show fd ++ ")"
c_close fd
c_close fd
@@ -328,10 +350,14 @@ freeConnection conn = ignoreException $ do
freeEvTimer timerObj
freeTimerCallback timerCb
- -- stop and free i/o object
- evIoStop loop ioObj
- freeEvIo ioObj
- freeIoCallback ioCb
+ -- stop and free i/o objects
+ evIoStop loop ioWrObj
+ freeEvIo ioWrObj
+ freeIoCallback ioWrCb
+
+ evIoStop loop ioRdObj
+ freeEvIo ioRdObj
+ freeIoCallback ioRdCb
-- remove the thread id from the backend set
tid <- readMVar threadMVar
@@ -349,8 +375,10 @@ freeConnection conn = ignoreException $ do
fd = _socketFd conn
threadMVar = _connThread conn
- ioObj = _connIOObj conn
- ioCb = _connIOCallback conn
+ ioWrObj = _connWriteIOObj conn
+ ioWrCb = _connWriteIOCallback conn
+ ioRdObj = _connReadIOObj conn
+ ioRdCb = _connReadIOCallback conn
timerObj = _timerObj conn
timerCb = _timerCallback conn
@@ -410,7 +438,9 @@ withConnection backend cpu proc = go
threadProc conn = ignoreException (proc conn) `finally` freeConnection conn
go = do
+ debug $ "withConnection: reading from chan"
fd <- readChan $ _connectionQueue backend
+ debug $ "withConnection: got fd " ++ show fd
-- if fd < 0 throw an exception here (because this only happens if stop
-- is called)
@@ -441,14 +471,23 @@ withConnection backend cpu proc = go
tcb <- mkTimerCallback $ timerCallback thrmv
evTimerInit tmr tcb 20 0
- evio <- mkEvIo
- iocb <- mkIoCallback $ ioCallback ra wa
- evIoInit evio iocb fd (ev_read .|. ev_write)
+ readActive <- newIORef True
+ writeActive <- newIORef True
+
+ evioRead <- mkEvIo
+ ioReadCb <- mkIoCallback $ ioReadCallback fd readActive ra
+
+ evioWrite <- mkEvIo
+ ioWriteCb <- mkIoCallback $ ioWriteCallback fd writeActive wa
+
+ evIoInit evioRead ioReadCb fd ev_read
+ evIoInit evioWrite ioWriteCb fd ev_write
-- take ev_loop lock, start timer and io watchers
withMVar (_loopLock backend) $ \_ -> do
evTimerStart lp tmr
- evIoStart lp evio
+ evIoStart lp evioRead
+ evIoStart lp evioWrite
-- wakeup the loop thread so that these new watchers get
-- registered next time through the loop
@@ -467,8 +506,12 @@ withConnection backend cpu proc = go
tcb
now
lastActRef
- evio
- iocb
+ readActive
+ writeActive
+ evioRead
+ ioReadCb
+ evioWrite
+ ioWriteCb
thrmv
@@ -556,13 +599,33 @@ recvData conn n = do
else B.packCStringLen ((castPtr cstr),(fromEnum sz))
where
+ io = _connReadIOObj conn
+ bk = _backend conn
+ active = _readActive conn
+ lp = _evLoop bk
+ looplock = _loopLock bk
+ async = _asyncObj bk
+
dbg s = debug $ "Backend.recvData(" ++ show (_socketFd conn) ++ "): " ++ s
fd = _socketFd conn
lock = _readAvailable conn
waitForLock = do
- dbg "waitForLock"
+ dbg "start waitForLock"
+
+ withMVar looplock $ \_ -> do
+ act <- readIORef active
+ if act
+ then dbg "read watcher already active, skipping"
+ else do
+ dbg "starting watcher, sending async"
+ evIoStart lp io
+ writeIORef active True
+ evAsyncSend lp async
+
+ dbg "waitForLock: waiting for mvar"
takeMVar lock
+ dbg "waitForLock: took mvar"
sendData :: Connection -> ByteString -> IO ()
@@ -583,10 +646,31 @@ sendData conn bs = do
else return ()
where
+ io = _connWriteIOObj conn
+ bk = _backend conn
+ lp = _evLoop bk
+ active = _writeActive conn
+ looplock = _loopLock bk
+ async = _asyncObj bk
+
dbg s = debug $ "Backend.sendData(" ++ show (_socketFd conn) ++ "): " ++ s
fd = _socketFd conn
lock = _writeAvailable conn
- waitForLock = takeMVar lock
+ waitForLock = do
+ dbg "waitForLock: starting"
+ withMVar looplock $ \_ -> do
+ act <- readIORef active
+ if act
+ then dbg "write watcher already running, skipping"
+ else do
+ dbg "starting watcher, sending async event"
+ evIoStart lp io
+ writeIORef active True
+ evAsyncSend lp async
+
+ dbg "waitForLock: taking mvar"
+ takeMVar lock
+ dbg "waitForLock: took mvar"
getReadEnd :: Connection -> Enumerator IO a
-----------------------------------------------------------------------
hooks/post-receive
--
snap-server
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap