@@ -255,7 +255,6 @@ pushCheap f e = Event $ \sub -> do
255255data CacheSubscribed x a
256256 = CacheSubscribed { _cacheSubscribed_subscribers :: {-# UNPACK #-} !(FastWeakBag (Subscriber x a))
257257 , _cacheSubscribed_parent :: {-# UNPACK #-} !(EventSubscription x)
258− , _cacheSubscribed_cached :: {-# UNPACK #-} !(IORef (Maybe (FastWeakTicket (CacheSubscribed x a))))
259258 , _cacheSubscribed_occurrence :: {-# UNPACK #-} !(IORef (Maybe a))
260259 }
261260
@@ -273,13 +272,13 @@ cacheEvent e =
273272#else
274273 Event $
275274#endif
276− let mSubscribedRef :: IORef (Maybe (FastWeakTicket (CacheSubscribed x a)))
277− !mSubscribedRef = unsafeNewIORef e Nothing
275+ let mSubscribedRef :: IORef (FastWeak (CacheSubscribed x a))
276+ !mSubscribedRef = unsafeNewIORef e emptyFastWeak
278277 in \sub -> {-# SCC "cacheEvent" #-} do
279278#ifdef DEBUG_TRACE_EVENTS
280279 unless (BS8.null callSite) $ liftIO $ BS8.hPutStrLn stderr callSite
281280#endif
282− subscribedTicket <- liftIO (readIORef mSubscribedRef) >>= \case
281+ subscribedTicket <- liftIO (readIORef mSubscribedRef >>= getFastWeakTicket) >>= \case
283282 Just subscribedTicket -> return subscribedTicket
284283 Nothing -> do
285284 subscribers <- liftIO FastWeakBag.empty
@@ -300,27 +299,30 @@ cacheEvent e =
300299 let !subscribed = CacheSubscribed
301300 { _cacheSubscribed_subscribers = subscribers
302301 , _cacheSubscribed_parent = parentSub
303− , _cacheSubscribed_cached = mSubscribedRef
304302 , _cacheSubscribed_occurrence = occRef
305303 }
306304 subscribedTicket <- liftIO $ mkFastWeakTicket subscribed
307− liftIO $ writeIORef mSubscribedRef $ Just subscribedTicket
305+ liftIO $ writeIORef mSubscribedRef =<< getFastWeakTicketWeak subscribedTicket
308306 return subscribedTicket
309307 liftIO $ do
310− let subscribed = fastWeakTicketValue subscribedTicket
311− subscribedWeak <- getFastWeakTicketWeak subscribedTicket
312− ticket <- FastWeakBag.insert sub (_cacheSubscribed_subscribers subscribed) subscribedWeak cleanupCacheSubscribed
308+ subscribed <- getFastWeakTicketValue subscribedTicket
309+ ticket <- FastWeakBag.insert sub $ _cacheSubscribed_subscribers subscribed
313310 occ <- readIORef $ _cacheSubscribed_occurrence subscribed
314− let es = EventSubscribed
315− { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ _cacheSubscribed_parent subscribed
316− , eventSubscribedRetained = toAny subscribed
311+ let es = EventSubscription
312+ { _eventSubscription_unsubscribe = do
313+ FastWeakBag.remove ticket
314+ isEmpty <- FastWeakBag.isEmpty $ _cacheSubscribed_subscribers subscribed
315+ when isEmpty $ do
316+ writeIORef mSubscribedRef emptyFastWeak
317+ unsubscribe $ _cacheSubscribed_parent subscribed
318+ touch ticket
319+ touch subscribedTicket
320+ , _eventSubscription_subscribed = EventSubscribed
321+ { eventSubscribedHeightRef = eventSubscribedHeightRef $ _eventSubscription_subscribed $ _cacheSubscribed_parent subscribed
322+ , eventSubscribedRetained = toAny subscribedTicket
323+ }
317324 }
318− return (EventSubscription (FastWeakBag.remove ticket >> touch ticket) es, occ)
319−
320−cleanupCacheSubscribed :: CacheSubscribed x a -> IO ()
321−cleanupCacheSubscribed self = do
322− unsubscribe $ _cacheSubscribed_parent self
323− writeIORef (_cacheSubscribed_cached self) Nothing
325+ return (es, occ)
324326
325327subscribe :: Event x a -> Subscriber x a -> EventM x (EventSubscription x)
326328subscribe e s = fst <$> subscribeAndRead e s