select 0.2.1 → 0.3
raw patch · 7 files changed
+30/−125 lines, 7 filesdep −stm
Dependencies removed: stm
Files
- example/Example.hs +8/−15
- select.cabal +15/−32
- src/Control/Concurrent/MVarIO.hs +0/−19
- src/Control/Concurrent/STM/RunOrElse.hs +0/−38
- src/Control/Concurrent/STM/TMVarIO.hs +0/−21
- src/System/Posix/IO/Select.hs +6/−0
- src/System/Posix/IO/Select/select_wrapper.h +1/−0
example/Example.hs view
@@ -1,19 +1,17 @@ module Main where import System.Posix.IO--import System.Posix.IO.Select.STM-import Control.Concurrent.STM.RunOrElse-import qualified System.Posix.IO.Select.MVar as M+import System.Posix.IO.Select import Control.Concurrent-import Control.Concurrent.STM.TMVar+import Control.Concurrent.STM.OrElseIO import Control.Concurrent.STM+import Control.Concurrent.STM.TMVar import Control.Concurrent.STM.TChan - flags :: OpenFileFlags flags = OpenFileFlags { append = False, exclusive = False, noctty = False, nonBlock = True, trunc = False } +-- Needs the threaded runtime! main :: IO () main = newEmptyTMVarIO >>= \t ->@@ -27,16 +25,11 @@ openFd "fifo3" ReadOnly Nothing flags >>= \fd3 -> openFd "fifo4" ReadOnly Nothing flags >>= \fd4 -> putStrLn "The file was opened, so let the waiting game begin!" >>- -- selectOrTakeTMVar [fd,fd2,fd3,fd4] [] [] (Time 15 0) t >>= \ret ->- -- case ret of- -- Left 0 -> putStrLn "select() timed out on the files."- -- Left x -> putStrLn "There's data in one of the files!"- -- Right s -> putStrLn $ "Oh no, the interruptor is here: " ++ s- selectOrElse' (readTChan c) [fd,fd2,fd3,fd4] [] [] (Time 15 0) >>= \ret ->+ runOrElse (select [fd,fd2,fd3,fd4] [] [] (Time 9 0)) (readTChan c) >>= \ret -> case ret of- Right 0 -> putStrLn "select() timed out on the files."- Right x -> putStrLn "There's data in one of the files!"- Left s -> putStrLn $ "Oh no, the interruptor is here: " ++ s + Left 0 -> putStrLn "select() timed out on the files."+ Left x -> putStrLn "There's data in one of the files!"+ Right s -> putStrLn $ "Oh no, the interruptor is here: " ++ s interruptor :: TMVar String -> IO () interruptor t = threadDelay (10 * 1000000) >>
select.cabal view
@@ -1,6 +1,6 @@ Name: select-Version: 0.2.1-Synopsis: Give the select(2) POSIX function a simple STM interface+Version: 0.3+Synopsis: Wrap the select(2) POSIX function Homepage: http://nonempty.org/software/haskell-select License: BSD3 License-file: LICENSE@@ -12,48 +12,31 @@ Extra-source-files: src/System/Posix/IO/Select/select_wrapper.c src/System/Posix/IO/Select/select_wrapper.h Cabal-version: >=1.2 Description: While tinkering on a project, I frequently found myself- having to make FFI calls to @select(2)@. This package is an attempt- reduce the boilerplate I needed to do that. While at it, I took the- opportunity to have what @select@ returns put in a 'TMVar'.- .- The package has three parts:+ having to make FFI calls to @select(2)@. This package provides an interface to that system call.+ It also used to expose an STM interface for running @select(2)@ with alternative STM actions,+ but that functionality was split into the stm-orelse-io package from version 0.3. .- ["System.Posix.IO.Select"] just wraps @select@.+ Changes in version 0.3: .- ["Control.Concurrent.STM.TMVarIO"] and "Control.Concurrent.MVarIO" put the- return value of IO actions into a 'TMVar' or an 'MVar', respectively.+ * Split all STM-related functionality into a separate package, stm-orelse-io, independent+ of select. .- ["Control.Concurrent.STM.RunOrElse"] defines functions that give you- the return value of whatever finishes first of an IO action and an STM- operation.+ TODO: .- ["System.Posix.IO.Select.STM"] and "System.Posix.IO.Select.MVar" do the above- for the special case @select@.+ * Provide a type for @fd_set@ that can be passed to and from C so that we can have a version + of 'System.Posix.IO.select' that reports /which/ file descriptors are ready, instead of how many.+ Its type will be something like @[Fd] -> [Fd] -> [Fd] -> Timeout -> IO ([Fd], [Fd], [Fd])@. . /NOTE/: I feel I'm occupying prime namespace realestate with a package name like select. I'll happily let myself be chased away if anybody else wants to use this package name. Let me know.- .- /NOTE 2/: The vector dependency comes from me not spending time figuring out- how to pass lists of data to C without first turning them into vectors. It'll- probably disappear soon.- .- /CAVEAT/: I'm not an experienced Haskeller (as you can tell from note 2), and- this is my first foray into FFI in general. Use with caution. -- Library- Exposed-modules: Control.Concurrent.MVarIO,- Control.Concurrent.STM.TMVarIO,- Control.Concurrent.STM.RunOrElse,- System.Posix.IO.Select,- System.Posix.IO.Select.STM,- System.Posix.IO.Select.Types,- System.Posix.IO.Select.MVar+ Exposed-modules: System.Posix.IO.Select,+ System.Posix.IO.Select.Types hs-source-dirs: src- Build-depends: base >= 4 && <5, vector, stm+ Build-depends: base >= 4 && <5, vector c-sources: src/System/Posix/IO/Select/select_wrapper.c cc-options: -std=c99 -Wall -DNDEBUG
− src/Control/Concurrent/MVarIO.hs
@@ -1,19 +0,0 @@--- | Perform an IO action, and place its result in an 'MVar'. See--- also "Control.Concurrent.STM.TMVarIO" for a 'TMVar' version.-module Control.Concurrent.MVarIO (run) where--import Control.Concurrent---- | @'run' action@ returns an 'MVar' immediately. The result of--- @action@ will be placed in said 'MVar'. If the 'MVar' is full when--- @action@ completes, the return value is lost (the action does not--- wait for an empty 'MVar').-run :: IO a -> IO (MVar a)-run action = newEmptyMVar >>= \mv ->- forkIO (run' action mv) >>- return mv--run' :: IO a -> MVar a -> IO ()-run' action mv = action >>= \ret ->- tryPutMVar mv ret >>- return ()
− src/Control/Concurrent/STM/RunOrElse.hs
@@ -1,38 +0,0 @@-module Control.Concurrent.STM.RunOrElse(runOrElse, runOrElse', runOrTakeTMVar) where--import Control.Applicative-import Control.Concurrent.STM-import Control.Concurrent.STM.TMVarIO---- | @'runOrElse' action stm@ runs the IO action @action@ and attempts--- the STM operation @stm@, returning the return value which is--- available first. If @action@ returns first, then @stm@ is not--- run. If @stm@ returns first, @action@ may or may not complete, but--- its return value is discarded.------ 'runOrTakeTMVar' is a special case--- of this function, where @stm@ is simply 'takeTMVar' applied to the--- given 'TMVar'.-runOrElse :: IO a -> STM b -> IO (Either a b)-runOrElse action stm = run action >>= \tm ->- atomically ((Left <$> takeTMVar tm) `orElse` (Right <$> stm))---- | A version of 'runOrElse' that prefers the STM operation to the IO--- action.-runOrElse' :: STM a -> IO b -> IO (Either a b)-runOrElse' stm action = run action >>= \tm ->- atomically ((Left <$> stm) `orElse` (Right <$> takeTMVar tm))---- | This version of 'Control.Concurrent.STM.TMVarIO.run' takes an--- additional 'TMVar', and returns its content /or/ the result of the--- IO action, depending on which is available first. Note that the--- action is /not/ interrupted if the 'TMVar' is the winner, so you--- may want to make sure it doesn't stick around forever.------ @'runOrTakeTMVar' action tm = 'runOrElse' action ('takeTMVar' tm)@.------ The function was originally made to support--- 'System.Posix.IO.Select.STM.selectOrTakeTMVar', the reason this--- library exists.-runOrTakeTMVar :: IO a -> TMVar b -> IO (Either a b)-runOrTakeTMVar action tm = runOrElse action (takeTMVar tm)
− src/Control/Concurrent/STM/TMVarIO.hs
@@ -1,21 +0,0 @@--- | Perform an IO action, and place its result in a 'TMVar'. See--- also "Control.Concurrent.MVarIO" for an 'MVar' version.-module Control.Concurrent.STM.TMVarIO (run) where--import Data.Functor-import Control.Concurrent-import Control.Concurrent.STM---- | @'run' action@ returns a 'TMVar' immediately. The result of--- @action@ will be placed in said 'TMVar'. If the 'TMVar' is full--- when @action@ completes, the return value is lost (the action does--- not wait for an empty 'TMVar').-run :: IO a -> IO (TMVar a)-run action = newEmptyTMVarIO >>= \tm ->- forkIO (run' action tm) >>- return tm--run' :: IO a -> TMVar a -> IO ()-run' action tm = action >>= \ret ->- atomically (tryPutTMVar tm ret) >>- return ()
src/System/Posix/IO/Select.hs view
@@ -1,6 +1,12 @@ {-# LANGUAGE ForeignFunctionInterface #-} -- | Interface to the @select(2)@ POSIX function.+-- +-- TODO: +--+-- * Make a version of @'select'@ that shows which file descriptors+-- are ready. (Needs a type for fd_set that can be passed to and from+-- C). module System.Posix.IO.Select (select, Timeout(Never, Time)) where import System.Posix.IO.Select.Types
src/System/Posix/IO/Select/select_wrapper.h view
@@ -4,3 +4,4 @@ const int* writefds, int num_writefds, const int* exceptfds, int num_exceptfds, char timeout, long secs, long usecs);+