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  53cf92232ff69c6dea4b3ffc8d6d7f59a354afeb (commit)
      from  bf50ce5ed3c8f612444124ad851295c82a20a2ff (commit)


Summary of changes:
 src/Snap/Internal/Http/Server.hs               |    3 +-
 src/Snap/Internal/Http/Server/LibevBackend.hs  |   53 +++++++-----------------
 src/Snap/Internal/Http/Server/SimpleBackend.hs |   38 ++++++++++++-----
 3 files changed, 42 insertions(+), 52 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 53cf92232ff69c6dea4b3ffc8d6d7f59a354afeb
Author: Gregory Collins <[email protected]>
Date:   Fri Sep 17 23:08:04 2010 -0400

    Get rid of annoying delay on exit

diff --git a/src/Snap/Internal/Http/Server.hs b/src/Snap/Internal/Http/Server.hs
index 91a237e..fd40555 100644
--- a/src/Snap/Internal/Http/Server.hs
+++ b/src/Snap/Internal/Http/Server.hs
@@ -157,7 +157,6 @@ httpServe bindAddress bindPort localHostname alogPath 
elogPath handler =
                     elog <- maybeSpawnLogger efp
                     return (alog, elog))
                 (\(alog, elog) -> do
-                    threadDelay 1000000
                     maybe (return ()) stopLogger alog
                     maybe (return ()) stopLogger elog)
 
@@ -699,7 +698,7 @@ sendResponse rsp' writeEnd onSendFile = do
             return $ r' { rspBody = b }
 
       where
-        i :: forall a . Enumerator IO a -> Enumerator IO a
+        i :: forall z . Enumerator IO z -> Enumerator IO z
         i enum iter = enum (joinI $ takeExactly cl iter)
 
 
diff --git a/src/Snap/Internal/Http/Server/LibevBackend.hs 
b/src/Snap/Internal/Http/Server/LibevBackend.hs
index 5627768..7b69a77 100644
--- a/src/Snap/Internal/Http/Server/LibevBackend.hs
+++ b/src/Snap/Internal/Http/Server/LibevBackend.hs
@@ -47,11 +47,10 @@ import             Data.Typeable
 import             Foreign hiding (new)
 import             Foreign.C.Error
 import             Foreign.C.Types
-import             GHC.Conc (forkOnIO)
+import             GHC.Conc (forkOnIO, numCapabilities)
 import             Network.Libev
 import             Network.Socket
 import             Prelude hiding (catch)
-import             System.Timeout
 ------------------------------------------------------------------------------
 
 -- FIXME: should be HashSet, make that later.
@@ -82,6 +81,7 @@ data Backend = Backend
     , _killObj           :: !EvAsyncPtr
     , _connectionThreads :: !(HashMap ThreadId ())
     , _backendCPU        :: !Int
+    , _backendFreed      :: !(MVar ())
     }
 
 
@@ -216,6 +216,9 @@ new (sock,sockFd) cpu = do
     -- thread set stuff
     connSet <- H.new (H.hashString . show)
 
+    -- freed gets stuffed with () when all resources are released.
+    freed <- newEmptyMVar
+
     let b = Backend sock
                     sockFd
                     connq
@@ -230,6 +233,7 @@ new (sock,sockFd) cpu = do
                     killObj
                     connSet
                     cpu
+                    freed
 
     forkOnIO cpu $ loopThread b
 
@@ -244,9 +248,11 @@ loopThread backend = do
     (ignoreException go) `finally` cleanup
     debug $ "loop finished"
   where
-    cleanup = do
+    cleanup = block $ do
         debug $ "loopThread: cleaning up"
         ignoreException $ freeBackend backend
+        putMVar (_backendFreed backend) ()
+
     lock    = _loopLock backend
     loop    = _evLoop backend
     go      = takeMVar lock >> block (evLoop loop 0)
@@ -288,43 +294,28 @@ ioWriteCallback fd active wa _loopPtr _ioPtr _ = do
     writeIORef active False
 
 
-seconds :: Int -> Int
-seconds n = n * ((10::Int)^(6::Int))
-
-
 stop :: Backend -> IO ()
 stop b = ignoreException $ do
     debug $ "Backend.stop"
 
-    -- FIXME: what are we gonna do here?
-    --
     -- 1. take the loop lock
     -- 2. shut down the accept() callback
     -- 3. stuff a poison pill (a bunch of -1 values should do) down the
     --    connection queue so that withConnection knows to throw an exception
     --    back up to its caller
-    -- 4. release the loop lock
-    -- 5. wait until all of the threads have finished, or until 10 seconds have
-    --    elapsed, whichever comes first
-    -- 6. take the loop lock
-    -- 7. call evUnloop and wake up the loop using evAsyncSend
-    -- 8. release the loop lock, the main loop thread should then free/clean
+    -- 4. call evUnloop and wake up the loop using evAsyncSend
+    -- 5. release the loop lock, the main loop thread should then free/clean
     --    everything up (threads, connections, io objects, callbacks, etc)
