
Am Freitag, 6. Juli 2007 02:13 schrieb Thomas Conway:
Here's my solution:
acceptLoop sok reqChan = do req <- Network.Socket.accept sok atomically (writeTChan reqChan req) acceptLoop sok reqChan
mainLoop reqChan quitVar liveOpCountVar = do action <- atomically (quitNow `orElse` getReq) case action of Nothing -> return () Just (reqSok,reqAddr) -> do atomically $ do liveOpCount <- readTVar liveOpCountVar writeTVar liveOpCountVar (liveOpCount + 1) forkIO (doSession reqSok reqAddr quitVar liveOpCountVar) mainLoop reqChan quitVar liveOpCountVar where quitNow = do q <- readTVar quitVar case q of True -> return Nothing False -> retry
getReq = do req <- readTChan reqChan return (Just req)
doit sok = do reqChan <- atomically newTChan quitVar <- atomically (newTVar False) liveOpCountVar <- atomically (newTVar 0) forkIO (acceptLoop sok reqChan) mainLoop reqChan quitVar liveOpCountVar atomically $ do liveOpCount <- readTVar liveOpCountVar if liveOpCount > 0 then retry else return ()
Although doSession is not included, obviously when you want to quit, something in doSession should set quitVar to True. Also, as suggested elsewhere, doSession should involve a "finally" clauses to make sure the live op count gets decremented.
I don't see how this solves the problem. AFAICS acceptLoop never returns and sok is never closed. On the other hand, my program doesn't need a liveOpCount because the subthreads take care of themselves. It's just the accept loop I need to break somehow. Lukas