[commit: packages/terminfo] master: Use set_curterm instead of peek/poking curterm directly. (9645504)
git at git.haskell.org
git at git.haskell.org
Fri Dec 18 21:50:40 UTC 2015
Repository : ssh://git@git.haskell.org/terminfo
On branch : master
Link : http://git.haskell.org/packages/terminfo.git/commitdiff/96455041834b54f86482741d940a7941c53cd01e
>---------------------------------------------------------------
commit 96455041834b54f86482741d940a7941c53cd01e
Author: Judah Jacobson <judah.jacobson at gmail.com>
Date: Mon Nov 30 23:28:27 2015 -0800
Use set_curterm instead of peek/poking curterm directly.
This fixes the build of GHC on openSUSE, which builds ncurses in "threaded"
mode. (Threaded ncurses hides the cur_term global from use).
Patch originally by Scott Bahling <sbahling at suse.com>.
We also mark set_cuterm as an "unsafe" FFI call since this change may cause
it to be called more often.
>---------------------------------------------------------------
96455041834b54f86482741d940a7941c53cd01e
System/Console/Terminfo/Base.hs | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/System/Console/Terminfo/Base.hs b/System/Console/Terminfo/Base.hs
index 1f60679..719bb65 100644
--- a/System/Console/Terminfo/Base.hs
+++ b/System/Console/Terminfo/Base.hs
@@ -63,8 +63,8 @@ import Data.Typeable
data TERMINAL
newtype Terminal = Terminal (ForeignPtr TERMINAL)
-foreign import ccall "&" cur_term :: Ptr (Ptr TERMINAL)
-foreign import ccall set_curterm :: Ptr TERMINAL -> IO (Ptr TERMINAL)
+-- Use "unsafe" to make set_curterm faster since it's called quite a bit.
+foreign import ccall unsafe set_curterm :: Ptr TERMINAL -> IO (Ptr TERMINAL)
foreign import ccall "&" del_curterm :: FunPtr (Ptr TERMINAL -> IO ())
foreign import ccall setupterm :: CString -> CInt -> Ptr CInt -> IO ()
@@ -73,19 +73,15 @@ foreign import ccall setupterm :: CString -> CInt -> Ptr CInt -> IO ()
--
-- Throws a 'SetupTermError' if the terminfo database could not be read.
setupTerm :: String -> IO Terminal
-setupTerm term = bracket (peek cur_term) (poke cur_term) $ \_ ->
+setupTerm term =
withCString term $ \c_term ->
with 0 $ \ret_ptr -> do
-- NOTE: I believe that for the way we use terminfo
-- (i.e. custom output function)
-- this parameter does not affect anything.
let stdOutput = 1
- {-- Force ncurses to return a new struct rather than
- a copy of the current one (which it would do if the
- terminal names are the same). This prevents problems
- when calling del_term on a struct shared by more than one
- Terminal. --}
- poke cur_term nullPtr
+ -- Save the previous terminal to be restored after calling setupterm.
+ old_term <- set_curterm nullPtr
-- Call setupterm and check the return value.
setupterm c_term stdOutput ret_ptr
ret <- peek ret_ptr
@@ -93,7 +89,7 @@ setupTerm term = bracket (peek cur_term) (poke cur_term) $ \_ ->
then throwIO $ SetupTermError
$ "Couldn't look up terminfo entry " ++ show term
else do
- cterm <- peek cur_term
+ cterm <- set_curterm old_term
fmap Terminal $ newForeignPtr del_curterm cterm
data SetupTermError = SetupTermError String
@@ -120,14 +116,10 @@ setupTermFromEnv = do
-- TODO: this isn't really thread-safe...
withCurTerm :: Terminal -> IO a -> IO a
withCurTerm (Terminal term) f = withForeignPtr term $ \cterm -> do
- old_term <- peek cur_term
- if old_term /= cterm
- then do
- _ <- set_curterm cterm
- x <- f
- _ <- set_curterm old_term
- return x
- else f
+ old_term <- set_curterm cterm
+ x <- f
+ set_curterm old_term
+ return x
----------------------
More information about the ghc-commits
mailing list