- <para>When <literal>foreign import ccall "wrapper"</literal> is used
- in a Haskell module, The C stub file <filename>M_stub.c</filename>
- generated by GHC contains small helper functions used by the code
- generated for the imported wrapper, so it must be linked in to the
- final program. When linking the program, remember to include
- <filename>M_stub.o</filename> in the final link command line, or
- you'll get link errors for the missing function(s) (this isn't
- necessary when building your program with <literal>ghc
- ––make</literal>, as GHC will automatically link in the
- correct bits).</para>
+ <para>The main requirement here is that the runtime needs to be
+ initialized before any Haskell code can be called, so your library
+ should provide initialisation and deinitialisation entry points,
+ implemented in C or C++. For example:</para>
+
+<programlisting>
+ HsBool mylib_init(void){
+ int argc = ...
+ char *argv[] = ...
+
+ // Initialize Haskell runtime
+ hs_init(&argc, &argv);
+
+ // Tell Haskell about all root modules
+ hs_add_root(__stginit_Foo);
+
+ // do any other initialization here and
+ // return false if there was a problem
+ return HS_BOOL_TRUE;
+ }
+
+ void mylib_end(void){
+ hs_exit();
+ }
+</programlisting>
+
+ <para>The initialisation routine, <literal>mylib_init</literal>, calls
+ <literal>hs_init()</literal> and <literal>hs_add_root()</literal> as
+ normal to initialise the Haskell runtime, and the corresponding
+ deinitialisation function <literal>mylib_end()</literal> calls
+ <literal>hs_exit()</literal> to shut down the runtime.</para>
+ </sect3>
+
+ <sect3 id="hs-exit">
+ <title>On the use of <literal>hs_exit()</literal></title>
+
+ <para><literal>hs_exit()</literal> normally causes the termination of
+ any running Haskell threads in the system, and when
+ <literal>hs_exit()</literal> returns, there will be no more Haskell
+ threads running. The runtime will then shut down the system in an
+ orderly way, generating profiling
+ output and statistics if necessary, and freeing all the memory it
+ owns.</para>
+
+ <para>It isn't always possible to terminate a Haskell thread forcibly:
+ for example, the thread might be currently executing a foreign call,
+ and we have no way to force the foreign call to complete. What's
+ more, the runtime must
+ assume that in the worst case the Haskell code and runtime are about
+ to be removed from memory (e.g. if this is a <link linkend="win32-dlls">Windows DLL</link>,
+ <literal>hs_exit()</literal> is normally called before unloading the
+ DLL). So <literal>hs_exit()</literal> <emphasis>must</emphasis> wait
+ until all outstanding foreign calls return before it can return
+ itself.</para>
+
+ <para>The upshot of this is that if you have Haskell threads that are
+ blocked in foreign calls, then <literal>hs_exit()</literal> may hang
+ (or possibly busy-wait) until the calls return. Therefore it's a
+ good idea to make sure you don't have any such threads in the system
+ when calling <literal>hs_exit()</literal>. This includes any threads
+ doing I/O, because I/O may (or may not, depending on the
+ type of I/O and the platform) be implemented using blocking foreign
+ calls.</para>
+
+ <para>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
+ <literal>hs_exit()</literal>, then call
+ <literal>shutdownHaskellAndExit()</literal> instead).</para>