[commit: ghc] master: Expose hs_exit_(rtsFalse) as hs_exit_nowait() (74c4ca0)

git at git.haskell.org git at git.haskell.org
Fri Sep 23 04:40:06 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/74c4ca02df1f7099420eedf32ab4fabc0fd8cb8c/ghc

>---------------------------------------------------------------

commit 74c4ca02df1f7099420eedf32ab4fabc0fd8cb8c
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Fri Sep 16 11:04:44 2016 +0100

    Expose hs_exit_(rtsFalse) as hs_exit_nowait()
    
    Summary: And document it.  See the docmentation for the reason I want this.
    
    Test Plan: It's an existing API, just exposing it.
    
    Reviewers: bgamari, niteria, austin, erikd
    
    Subscribers: thomie
    
    Differential Revision: https://phabricator.haskell.org/D2531


>---------------------------------------------------------------

74c4ca02df1f7099420eedf32ab4fabc0fd8cb8c
 docs/users_guide/ffi-chap.rst | 16 +++++++++++++---
 includes/HsFFI.h              |  1 +
 rts/RtsStartup.c              |  8 ++++++++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/docs/users_guide/ffi-chap.rst b/docs/users_guide/ffi-chap.rst
index f46d902..70b55d0 100644
--- a/docs/users_guide/ffi-chap.rst
+++ b/docs/users_guide/ffi-chap.rst
@@ -612,9 +612,19 @@ The GHC runtime treats program exit as a special case, to avoid the need
 to wait for blocked threads when a standalone executable exits. Since
 the program and all its threads are about to terminate at the same time
 that the code is removed from memory, it isn't necessary to ensure that
-the threads have exited first. (Unofficially, if you want to use this
-fast and loose version of ``hs_exit()``, then call
-``shutdownHaskellAndExit()`` instead).
+the threads have exited first.  If you want this fast and loose
+version of ``hs_exit()``, you can call:
+
+.. code-block:: c
+
+   void hs_exit_nowait(void);
+
+instead.  This is particularly useful if you have foreign libraries
+that need to call ``hs_exit()`` at program exit (perhaps via a C++
+destructor): in this case you should use ``hs_exit_nowait()``, because
+the thread that called ``exit()`` and is running C++ destructors is in
+a foreign call from Haskell that will never return, so ``hs_exit()``
+would deadlock.
 
 .. _hs_try_putmvar:
 
diff --git a/includes/HsFFI.h b/includes/HsFFI.h
index cdf4510..8e9ff40 100644
--- a/includes/HsFFI.h
+++ b/includes/HsFFI.h
@@ -96,6 +96,7 @@ typedef void*                   HsStablePtr;
 
 extern void hs_init     (int *argc, char **argv[]);
 extern void hs_exit     (void);
+extern void hs_exit_nowait(void);
 extern void hs_set_argv (int argc, char *argv[]);
 extern void hs_add_root (void (*init_root)(void));
 extern void hs_thread_done (void);
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index 33ffb83..a2630b2 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -455,6 +455,14 @@ hs_exit(void)
     // be safe; this might be a DLL
 }
 
+void
+hs_exit_nowait(void)
+{
+    hs_exit_(rtsFalse);
+    // do not wait for outstanding foreign calls to return; if they return in
+    // the future, they will block indefinitely.
+}
+
 // Compatibility interfaces
 void
 shutdownHaskell(void)



More information about the ghc-commits mailing list