@@ -9,6 +9,8 @@ module Duct.Context
9 , saveContext
9 , saveContext
10 , restoreContext
10 , restoreContext
11 , resumeContext
11 , resumeContext
12 , Location(..)
14 , Location(..)
13 , getLocation
15 , getLocation
14 , setLocation
16 , setLocation
@@ -50,6 +52,7 @@ data Context = Context
50 -- In nested binds we store the current m only, but the whole stack of fs
52 -- In nested binds we store the current m only, but the whole stack of fs
51 , currentm :: Any -- untyped, the real type is: m a
53 , currentm :: Any -- untyped, the real type is: m a
52 , fstack :: [Any] -- untyped, the real type is: [a -> m b]
54 , fstack :: [Any] -- untyped, the real type is: [a -> m b]
55+ -- XXX keep a composed computation instead
53 -- ^ List of continuations
56 -- ^ List of continuations
55 -- log only when there is a restore or if we are teleporting
58 -- log only when there is a restore or if we are teleporting
@@ -101,7 +104,7 @@ data Context = Context
102 , threadCredit :: IORef Int
105 , threadCredit :: IORef Int
103 -- ^ How many more threads are allowed to be created?
106 -- ^ How many more threads are allowed to be created?
104− , accumResults :: IORef [Any]
107+ , accumResults :: [Any]
105 -- ^ Accumulated results when running synchronously
108 -- ^ Accumulated results when running synchronously
106 } deriving Typeable
109 } deriving Typeable
@@ -110,19 +113,19 @@ initContext
110 -> TChan (ChildEvent a)
113 -> TChan (ChildEvent a)
111 -> IORef [ThreadId]
114 -> IORef [ThreadId]
112 -> IORef Int
115 -> IORef Int
113− -> IORef [a]
116+ -> (b -> m a)
114 -> Context
117 -> Context
115−initContext x childChan pending credit results =
118+initContext x childChan pending credit finalizer =
116− Context { event = mempty
119+ Context { event = mempty -- XXX Nothing
117 , currentm = unsafeCoerce x
120 , currentm = unsafeCoerce x
118− , fstack = []
121+ , fstack = [unsafeCoerce finalizer]
119 , location = Worker
122 , location = Worker
120 , mfData = mempty
123 , mfData = mempty
121 , parentChannel = Nothing
124 , parentChannel = Nothing
122 , childChannel = unsafeCoerce childChan
125 , childChannel = unsafeCoerce childChan
123 , pendingThreads = pending
126 , pendingThreads = pending
124 , threadCredit = credit
127 , threadCredit = credit
125− , accumResults = unsafeCoerce results }
128+ , accumResults = [] }
127------------------------------------------------------------------------------
130------------------------------------------------------------------------------
128-- Where is the computation running?
131-- Where is the computation running?
@@ -165,6 +168,7 @@ restoreContext x = do
165 ctx@Context { fstack = f:fs } <- Lazy.get
168 ctx@Context { fstack = f:fs } <- Lazy.get
167 let mres = case x of
170 let mres = case x of
171+ -- XXX use mzero instead
168 Nothing -> empty
172 Nothing -> empty
169 Just y -> (unsafeCoerce f) y
173 Just y -> (unsafeCoerce f) y
@@ -180,7 +184,6 @@ restoreContext x = do
180resumeContext :: (MonadIO m, MonadPlus m) => Context -> m a
184resumeContext :: (MonadIO m, MonadPlus m) => Context -> m a
181resumeContext Context { currentm = m
185resumeContext Context { currentm = m
182 , fstack = fs
186 , fstack = fs
183− , accumResults = resultsRef
185 unsafeCoerce m >>= composefStack (unsafeCoerce fs)
188 unsafeCoerce m >>= composefStack (unsafeCoerce fs)
@@ -194,12 +197,17 @@ resumeContext Context { currentm = m
194 -- Before returning we save the result of the computation in the context.
197 -- Before returning we save the result of the computation in the context.
196 -- composefStack :: Monad m => [a -> AsyncT m a] -> a -> AsyncT m b
199 -- composefStack :: Monad m => [a -> AsyncT m a] -> a -> AsyncT m b
197− composefStack [] x = do
200+ composefStack [] _ = error "Bug: this should never be reached"
198− -- remove this, return use the modified context
199− liftIO $ modifyIORef resultsRef $ \r -> x : r
201 composefStack (f:ff) x = f x >>= composefStack ff
201 composefStack (f:ff) x = f x >>= composefStack ff
203+contextSaveResult :: Monad m => a -> StateT Context m ()
204+contextSaveResult r =
205+ modify $ \ Context {accumResults = rs, ..} ->
206+ Context {accumResults = unsafeCoerce r : rs, ..}
208+contextGetResult :: Context -> [a]
209+contextGetResult ctx = unsafeCoerce $ accumResults ctx
203------------------------------------------------------------------------------
211------------------------------------------------------------------------------
204-- * Extensible State: Session Data Management
212-- * Extensible State: Session Data Management
205------------------------------------------------------------------------------
213------------------------------------------------------------------------------