@@ -255,7 +255,6 @@ pushCheap f e = Event $ \sub -> do
255data CacheSubscribed x a
255data CacheSubscribed x a
256 = CacheSubscribed { _cacheSubscribed_subscribers :: {-# UNPACK #-} !(FastWeakBag (Subscriber x a))
256 = CacheSubscribed { _cacheSubscribed_subscribers :: {-# UNPACK #-} !(FastWeakBag (Subscriber x a))
257 , _cacheSubscribed_parent :: {-# UNPACK #-} !(EventSubscription x)
257 , _cacheSubscribed_parent :: {-# UNPACK #-} !(EventSubscription x)
258− , _cacheSubscribed_cached :: {-# UNPACK #-} !(IORef (Maybe (FastWeakTicket (CacheSubscribed x a))))
259 , _cacheSubscribed_occurrence :: {-# UNPACK #-} !(IORef (Maybe a))
258 , _cacheSubscribed_occurrence :: {-# UNPACK #-} !(IORef (Maybe a))
@@ -273,13 +272,13 @@ cacheEvent e =
276− let mSubscribedRef :: IORef (Maybe (FastWeakTicket (CacheSubscribed x a)))
275+ let mSubscribedRef :: IORef (FastWeak (CacheSubscribed x a))
277− !mSubscribedRef = unsafeNewIORef e Nothing
276+ !mSubscribedRef = unsafeNewIORef e emptyFastWeak
278 in \sub -> {-# SCC "cacheEvent" #-} do
277 in \sub -> {-# SCC "cacheEvent" #-} do
279#ifdef DEBUG_TRACE_EVENTS
278#ifdef DEBUG_TRACE_EVENTS
280 unless (BS8.null callSite) $ liftIO $ BS8.hPutStrLn stderr callSite
279 unless (BS8.null callSite) $ liftIO $ BS8.hPutStrLn stderr callSite
282− subscribedTicket <- liftIO (readIORef mSubscribedRef) >>= \case
281+ subscribedTicket <- liftIO (readIORef mSubscribedRef >>= getFastWeakTicket) >>= \case
283 Just subscribedTicket -> return subscribedTicket
282 Just subscribedTicket -> return subscribedTicket
284 Nothing -> do
283 Nothing -> do
285 subscribers <- liftIO FastWeakBag.empty
284 subscribers <- liftIO FastWeakBag.empty
@@ -300,27 +299,30 @@ cacheEvent e =
300 let !subscribed = CacheSubscribed
299 let !subscribed = CacheSubscribed
301 { _cacheSubscribed_subscribers = subscribers
300 { _cacheSubscribed_subscribers = subscribers
302 , _cacheSubscribed_parent = parentSub
301 , _cacheSubscribed_parent = parentSub
303− , _cacheSubscribed_cached = mSubscribedRef
304 , _cacheSubscribed_occurrence = occRef
302 , _cacheSubscribed_occurrence = occRef
306 subscribedTicket <- liftIO $ mkFastWeakTicket subscribed
304 subscribedTicket <- liftIO $ mkFastWeakTicket subscribed
307− liftIO $ writeIORef mSubscribedRef $ Just subscribedTicket
305+ liftIO $ writeIORef mSubscribedRef =<< getFastWeakTicketWeak subscribedTicket
308 return subscribedTicket
306 return subscribedTicket
309 liftIO $ do
307 liftIO $ do
310− let subscribed = fastWeakTicketValue subscribedTicket
308+ subscribed <- getFastWeakTicketValue subscribedTicket
311− subscribedWeak <- getFastWeakTicketWeak subscribedTicket
312− ticket <- FastWeakBag.insert sub (_cacheSubscribed_subscribers subscribed) subscribedWeak cleanupCacheSubscribed
309+ ticket <- FastWeakBag.insert sub $ _cacheSubscribed_subscribers subscribed
313 occ <- readIORef $ _cacheSubscribed_occurrence subscribed
310 occ <- readIORef $ _cacheSubscribed_occurrence subscribed
311+ let es = EventSubscription
312+ { _eventSubscription_unsubscribe = do
313+ FastWeakBag.remove ticket
314+ isEmpty <- FastWeakBag.isEmpty $ _cacheSubscribed_subscribers subscribed
316+ writeIORef mSubscribedRef emptyFastWeak
317+ unsubscribe $ _cacheSubscribed_parent subscribed
319+ touch subscribedTicket
314− let es = EventSubscribed
320+ , _eventSubscription_subscribed = EventSubscribed
315− { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ _cacheSubscribed_parent subscribed
321+ { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ _cacheSubscribed_parent subscribed
316− , eventSubscribedRetained = toAny subscribed
322+ , eventSubscribedRetained = toAny subscribedTicket
318− return (EventSubscription (FastWeakBag.remove ticket >> touch ticket) es, occ)
325+ return (es, occ)
320−cleanupCacheSubscribed :: CacheSubscribed x a -> IO ()
321−cleanupCacheSubscribed self = do
322− unsubscribe $ _cacheSubscribed_parent self
323− writeIORef (_cacheSubscribed_cached self) Nothing
325subscribe :: Event x a -> Subscriber x a -> EventM x (EventSubscription x)
327subscribe :: Event x a -> Subscriber x a -> EventM x (EventSubscription x)
326subscribe e s = fst <$> subscribeAndRead e s
328subscribe e s = fst <$> subscribeAndRead e s