X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fusers_guide%2Fffi-chap.xml;h=aea2f5eb137c9c7580bdab1b29bcd65f5acb177b;hp=b33e95abb6e67ee60164ad14d23f6f5832745eeb;hb=46809fa91667e952afe016e4cd704b21274241b4;hpb=83d563cb9ede0ba792836e529b1e2929db926355
diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml
index b33e95a..aea2f5e 100644
--- a/docs/users_guide/ffi-chap.xml
+++ b/docs/users_guide/ffi-chap.xml
@@ -6,10 +6,10 @@
Foreign function interface (FFI)
- GHC (mostly) conforms to the Haskell 98 Foreign Function Interface
- Addendum 1.0, whose definition is available from http://www.haskell.org/.
+ GHC (mostly) conforms to the Haskell Foreign Function Interface,
+ whose definition is part of the Haskell Report on http://www.haskell.org/.
- To enable FFI support in GHC, give the
+ FFI support is enabled by default, but can be enabled or disabled explicitly with the flag.GHC implements a number of GHC-specific extensions to the FFI
@@ -78,6 +78,86 @@ OK:
details see the GHC developer wiki.
+
+
+ Interruptible foreign calls
+
+ This concerns the interaction of foreign calls
+ with Control.Concurrent.throwTo.
+ Normally when the target of a throwTo is
+ involved in a foreign call, the exception is not raised
+ until the call returns, and in the meantime the caller is
+ blocked. This can result in unresponsiveness, which is
+ particularly undesirable in the case of user interrupt
+ (e.g. Control-C). The default behaviour when a Control-C
+ signal is received (SIGINT on Unix) is to raise
+ the UserInterrupt exception in the main
+ thread; if the main thread is blocked in a foreign call at
+ the time, then the program will not respond to the user
+ interrupt.
+
+
+
+ The problem is that it is not possible in general to
+ interrupt a foreign call safely. However, GHC does provide
+ a way to interrupt blocking system calls which works for
+ most system calls on both Unix and Windows. A foreign call
+ can be annotated with interruptible instead
+ of safe or unsafe:
+
+
+foreign import ccall interruptible
+ "sleep" :: CUint -> IO CUint
+
+
+ interruptble behaves exactly as
+ safe, except that when
+ a throwTo is directed at a thread in an
+ interruptible foreign call, an OS-specific mechanism will be
+ used to attempt to cause the foreign call to return:
+
+
+
+ Unix systems
+
+
+ The thread making the foreign call is sent
+ a SIGPIPE signal
+ using pthread_kill(). This is
+ usually enough to cause a blocking system call to
+ return with EINTR (GHC by default
+ installs an empty signal handler
+ for SIGPIPE, to override the
+ default behaviour which is to terminate the process
+ immediately).
+
+
+
+
+ Windows systems
+
+
+ [Vista and later only] The RTS calls the Win32
+ function CancelSynchronousIO,
+ which will cause a blocking I/O operation to return
+ with the
+ error ERROR_OPERATION_ABORTED.
+
+
+
+
+
+ If the system call is successfully interrupted, it will
+ return to Haskell whereupon the exception can be raised. Be
+ especially careful when
+ using interruptible that the caller of
+ the foreign function is prepared to deal with the
+ consequences of the call being interrupted; on Unix it is
+ good practice to check for EINTR always,
+ but on Windows it is not typically necessary to
+ handle ERROR_OPERATION_ABORTED.
+
+
@@ -484,7 +564,7 @@ int main(int argc, char *argv[])
is platform dependent, but is intended to cause blocking
system calls to return immediately with an interrupted error
code. The underlying operating system thread is not to be
- destroyed.
+ destroyed. See for more details.