Index: uspace/lib/cpp/include/__bits/thread/future.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future.hpp	(revision d86c00f06f2a1ec0887539b0bf8be7148152287d)
+++ uspace/lib/cpp/include/__bits/thread/future.hpp	(revision 6e97265b96eea3b6aee139c2a86b672697a762e9)
@@ -30,75 +30,131 @@
 #define LIBCPP_BITS_THREAD_FUTURE
 
+#include <__bits/thread/future_common.hpp>
+#include <__bits/thread/shared_state.hpp>
+#include <__bits/utility/forward_move.hpp>
 #include <cassert>
-#include <memory>
-#include <system_error>
-#include <thread>
-#include <tuple>
-#include <type_traits>
-#include <utility>
 
 namespace std
 {
     /**
-     * 30.6, futures:
-     */
-
-    enum class future_errc
-    { // The 5001 start is to not collide with system_error's codes.
-        broken_promise = 5001,
-        future_already_retrieved,
-        promise_already_satisfied,
-        no_state
-    };
-
-    enum class future_status
-    {
-        ready,
-        timeout,
-        deferred
-    };
-
-    /**
-     * 30.6.2, error handling:
-     */
-
-    template<>
-    struct is_error_code_enum<future_errc>: true_type
-    { /* DUMMY BODY */ };
-
-    error_code make_error_code(future_errc) noexcept;
-    error_condition make_error_condition(future_errc) noexcept;
-
-    const error_category& future_category() noexcept;
-
-    /**
-     * 30.6.3, class future_error:
-     */
-
-    class future_error: public logic_error
-    {
-        public:
-            future_error(error_code ec);
-
-            const error_code& code() const noexcept;
-            const char* what() const noexcept;
-
-        private:
-            error_code code_;
-    };
-
-    /**
      * 30.6.6, class template future:
      */
 
+    namespace aux
+    {
+        template<class R>
+        class future_base
+        {
+            public:
+                future_base() noexcept
+                    : state_{nullptr}
+                { /* DUMMY BODY */ }
+
+                future_base(const future_base&) = delete;
+
+                future_base(future_base&& rhs) noexcept
+                    : state_{std::move(rhs.state_)}
+                {
+                    rhs.state_ = nullptr;
+                }
+
+                future_base(aux::shared_state<R>* state)
+                    : state_{state}
+                {
+                    /**
+                     * Note: This is a custom non-standard constructor that allows
+                     *       us to create a future directly from a shared state. This
+                     *       should never be a problem as aux::shared_state is a private
+                     *       type and future has no constructor templates.
+                     */
+                }
+
+                virtual ~future_base()
+                {
+                    release_state_();
+                }
+
+                future_base& operator=(const future_base&) = delete;
+
+                future_base& operator=(future_base&& rhs) noexcept
+                {
+                    release_state_();
+                    state_ = std::move(rhs.state_);
+                    rhs.state_ = nullptr;
+                }
+
+                bool valid() const noexcept
+                {
+                    return state_ != nullptr;
+                }
+
+                void wait() const noexcept
+                {
+                    assert(state_);
+
+                    state_->wait();
+                }
+
+                template<class Rep, class Period>
+                future_status
+                wait_for(const chrono::duration<Rep, Period>& rel_time) const
+                {
+                    assert(state_);
+
+                    return state_->wait_for(rel_time);
+                }
+
+                template<class Clock, class Duration>
+                future_status
+                wait_until(
+                    const chrono::time_point<Clock, Duration>& abs_time
+                ) const
+                {
+                    assert(state_);
+
+                    return state_->wait_until(abs_time);
+                }
+
+            protected:
+                void release_state_()
+                {
+                    if (!state_)
+                        return;
+
+                    /**
+                     * Note: This is the 'release' move described in
+                     *       30.6.4 (5).
+                     * Last reference to state -> destroy state.
+                     * Decrement refcount of state otherwise.
+                     * Will not block, unless all following hold:
+                     *  1) State was created by call to std::async.
+                     *  2) State is not yet ready.
+                     *  3) This was the last reference to the shared state.
+                     */
+                    if (state_->decrement())
+                    {
+                        /**
+                         * The destroy call handles the special case
+                         * when 1) - 3) hold.
+                         */
+                        state_->destroy();
+                        delete state_;
+                        state_ = nullptr;
+                    }
+                }
+
+                aux::shared_state<R>* state_;
+        };
+    }
+
     template<class R>
     class shared_future;
 
     template<class R>
-    class future
+    class future: public aux::future_base<R>
     {
         public:
             future() noexcept
-                : state_{nullptr}
+                : aux::future_base<R>{}
             { /* DUMMY BODY */ }
 
@@ -106,32 +162,16 @@
 
             future(future&& rhs) noexcept
-                : state_{std::move(rhs.state_)}
-            {
-                rhs.state_ = nullptr;
-            }
+                : aux::future_base<R>{std::move(rhs.state_)}
+            { /* DUMMY BODY */ }
 
             future(aux::shared_state<R>* state)
-                : state_{state}
-            {
-                /**
-                 * Note: This is a custom non-standard constructor that allows
-                 *       us to create a future directly from a shared state. This
-                 *       should never be a problem as aux::shared_state is a private
-                 *       type and future has no constructor templates.
-                 */
-            }
-
-            ~future()
-            {
-                release_state_();
-            }
-
-            future& operator=(const future) = delete;
+                : aux::future_base<R>{state}
+            { /* DUMMY BODY */ }
+
+            future& operator=(const future&) = delete;
 
             future& operator=(future&& rhs) noexcept
             {
-                release_state_();
-                state_ = std::move(rhs.state_);
-                rhs.state_ = nullptr;
+                return aux::future_base<R>::operator=(std::move(rhs));
             }
 
@@ -143,74 +183,16 @@
             R get()
             {
-                assert(state_);
-
-                wait();
-
-                if (state_->has_exception())
-                    state_->throw_stored_exception();
-                auto res = std::move(state_->get());
-
-                release_state_();
+                assert(this->state_);
+
+                this->wait();
+
+                if (this->state_->has_exception())
+                    this->state_->throw_stored_exception();
+                auto res = std::move(this->state_->get());
+
+                this->release_state_();
 
                 return res;
             }
-
-            bool valid() const noexcept
-            {
-                return state_ != nullptr;
-            }
-
-            void wait() const noexcept
-            {
-                assert(state_);
-
-                state_->wait();
-            }
-
-            template<class Rep, class Period>
-            future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const
-            {
-                assert(state_);
-
-                return state_->wait_for(rel_time);
-            }
-
-            template<class Clock, class Duration>
-            future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
-            {
-                assert(state_);
-
-                return state_->wait_until(abs_time);
-            }
-
-        private:
-            void release_state_()
-            {
-                if (!state_)
-                    return;
-
-                /**
-                 * Note: This is the 'release' move described in
-                 *       30.6.4 (5).
-                 * Last reference to state -> destroy state.
-                 * Decrement refcount of state otherwise.
-                 * Will not block, unless all following hold:
-                 *  1) State was created by call to std::async.
-                 *  2) State is not yet ready.
-                 *  3) This was the last reference to the shared state.
-                 */
-                if (state_->decrement())
-                {
-                    /**
-                     * The destroy call handles the special case
-                     * when 1) - 3) hold.
-                     */
-                    state_->destroy();
-                    delete state_;
-                    state_ = nullptr;
-                }
-            }
-
-            aux::shared_state<R>* state_;
     };
 
Index: uspace/lib/cpp/include/__bits/thread/future_common.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future_common.hpp	(revision 6e97265b96eea3b6aee139c2a86b672697a762e9)
+++ uspace/lib/cpp/include/__bits/thread/future_common.hpp	(revision 6e97265b96eea3b6aee139c2a86b672697a762e9)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - 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.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef LIBCPP_BITS_THREAD_FUTURE_COMMON
+#define LIBCPP_BITS_THREAD_FUTURE_COMMON
+
+#include <system_error>
+#include <stdexcept>
+
+namespace std
+{
+    /**
+     * 30.6, futures:
+     */
+
+    enum class future_errc
+    { // The 5001 start is to not collide with system_error's codes.
+        broken_promise = 5001,
+        future_already_retrieved,
+        promise_already_satisfied,
+        no_state
+    };
+
+    enum class future_status
+    {
+        ready,
+        timeout,
+        deferred
+    };
+
+    /**
+     * 30.6.2, error handling:
+     */
+
+    template<>
+    struct is_error_code_enum<future_errc>: true_type
+    { /* DUMMY BODY */ };
+
+    error_code make_error_code(future_errc) noexcept;
+    error_condition make_error_condition(future_errc) noexcept;
+
+    const error_category& future_category() noexcept;
+
+    /**
+     * 30.6.3, class future_error:
+     */
+
+    class future_error: public logic_error
+    {
+        public:
+            future_error(error_code ec);
+
+            const error_code& code() const noexcept;
+            const char* what() const noexcept;
+
+        private:
+            error_code code_;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/shared_state.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/shared_state.hpp	(revision d86c00f06f2a1ec0887539b0bf8be7148152287d)
+++ uspace/lib/cpp/include/__bits/thread/shared_state.hpp	(revision 6e97265b96eea3b6aee139c2a86b672697a762e9)
@@ -34,8 +34,18 @@
  */
 
+#include <__bits/exception.hpp>
 #include <__bits/functional/function.hpp>
 #include <__bits/functional/invoke.hpp>
 #include <__bits/refcount_obj.hpp>
+#include <__bits/thread/future_common.hpp>
 #include <__bits/thread/threading.hpp>
+#include <cerrno>
+#include <thread>
+#include <tuple>
+
+namespace std
+{
+    enum class future_status;
+}
 
 namespace std::aux
@@ -137,44 +147,60 @@
 
             template<class Rep, class Period>
-            virtual future_status
+            future_status
             wait_for(const chrono::duration<Rep, Period>& rel_time)
             {
                 aux::threading::mutex::lock(mutex_);
-                auto res = aux::threading::condvar::wait_for(
-                    condvar_, mutex_,
+                auto res = timed_wait_(
                     aux::threading::time::convert(rel_time)
                 );
                 aux::threading::mutex::unlock(mutex_);
 
+                return res;
+            }
+
+            template<class Clock, class Duration>
+            future_status
+            wait_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                aux::threading::mutex::lock(mutex_);
+                auto res = timed_wait_(
+                    aux::threading::time(convert(abs_time - Clock::now()))
+                );
+                aux::threading::mutex::unlock(mutex_);
+
+                return res;
+            }
+
+            ~shared_state() override = default;
+
+        protected:
+            aux::mutex_t mutex_;
+            aux::condvar_t condvar_;
+
+            R value_;
+            bool value_set_;
+
+            exception_ptr exception_;
+            bool has_exception_;
+
+            /**
+             * Note: wait_for and wait_until are templates and as such
+             *       cannot be virtual and overriden by the deferred_ and
+             *       async_ children. However, we are using aux::time_unit_t
+             *       in the end anyway, so we can work around that
+             *       by using the 'template method' design pattern
+             *       (i.e. by providing a virtual function called by these
+             *       templates and then overriding that function in the
+             *       children).
+             */
+            virtual future_status timed_wait_(aux::time_unit_t time)
+            {
+                auto res = aux::threading::condvar::wait_for(
+                    condvar_, mutex_, time
+                );
+
                 return res == ETIMEOUT ? future_status::timeout
                                        : future_status::ready;
             }
-
-            template<class Clock, class Duration>
-            virtual future_status
-            wait_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                aux::threading::mutex::lock(mutex_);
-                auto res = aux::threading::condvar::wait_for(
-                    condvar_, mutex_,
-                    aux::threading::time::convert(abs_time - Clock::now())
-                );
-                aux::threading::mutex::unlock(mutex_);
-
-                return res == ETIMEOUT ? future_status::timeout
-                                       : future_status::ready;
-            }
-
-            ~shared_state() override = default;
-
-        private:
-            aux::mutex_t mutex_;
-            aux::condvar_t condvar_;
-
-            R value_;
-            bool value_set_;
-
-            exception_ptr exception_;
-            bool has_exception_;
     };
 
@@ -224,23 +250,14 @@
             }
 
