X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fffi-chap.xml;h=2e6ce2f372219c8d9205a07f1d6c28a39b656249;hb=0a435635320c2fb075694b52ddbce5bb792110f5;hp=7e2c547d27cd049c0911e9fbdadc626a7a26c39c;hpb=433558226790dfa88d215cf12a39df44a3ed01fd;p=ghc-hetmet.git diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml index 7e2c547..2e6ce2f 100644 --- a/docs/users_guide/ffi-chap.xml +++ b/docs/users_guide/ffi-chap.xml @@ -19,7 +19,7 @@ Foreign function interface (FFI) The FFI libraries are documented in the accompanying library documentation; see for example the - Foreign module. + Foreign module. GHC extensions to the FFI Addendum @@ -63,6 +63,101 @@ OK: + + + Primitive imports + + GHC extends the FFI with an additional calling convention + prim, e.g.: + + foreign import prim "foo" foo :: ByteArray# -> (# Int#, Int# #) + + This is used to import functions written in Cmm code that follow an + internal GHC calling convention. This feature is not intended for + use outside of the core libraries that come with GHC. For more + 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. + + @@ -461,6 +556,15 @@ int main(int argc, char *argv[]) threads, but there may be an arbitrary number of foreign calls in progress at any one time, regardless of the +RTS -N value. + + If a call is annotated as interruptible + and the program was multithreaded, the call may be + interrupted in the event that the Haskell thread receives an + exception. The mechanism by which the interrupt occurs + 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. See for more details. @@ -483,7 +587,7 @@ int main(int argc, char *argv[]) threads, which are Haskell threads tied to a particular OS thread. For information on bound threads, see the documentation - for the Control.Concurrent + for the Control.Concurrent module. @@ -548,7 +652,6 @@ int main(int argc, char *argv[])