Wolfgang Jeltsch pushed to branch wip/jeltsch/obtaining-os-handles at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • libraries/base/src/GHC/IO/Handle.hs
    ... ... @@ -79,7 +79,11 @@ module GHC.IO.Handle
    79 79
          withFileDescriptorReadingBiased,
    
    80 80
          withFileDescriptorWritingBiased,
    
    81 81
          withWindowsHandleReadingBiased,
    
    82
    -     withWindowsHandleWritingBiased
    
    82
    +     withWindowsHandleWritingBiased,
    
    83
    +     withFileDescriptorReadingBiasedRaw,
    
    84
    +     withFileDescriptorWritingBiasedRaw,
    
    85
    +     withWindowsHandleReadingBiasedRaw,
    
    86
    +     withWindowsHandleWritingBiasedRaw
    
    83 87
     
    
    84 88
          -- ** Caveats
    
    85 89
          -- $with-ref-caveats
    
    ... ... @@ -90,7 +94,7 @@ import GHC.Internal.IO.Handle
    90 94
     import GHC.Internal.Control.Monad (return)
    
    91 95
     import GHC.Internal.Control.Concurrent.MVar (MVar)
    
    92 96
     import GHC.Internal.Control.Exception (mask)
    
    93
    -import GHC.Internal.Data.Function ((.), ($))
    
    97
    +import GHC.Internal.Data.Function (const, (.), ($))
    
    94 98
     import GHC.Internal.Data.Functor (fmap)
    
    95 99
     #if defined(mingw32_HOST_OS)
    
    96 100
     import GHC.Internal.Data.Bool (otherwise)
    
    ... ... @@ -132,11 +136,11 @@ import GHC.Internal.Foreign.C.Types (CInt)
    132 136
     
    
    133 137
     {-|
    
    134 138
         Obtains an operating-system handle that underlies a Haskell handle and
    
    135
    -    executes a user-provided action on it. The Haskell-managed buffers related
    
    136
    -    to the operating-system handle are flushed before the user-provided action
    
    137
    -    is run. While this action is executed, further operations on the Haskell
    
    138
    -    handle are blocked to a degree that interference with this action is
    
    139
    -    prevented.
    
    139
    +    executes a user-provided action on it. Before the user-provided action is
    
    140
    +    run, user-defined perparation based on the handle state that contains the
    
    141
    +    operating-system handle is performed. While the user-provided action is
    
    142
    +    executed, further operations on the Haskell handle are blocked to a degree
    
    143
    +    that interference with this action is prevented.
    
    140 144
     
    
    141 145
         See [below](#with-ref-caveats) for caveats regarding this operation.
    
    142 146
     -}
    
    ... ... @@ -149,16 +153,18 @@ withOSHandle :: String
    149 153
                     -}
    
    150 154
                  -> (forall d. Typeable d => d -> IO a)
    
    151 155
                     -- ^ Conversion of a device into an operating-system handle
    
    156
    +             -> (Handle__ -> IO ())
    
    157
    +                -- ^ The preparation
    
    152 158
                  -> Handle
    
    153 159
                     -- ^ The Haskell handle to use
    
    154 160
                  -> (a -> IO r)
    
    155 161
                     -- ^ The action to execute on the operating-system handle
    
    156 162
                  -> IO r
    
    157
    -withOSHandle opName handleStateVar getOSHandle handle act
    
    163
    +withOSHandle opName handleStateVar getOSHandle prepare handle act
    
    158 164
         = mask $ \ withOriginalMaskingState ->
    
    159 165
           withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
    
    160 166
               osHandle <- getOSHandle dev
    
    161
    -          flushBuffer handleState
    
    167
    +          prepare handleState
    
    162 168
               withOriginalMaskingState $ act osHandle
    
    163 169
           where
    
    164 170
     
    
    ... ... @@ -272,6 +278,7 @@ withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
    272 278
     withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
    
    273 279
                                                    handleStateVarReadingBiased
    
    274 280
                                                    getFileDescriptor
    
    281
    +                                               flushBuffer
    
    275 282
     
    
    276 283
     {-|
    
    277 284
         Obtains the POSIX file descriptor that underlies a handle or specifically
    
    ... ... @@ -290,6 +297,7 @@ withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
    290 297
     withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
    
    291 298
                                                    handleStateVarWritingBiased
    
    292 299
                                                    getFileDescriptor
    
    300
    +                                               flushBuffer
    
    293 301
     
    
    294 302
     {-|
    
    295 303
         Obtains the Windows handle that underlies a Haskell handle or specifically
    
    ... ... @@ -308,6 +316,7 @@ withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
    308 316
     withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
    
    309 317
                                                   handleStateVarReadingBiased
    
    310 318
                                                   getWindowsHandle
    
    319
    +                                              flushBuffer
    
    311 320
     
    
    312 321
     {-|
    
    313 322
         Obtains the Windows handle that underlies a Haskell handle or specifically
    
    ... ... @@ -326,17 +335,62 @@ withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
    326 335
     withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
    
    327 336
                                                   handleStateVarWritingBiased
    
    328 337
                                                   getWindowsHandle
    
    338
    +                                              flushBuffer
    
    339
    +
    
    340
    +{-|
    
    341
    +    Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
    
    342
    +    are not flushed.
    
    343
    +-}
    
    344
    +withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
    
    345
    +withFileDescriptorReadingBiasedRaw
    
    346
    +    = withOSHandle "withFileDescriptorReadingBiasedRaw"
    
    347
    +                   handleStateVarReadingBiased
    
    348
    +                   getFileDescriptor
    
    349
    +                   (const $ return ())
    
    350
    +
    
    351
    +{-|
    
    352
    +    Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
    
    353
    +    are not flushed.
    
    354
    +-}
    
    355
    +withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
    
    356
    +withFileDescriptorWritingBiasedRaw
    
    357
    +    = withOSHandle "withFileDescriptorWritingBiasedRaw"
    
    358
    +                   handleStateVarWritingBiased
    
    359
    +                   getFileDescriptor
    
    360
    +                   (const $ return ())
    
    361
    +
    
    362
    +{-|
    
    363
    +    Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
    
    364
    +    are not flushed.
    
    365
    +-}
    
    366
    +withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
    
    367
    +withWindowsHandleReadingBiasedRaw
    
    368
    +    = withOSHandle "withWindowsHandleReadingBiasedRaw"
    
    369
    +                   handleStateVarReadingBiased
    
    370
    +                   getWindowsHandle
    
    371
    +                   (const $ return ())
    
    372
    +
    
    373
    +{-|
    
    374
    +    Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
    
    375
    +    are not flushed.
    
    376
    +-}
    
    377
    +withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
    
    378
    +withWindowsHandleWritingBiasedRaw
    
    379
    +    = withOSHandle "withWindowsHandleWritingBiasedRaw"
    
    380
    +                   handleStateVarWritingBiased
    
    381
    +                   getWindowsHandle
    
    382
    +                   (const $ return ())
    
    329 383
     
    
    330 384
     -- ** Caveats
    
    331 385
     
    
    332 386
     {-$with-ref-caveats
    
    333
    -    #with-ref-caveats#There are the following caveats regarding each of the
    
    334
    -    above operations:
    
    387
    +    #with-ref-caveats#There are the following caveats regarding the above
    
    388
    +    operations:
    
    335 389
     
    
    336
    -      * The flushing of buffers can fail if the given handle is readable but not
    
    390
    +      * Flushing of buffers can fail if the given handle is readable but not
    
    337 391
             seekable.
    
    338 392
     
    
    339
    -      * If the operation is performed as part of an action executed by
    
    393
    +      * If one of these operation is performed as part of an action executed by
    
    340 394
             'unsafePerformIO', 'unsafeInterleaveIO', or one of their “dupable”
    
    341 395
             variants and the user-provided action receives an asychnchronous
    
    342 396
             exception and does not catch it, then the following happens: