on master help sign in
Invoke write directly instead of via hPutBuf

Ignore-this: 172072f7a4876e5864c8e54f896bf0b0 darcs-hash:20100114091229-f0a0d-915e8160f8cf596abbae4df8c9d883febeedf509.gz

commit4f06259de31dab3e0c9cc529a150464912934e3d authorcoreyoconnor <coreyoconnor@gmail.com> dateThu 14 Jan 2010, 01:12 (17 years ago) parentac46ab8
5 files changed+38−6
cbits/output_buffer.c+18 cbits/output_buffer.h+5 src/Graphics/Vty/Terminal/TerminfoBased.hs+12−5 test/Makefile+1−1 vty.cabal+2
cbits/output_buffer.cnew file+18
@@ -0,0 +1,18 @@
1+#define _XOPEN_SOURCE 500
2+#include <unistd.h>
3+
4+#include "output_buffer.h"
5+
6+void stdout_output_buffer ( uint8_t* buffer, size_t buffer_size )
7+{
8+ while ( buffer_size )
9+ {
10+ const ssize_t r = write( STDOUT_FILENO, (void*) buffer, buffer_size );
11+
12+ buffer_size -= (size_t) r;
13+ buffer += (size_t) r;
14+ }
15+
16+ fdatasync( STDOUT_FILENO );
17+}
18+
cbits/output_buffer.hnew file+5
@@ -0,0 +1,5 @@
1+#define _XOPEN_SOURCE 500
2+#include <unistd.h>
3+#include <stdint.h>
4+
5+void stdout_output_buffer ( uint8_t* buffer, size_t buffer_size );
src/Graphics/Vty/Terminal/TerminfoBased.hs+12−5
@@ -2,6 +2,7 @@
22{-# LANGUAGE ForeignFunctionInterface #-}
33{-# LANGUAGE ScopedTypeVariables #-}
44{-# LANGUAGE FlexibleInstances #-}
5+{-# OPTIONS_GHC -D_XOPEN_SOURCE=500 #-}
56module Graphics.Vty.Terminal.TerminfoBased ( terminal_instance
67 )
78 where
@@ -22,7 +23,8 @@ import Data.Bits ( (.&.) )
2223import Data.Maybe ( isJust, isNothing, fromJust )
2324import Data.Word
2425
25−import Foreign.C.Types ( CLong )
26+import Foreign.Ptr
27+import Foreign.C.Types ( CLong, CSize )
2628
2729import qualified System.Console.Terminfo as Terminfo
2830import System.IO
@@ -164,12 +166,17 @@ instance Terminal Term where
164166
165167 -- Output the byte buffer of the specified size to the terminal device.
166168 output_byte_buffer _t out_ptr out_byte_count = do
167− if out_byte_count == 0
168− then return ()
169− else hPutBuf stdout out_ptr (fromEnum out_byte_count)
169+ -- flush is required *before* the c_output_byte_buffer call
170+ -- otherwise there may still be data in GHC's internal stdout buffer.
170171 hFlush stdout
172+ if out_byte_count /= 0
173+ then c_output_byte_buffer out_ptr ( toEnum $! fromEnum out_byte_count )
174+ else return ()
171175
172−foreign import ccall "gwinsz.h c_get_window_size" c_get_window_size :: IO CLong
176+foreign import ccall unsafe "output_buffer.h stdout_output_buffer" c_output_byte_buffer
177+ :: Ptr Word8 -> CSize -> IO ()
178+foreign import ccall "gwinsz.h c_get_window_size" c_get_window_size
179+ :: IO CLong
173180
174181get_window_size :: IO (Int,Int)
175182get_window_size = do
test/Makefile+1−1
@@ -26,7 +26,7 @@ $(VERIF_TESTS)
2626$(shell mkdir -p objects )
2727
2828# TODO: Tests should also be buildable referencing the currently installed vty
29−GHC_ARGS=--make -i../src -package parallel -package deepseq-1.1.0.0 -hide-package transformers -hide-package monads-fd -hide-package monads-tf -package QuickCheck-2.1.0.2 -ignore-package vty ../cbits/gwinsz.c ../cbits/set_term_timing.c ../cbits/mk_wcwidth.c -O -funbox-strict-fields -Wall -threaded -fno-full-laziness -fspec-constr -odir objects -hidir objects
29+GHC_ARGS=--make -i../src -package parallel -package deepseq-1.1.0.0 -hide-package transformers -hide-package monads-fd -hide-package monads-tf -package QuickCheck-2.1.0.2 -ignore-package vty ../cbits/gwinsz.c ../cbits/output_buffer.c ../cbits/set_term_timing.c ../cbits/mk_wcwidth.c -O -funbox-strict-fields -Wall -threaded -fno-full-laziness -fspec-constr -odir objects -hidir objects
3030
3131GHC_PROF_ARGS=-prof -auto-all $(GHC_ARGS)
3232
vty.cabal+2
@@ -59,6 +59,8 @@ other-modules: Codec.Binary.UTF8.Width
5959C-Sources: cbits/gwinsz.c
6060 cbits/set_term_timing.c
6161 cbits/mk_wcwidth.c
62+ cbits/output_buffer.c
63+
6264Include-Dirs: cbits
6365hs-source-dirs: src
6466Extra-Source-Files: test/Makefile