-            template<class Rep, class Period>
-            future_status
-            wait_for(const chrono::duration<Rep, Period>&) override
+            ~async_shared_state() override
+            {
+                destroy();
+            }
+
+        protected:
+            future_status timed_wait_(aux::time_unit_t) override
             {
                 // TODO: have to sleep and check
-                return future_status::ready;
-            }
-
-            template<class Clock, class Duration>
-            future_status
-            wait_until(const chrono::time_point<Clock, Duration>&) override
-            {
-                // TODO: have to sleep and check
-                return future_status::ready;
-            }
-
-            ~async_shared_state() override
-            {
-                destroy();
+                return future_status::timeout;
             }
 
@@ -261,35 +278,17 @@
             void destroy() override
             {
-                aux::threading::mutex::lock(mutex_);
+                aux::threading::mutex::lock(this->mutex_);
                 if (!this->is_set())
                     invoke_(make_index_sequence<sizeof...(Args)>{});
-                aux::threading::mutex::unlock(mutex_);
+                aux::threading::mutex::unlock(this->mutex_);
             }
 
             void wait() override
             {
-                aux::threading::mutex::lock(mutex_);
+                /**
+                 * Note: Synchronization done in invoke_ -> set_value.
+                 */
                 if (!this->is_set())
                     invoke_(make_index_sequence<sizeof...(Args)>{});
-                aux::threading::mutex::unlock(mutex_);
-            }
-
-            template<class Rep, class Period>
-            future_status
-            wait_for(const chrono::duration<Rep, Period>&) override
-            {
-                /**
-                 * Note: Neither of the wait_ functions has any effect
-                 *       for deferred functions spawned by async (which
-                 *       are the only users of this state type).
-                 */
-                return future_status::deferred;
-            }
-
-            template<class Clock, class Duration>
-            future_status
-            wait_until(const chrono::time_point<Clock, Duration>&) override
-            {
-                return future_status::deferred;
             }
 
@@ -299,5 +298,5 @@
             }
 
-        private:
+        protected:
             function<R(decay_t<Args>...)> func_;
             tuple<decay_t<Args>...> args_;
@@ -315,4 +314,14 @@
                 }
             }
+
+            future_status timed_wait_(aux::time_unit_t) override
+            {
+                /**
+                 * Note: Neither of the wait_ functions has any effect
+                 *       for deferred functions spawned by async (which
+                 *       are the only users of this state type).
+                 */
+                return future_status::deferred;
+            }
     };
 }
