diff options
author | 2012-10-25 15:30:49 -0400 | |
---|---|---|
committer | 2012-10-25 15:47:27 -0400 | |
commit | d0268981b5411edf812bef00b8d08801e0e75fe9 (patch) | |
tree | e6f89de71eb244e7192e7a27a5b4eb87cfb87622 | |
parent | 7e141b473f8225bc64769e57fd08722532d5ea94 (diff) |
convert the assistant to use a bound thread for XMPP
This *may* solve the segfault I was seeing when the XMPP library called
startTLS. My hypothesis is as follows:
* TLS is documented
(http://www.gnu.org/software/gnutls/manual/gnutls.html#Thread-safety)
thread safe, but only when a single thread accesses it.
* forkIO threads are not bound to an OS thread, so it was possible for
the threaded runtime to run part of the XMPP code on one thread, and
then switch to another thread later.
So, forkOS, with its bound threads, should be used for the XMPP thread.
Since the crash doesn't happen reliably, I am not yet sure about this fix.
Note that I kept all the other threads in the assistant unbound, because
bound threads have significantly higher overhead.
-rw-r--r-- | Assistant.hs | 7 | ||||
-rw-r--r-- | Assistant/Threads/PushNotifier.hs | 2 |
2 files changed, 7 insertions, 2 deletions
diff --git a/Assistant.hs b/Assistant.hs index 7ab9cea51..77790b9c6 100644 --- a/Assistant.hs +++ b/Assistant.hs @@ -223,7 +223,12 @@ startAssistant assistant daemonize webappwaiter = withThreadState $ \st -> do waitForTermination watch a = (True, a) assist a = (False, a) + + {- Each named thread is started in a bound thread. + - (forkOS rather than forkIO). There are not too many, + - and this deals with libraries like gnuTLS that + - require only one thread access them. -} startthread dstatus (watcher, t) - | watcher || assistant = void $ forkIO $ + | watcher || assistant = void $ forkOS $ runNamedThread dstatus t | otherwise = noop diff --git a/Assistant/Threads/PushNotifier.hs b/Assistant/Threads/PushNotifier.hs index 84fe4952a..088e97ec4 100644 --- a/Assistant/Threads/PushNotifier.hs +++ b/Assistant/Threads/PushNotifier.hs @@ -45,7 +45,7 @@ pushNotifierThread st dstatus pushnotifier = NamedThread thisThread $ do client c jid = runClient server jid (xmppUsername c) (xmppPassword c) $ do void $ bindJID jid s <- getSession - _ <- liftIO $ forkIO $ void $ runXMPP s $ + _ <- liftIO $ forkOS $ void $ runXMPP s $ receivenotifications sendnotifications where |