diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2010, Nils Schweinsberg
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/mstate.cabal b/mstate.cabal
new file mode 100644
--- /dev/null
+++ b/mstate.cabal
@@ -0,0 +1,26 @@
+Name:           mstate
+Synopsis:       MState: A consistent State monad for concurrent applications.
+Description:    MState offers a State monad which can be used in concurrent
+                applications. It also manages new threads and waits until the
+                whole state monad has been evaluated/executed before it returns
+                the state values.
+
+Author:         Nils Schweinsberg
+Maintainer:     <mail@n-sch.de>
+
+Version:        0.1
+Category:       Concurrent, Monads
+License:        BSD3
+License-File:   LICENSE
+Cabal-Version:  >= 1.6
+Build-Type:     Simple
+
+Library
+    GHC-Options:        -Wall
+    Hs-Source-Dirs:     src
+    Build-Depends:
+        base    == 4.*,
+        mtl     == 1.*
+
+    Exposed-Modules:
+        Control.Concurrent.MState
diff --git a/src/Control/Concurrent/MState.hs b/src/Control/Concurrent/MState.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/MState.hs
@@ -0,0 +1,217 @@
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
+
+---------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Concurrent.MState
+-- Copyright   :  (c) Nils Schweinsberg 2010
+-- License     :  BSD3-style (see LICENSE)
+--
+-- Maintainer  :  mail@n-sch.de
+-- Stability   :  unstable
+-- Portability :  portable
+--
+-- MState: A consistent State monad for concurrent applications.
+--
+---------------------------------------------------------------------------
+
+module Control.Concurrent.MState
+    ( 
+      -- * The MState Monad
+      MState
+    , runMState
+    , evalMState
+    , execMState
+    , mapMState
+    , withMState
+
+      -- * Concurrency
+    , Forkable (..)
+    , forkM
+
+      -- * Example
+      -- $example
+    ) where
+
+import Control.Monad
+import Control.Monad.State.Class
+import Control.Monad.Trans
+
+import Control.Concurrent
+import Data.IORef
+
+import qualified Control.Exception as E
+
+
+-- | The MState is an abstract data definition for a State monad which can be
+-- used in concurrent applications. It can be accessed with @evalMState@ and
+-- @execMState@. To start a new state thread use @forkM@.
+newtype MState t m a = MState { runMState' :: (IORef t, Chan (MVar ())) -> m a }
+
+
+-- | The class which is needed to start new threads in the MState monad. Don't
+-- confuse this with @forkM@ which should be used to fork new threads!
+class (MonadIO m) => Forkable m where
+    fork :: m () -> m ThreadId
+
+instance Forkable IO where
+    fork = forkIO
+
+
+catchMVar :: IO a -> (E.BlockedIndefinitelyOnMVar -> IO a) -> IO a
+catchMVar = E.catch
+
+
+-- | Read the Chan full of MVars and wait for all MVars to get filled by the
+-- threads. On MVar-exception this will skip the current MVar and take the next
+-- one (if available).
+waitForTermination :: MonadIO m
+                   => Chan (MVar ())
+                   -> m ()
+waitForTermination c = liftIO $ do
+    empty <- isEmptyChan c
+    catchMVar (unless empty $ do -- Read next threads MVar and wait until it's filled
+                                 mv <- readChan c
+                                 _  <- takeMVar mv
+                                 waitForTermination c)
+              (const $ return ())
+
+
+-- | Run the MState and return both, the function value and the state value
+runMState :: Forkable m
+           => MState t m a      -- ^ Action to evaluate
+           -> t                 -- ^ Initial state value
+           -> m (a,t)
+runMState m t = do
+
+    ref <- liftIO $ newIORef t
+    c   <- liftIO newChan
+    mv  <- liftIO newEmptyMVar
+
+    _  <- runMState' (forkM $ m >>= liftIO . putMVar mv) (ref, c)
+
+    waitForTermination c
+    a  <- liftIO $ takeMVar mv
+    t' <- liftIO $ readIORef ref
+    return (a,t')
+
+
+-- | Evaluate the MState monad with the given initial state, throwing away the
+-- final state stored in the MVar.
+evalMState :: Forkable m
+           => MState t m a      -- ^ Action to evaluate
+           -> t                 -- ^ Initial state value
+           -> m a
+evalMState m t = runMState m t >>= return . fst
+
+
+-- | Execute the MState monad with a given initial state. Returns the value of
+-- the final state.
+execMState :: Forkable m
+           => MState t m a      -- ^ Action to execute
+           -> t                 -- ^ Initial state value
+           -> m t
+execMState m t = runMState m t >>= return . snd
+
+
+-- | Map a stateful computation from one @(return value, state)@ pair to
+-- another. See @Control.Monad.State.Lazy.mapState@ for more information.
+mapMState :: (MonadIO m, MonadIO n)
+          => (m (a,t) -> n (b,t))
+          -> MState t m a
+          -> MState t n b
+mapMState f m = MState $ \s@(r,_) -> do
+    ~(b,v') <- f $ do
+        a <- runMState' m s
+        v <- liftIO $ readIORef r
+        return (a,v)
+    liftIO $ writeIORef r v'
+    return b
+
+
+-- | Apply this function to this state and return the resulting state.
+withMState :: (MonadIO m)
+           => (t -> t)
+           -> MState t m a
+           -> MState t m a
+withMState f m = MState $ \s@(r,_) -> do
+    liftIO $ modifyIORef r f
+    runMState' m s
+
+
+-- | Start a new thread, using @forkIO@. The main process will wait for all
+-- child processes to finish.
+forkM :: Forkable m
+      => MState t m ()         -- ^ State action to be forked
+      -> MState t m ThreadId
+forkM m = MState $ \s@(_,c) -> do
+
+    -- Add new thread MVar to our waiting channel
+    w <- liftIO newEmptyMVar
+    liftIO $ writeChan c w
+    fork $ runMState' m s >> liftIO (putMVar w ())
+
+
+--------------------------------------------------------------------------------
+-- Monad instances
+--------------------------------------------------------------------------------
+
+instance (Monad m) => Monad (MState t m) where
+    return a = MState $ \_ -> return a
+    m >>= k  = MState $ \t -> do
+        a <- runMState' m t
+        runMState' (k a) t
+    fail str = MState $ \_ -> fail str
+
+instance (Monad m) => Functor (MState t m) where
+    fmap f m = MState $ \t -> do
+        a <- runMState' m t
+        return (f a)
+
+instance (MonadPlus m) => MonadPlus (MState t m) where
+    mzero       = MState $ \_       -> mzero
+    m `mplus` n = MState $ \t -> runMState' m t `mplus` runMState' n t
+
+instance (MonadIO m) => MonadState t (MState t m) where
+    get     = MState $ \(r,_) -> liftIO $ readIORef r
+    put val = MState $ \(r,_) -> liftIO $ writeIORef r val
+
+instance MonadTrans (MState t) where
+    lift m = MState $ \_ -> m
+
+instance (MonadIO m) => MonadIO (MState t m) where
+    liftIO = lift . liftIO
+
+
+{- $example
+
+Example usage:
+
+> import Control.Concurrent
+> import Control.Concurrent.MState
+> import Control.Monad.State
+> 
+> type MyState a = MState Int IO a
+> 
+> -- Expected state value: 2
+> main = print =<< execMState incTwice 0
+> 
+> incTwice :: MyState ()
+> incTwice = do
+> 
+>     -- First inc
+>     inc
+> 
+>     -- This thread should get killed before it can "inc" our state:
+>     kill =<< forkM incDelayed
+>     -- This thread should "inc" our state
+>     forkM incDelayed
+> 
+>     return ()
+> 
+>   where
+>     inc        = get >>= put . (+1)
+>     kill       = liftIO . killThread
+>     incDelayed = do liftIO $ threadDelay 2000000
+>                     inc
+
+-}