+    -- 6. wait for the loop thread to signal it has cleaned up and exited
 
     withMVar lock $ \_ -> do
         evIoStop loop acceptObj
-        replicateM_ 10 $ writeChan connQ (-1)
-
-    debug $ "Backend.stop: waiting at most 10 seconds for connection threads 
to die"
-    waitForThreads b $ seconds 10
-    debug $ "Backend.stop: all threads presumed dead, unlooping"
-
-    withMVar lock $ \_ -> do
+        replicateM_ (numCapabilities*2) $ writeChan connQ (-1)
         evUnloop loop evunloop_all
         evAsyncSend loop killObj
 
-    debug $ "unloop sent"
-
+    debug $ "accepting threads killed, unloop sent, waiting for completion"
+    takeMVar $ _backendFreed b
 
   where
     loop           = _evLoop b
@@ -335,18 +326,6 @@ stop b = ignoreException $ do
 
 
 
-waitForThreads :: Backend -> Int -> IO ()
-waitForThreads backend t = timeout t wait >> return ()
-  where
-    threadSet = _connectionThreads backend
-    wait = do
-        b       <- H.null threadSet
-        if b
-          then return ()
-          else threadDelay (seconds 1) >> wait
-
-
-
 getAddr :: SockAddr -> IO (ByteString, Int)
 getAddr addr =
     case addr of
@@ -434,8 +413,6 @@ ignoreException = handle (\(_::SomeException) -> return ())
 freeBackend :: Backend -> IO ()
 freeBackend backend = ignoreException $ block $ do
     -- note: we only get here after an unloop
-
-
     -- kill everything in thread table
     tset <- H.toList $ _connectionThreads backend
     Prelude.mapM_ (killThread . fst) tset
diff --git a/src/Snap/Internal/Http/Server/SimpleBackend.hs 
b/src/Snap/Internal/Http/Server/SimpleBackend.hs
index 5879e24..ace900c 100644
--- a/src/Snap/Internal/Http/Server/SimpleBackend.hs
+++ b/src/Snap/Internal/Http/Server/SimpleBackend.hs
@@ -138,34 +138,47 @@ new sock _ = do
 
     let b = Backend sock ed t
 
-    tid <- forkIO $ timeoutThread b PSQ.empty
+    tid <- forkIO $ timeoutThread b
     putMVar t tid
 
     return b
 
 
-timeoutThread :: Backend -> TimeoutTable -> IO ()
-timeoutThread backend = loop
-  where
-    loop tt = do
-        tt' <- killTooOld tt
+timeoutThread :: Backend -> IO ()
+timeoutThread backend = do
+    tref <- newIORef $ PSQ.empty
+    let loop = do
+        killTooOld tref
         threadDelay (5000000)
-        loop tt'
+        loop
 
+    loop `catch` (\(_::SomeException) -> killAll tref)
 
-    killTooOld table = do
+  where
+    killTooOld tref = do
+        !table <- readIORef tref
         -- atomic swap edit list
         now   <- getCurrentDateTime
         edits <- atomicModifyIORef tedits $ \t -> (D.empty, D.toList t)
 
         let table' = foldl' (flip ($)) table edits
         !t'   <- killOlderThan now table'
-        return t'
+        writeIORef tref t'
 
 
     -- timeout = 30 seconds
     tIMEOUT = 30
 
+    killAll !tref = do
+        debug "Backend.timeoutThread: shutdown, killing all connections"
+        !table <- readIORef tref
+        go table
+      where
+        go t = maybe (return ())
+                     (\m -> (killThread $ PSQ.key m) >>
+                            (go $ PSQ.deleteMin t))
+                     (PSQ.findMin t)
+
     killOlderThan now !table = do
         debug "Backend.timeoutThread: killing old connections"
         let mmin = PSQ.findMin table
@@ -190,7 +203,8 @@ stop (Backend s _ t) = do
     debug $ "Backend.stop"
     sClose s
 
-    -- kill timeout thread and current thread
+    -- kill timeout thread and current thread; timeout thread handler will stop
+    -- all of the running connection threads
     readMVar t >>= killThread
     myThreadId >>= killThread
 
@@ -318,8 +332,8 @@ tickleTimeout conn = do
     tedits = _timeoutEdits $ _backend conn
 
 
-cancelTimeout :: Connection -> IO ()
-cancelTimeout conn = do
+_cancelTimeout :: Connection -> IO ()
+_cancelTimeout conn = do
     debug "Backend.cancelTimeout"
     tid <- readMVar $ _connTid conn
 
-----------------------------------------------------------------------


hooks/post-receive
-- 
snap-server
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap

Reply via email to