@@ -9,6 +9,8 @@ module Duct.Context
99 , saveContext
1010 , restoreContext
1111 , resumeContext
12+ , contextSaveResult
13+ , contextGetResult
1214 , Location(..)
1315 , getLocation
1416 , setLocation
@@ -50,6 +52,7 @@ data Context = Context
5052 -- In nested binds we store the current m only, but the whole stack of fs
5153 , currentm :: Any -- untyped, the real type is: m a
5254 , fstack :: [Any] -- untyped, the real type is: [a -> m b]
55+ -- XXX keep a composed computation instead
5356 -- ^ List of continuations
5457
5558 -- log only when there is a restore or if we are teleporting
@@ -101,7 +104,7 @@ data Context = Context
101104 --
102105 , threadCredit :: IORef Int
103106 -- ^ How many more threads are allowed to be created?
104− , accumResults :: IORef [Any]
107+ , accumResults :: [Any]
105108 -- ^ Accumulated results when running synchronously
106109 } deriving Typeable
107110
@@ -110,19 +113,19 @@ initContext
110113 -> TChan (ChildEvent a)
111114 -> IORef [ThreadId]
112115 -> IORef Int
113− -> IORef [a]
116+ -> (b -> m a)
114117 -> Context
115−initContext x childChan pending credit results =
116− Context { event = mempty
118+initContext x childChan pending credit finalizer =
119+ Context { event = mempty -- XXX Nothing
117120 , currentm = unsafeCoerce x
118− , fstack = []
121+ , fstack = [unsafeCoerce finalizer]
119122 , location = Worker
120123 , mfData = mempty
121124 , parentChannel = Nothing
122125 , childChannel = unsafeCoerce childChan
123126 , pendingThreads = pending
124127 , threadCredit = credit
125− , accumResults = unsafeCoerce results }
128+ , accumResults = [] }
126129
127130------------------------------------------------------------------------------
128131-- Where is the computation running?
@@ -165,6 +168,7 @@ restoreContext x = do
165168 ctx@Context { fstack = f:fs } <- Lazy.get
166169
167170 let mres = case x of
171+ -- XXX use mzero instead
168172 Nothing -> empty
169173 Just y -> (unsafeCoerce f) y
170174
@@ -180,7 +184,6 @@ restoreContext x = do
180184resumeContext :: (MonadIO m, MonadPlus m) => Context -> m a
181185resumeContext Context { currentm = m
182186 , fstack = fs
183− , accumResults = resultsRef
184187 } =
185188 unsafeCoerce m >>= composefStack (unsafeCoerce fs)
186189
@@ -194,12 +197,17 @@ resumeContext Context { currentm = m
194197 -- Before returning we save the result of the computation in the context.
195198
196199 -- composefStack :: Monad m => [a -> AsyncT m a] -> a -> AsyncT m b
197− composefStack [] x = do
198− -- remove this, return use the modified context
199− liftIO $ modifyIORef resultsRef $ \r -> x : r
200− mzero
200+ composefStack [] _ = error "Bug: this should never be reached"
201201 composefStack (f:ff) x = f x >>= composefStack ff
202202
203+contextSaveResult :: Monad m => a -> StateT Context m ()
204+contextSaveResult r =
205+ modify $ \ Context {accumResults = rs, ..} ->
206+ Context {accumResults = unsafeCoerce r : rs, ..}
207+
208+contextGetResult :: Context -> [a]
209+contextGetResult ctx = unsafeCoerce $ accumResults ctx
210+
203211------------------------------------------------------------------------------
204212-- * Extensible State: Session Data Management
205213------------------------------------------------------------------------------