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".

The branch, master has been updated
       via  06af3d1ca4d9d21f05987e062dbb7f2007ec9549 (commit)
      from  c93ddeb6cdd037e684d7b9a624f5b4957f748647 (commit)


Summary of changes:
 src/Snap/Loader/Hint.hs |   40 ++++++++++++++++++++++++++++++++++------
 1 files changed, 34 insertions(+), 6 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 06af3d1ca4d9d21f05987e062dbb7f2007ec9549
Author: Carl Howells <[email protected]>
Date:   Thu Jul 1 09:44:42 2010 -0700

    More documentation for protectedActionEvaluator

diff --git a/src/Snap/Loader/Hint.hs b/src/Snap/Loader/Hint.hs
index 1e2bf82..3268d90 100644
--- a/src/Snap/Loader/Hint.hs
+++ b/src/Snap/Loader/Hint.hs
@@ -142,20 +142,51 @@ format (WontCompile errs) =
 -- before the delay time has expired after the exception was raised.
 protectedActionEvaluator :: NominalDiffTime -> IO a -> IO (IO a)
 protectedActionEvaluator minReEval action = do
+    -- The list of requesters waiting for a result.  Contains the
+    -- ThreadId in case of exceptions, and an empty MVar awaiting a
+    -- successful result.
+    --
+    -- type: MVar [(ThreadId, MVar a)]
     readerContainer <- newMVar []
+
+    -- Contains the previous result, and the time it was stored, if a
+    -- previous result has been computed.  The result stored is either
+    -- the actual result, or the exception thrown by the calculation.
+    --
+    -- type: MVar (Maybe (Either SomeException a, UTCTime))
     resultContainer <- newMVar Nothing
+
+    -- The model used for the above MVars in the returned action is
+    -- "keep them full, unless updating them."  In every case, when
+    -- one of those MVars is emptied, the next action is to fill that
+    -- same MVar.  This makes deadlocking on MVar wait impossible.
     return $ do
         existingResult <- readMVar resultContainer
         now <- getCurrentTime
 
         case existingResult of
             Just (res, ts) | diffUTCTime now ts < minReEval ->
+                -- There's an existing result, and it's still valid
                 case res of
                     Right val -> return val
                     Left  e   -> throwIO e
             _ -> do
+                -- Need to calculate a new result
+                tid <- myThreadId
+                reader <- newEmptyMVar
+
                 readers <- takeMVar readerContainer
 
+                -- Some strictness is employed to ensure the MVar
+                -- isn't holding on to a chain of unevaluated thunks.
+                let pair = (tid, reader)
+                    newReaders = pair `seq` (pair : readers)
+                putMVar readerContainer $! newReaders
+
+                -- If this is the first reader, kick off evaluation of
+                -- the action in a new thread. This is slightly
+                -- careful to block asynchronous exceptions to that
+                -- thread except when actually running the action.
                 when (null readers) $ do
                     let runAndFill = block $ do
                             a <- unblock action
@@ -172,12 +203,9 @@ protectedActionEvaluator minReEval action = do
                             allReaders <- swapMVar readerContainer []
                             mapM_ f allReaders
 
-                    forkIO $ runAndFill `catch` killWaiting
+                    _ <- forkIO $ runAndFill `catch` killWaiting
                     return ()
 
-                tid <- myThreadId
-                reader <- newEmptyMVar
-                let pair = (tid, reader)
-                    newReaders = pair `seq` (pair : readers)
-                putMVar readerContainer $! newReaders
+                -- Wait for the evaluation of the action to complete,
+                -- and return its result.
                 takeMVar reader
-----------------------------------------------------------------------


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

Reply via email to