os/ossrv/ossrv_pub/boost_apis/boost/thread/condition.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (C) 2001-2003
sl@0
     2
// William E. Kempf
sl@0
     3
//
sl@0
     4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
sl@0
     5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
     6
sl@0
     7
#ifndef BOOST_CONDITION_WEK070601_HPP
sl@0
     8
#define BOOST_CONDITION_WEK070601_HPP
sl@0
     9
sl@0
    10
#include <boost/thread/detail/config.hpp>
sl@0
    11
sl@0
    12
#include <boost/thread/exceptions.hpp>
sl@0
    13
#include <boost/utility.hpp>
sl@0
    14
#include <boost/thread/detail/lock.hpp>
sl@0
    15
sl@0
    16
#if defined(BOOST_HAS_PTHREADS)
sl@0
    17
#   include <pthread.h>
sl@0
    18
#elif defined(BOOST_HAS_MPTASKS)
sl@0
    19
#   include "scoped_critical_region.hpp"
sl@0
    20
#endif
sl@0
    21
sl@0
    22
namespace boost {
sl@0
    23
sl@0
    24
struct xtime;
sl@0
    25
// disable warnings about non dll import
sl@0
    26
// see: http://www.boost.org/more/separate_compilation.html#dlls
sl@0
    27
#ifdef BOOST_MSVC
sl@0
    28
#   pragma warning(push)
sl@0
    29
#   pragma warning(disable: 4251 4231 4660 4275)
sl@0
    30
#endif
sl@0
    31
sl@0
    32
namespace detail {
sl@0
    33
sl@0
    34
class BOOST_THREAD_DECL condition_impl : private noncopyable
sl@0
    35
{
sl@0
    36
    friend class condition;
sl@0
    37
sl@0
    38
public:
sl@0
    39
    condition_impl();
sl@0
    40
    ~condition_impl();
sl@0
    41
sl@0
    42
    void notify_one();
sl@0
    43
    void notify_all();
sl@0
    44
sl@0
    45
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
sl@0
    46
    void enter_wait();
sl@0
    47
    void do_wait();
sl@0
    48
    bool do_timed_wait(const xtime& xt);
sl@0
    49
#elif defined(BOOST_HAS_PTHREADS)
sl@0
    50
    void do_wait(pthread_mutex_t* pmutex);
sl@0
    51
    bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
sl@0
    52
#endif
sl@0
    53
sl@0
    54
#if defined(BOOST_HAS_WINTHREADS)
sl@0
    55
    void* m_gate;
sl@0
    56
    void* m_queue;
sl@0
    57
    void* m_mutex;
sl@0
    58
    unsigned m_gone;  // # threads that timed out and never made it to m_queue
sl@0
    59
    unsigned long m_blocked; // # threads blocked on the condition
sl@0
    60
    unsigned m_waiting; // # threads no longer waiting for the condition but
sl@0
    61
                        // still waiting to be removed from m_queue
sl@0
    62
#elif defined(BOOST_HAS_PTHREADS)
sl@0
    63
    pthread_cond_t m_condition;
sl@0
    64
#elif defined(BOOST_HAS_MPTASKS)
sl@0
    65
    MPSemaphoreID m_gate;
sl@0
    66
    MPSemaphoreID m_queue;
sl@0
    67
    threads::mac::detail::scoped_critical_region m_mutex;
sl@0
    68
    threads::mac::detail::scoped_critical_region m_mutex_mutex;
sl@0
    69
    unsigned m_gone; // # threads that timed out and never made it to m_queue
sl@0
    70
    unsigned long m_blocked; // # threads blocked on the condition
sl@0
    71
    unsigned m_waiting; // # threads no longer waiting for the condition but
sl@0
    72
                        // still waiting to be removed from m_queue
sl@0
    73
#endif
sl@0
    74
};
sl@0
    75
sl@0
    76
} // namespace detail
sl@0
    77
sl@0
    78
class condition : private noncopyable
sl@0
    79
{
sl@0
    80
public:
sl@0
    81
    condition() { }
sl@0
    82
    ~condition() { }
sl@0
    83
sl@0
    84
    void notify_one() { m_impl.notify_one(); }
sl@0
    85
    void notify_all() { m_impl.notify_all(); }
sl@0
    86
sl@0
    87
    template <typename L>
sl@0
    88
    void wait(L& lock)
sl@0
    89
    {
sl@0
    90
        if (!lock)
sl@0
    91
            throw lock_error();
sl@0
    92
sl@0
    93
        do_wait(lock.m_mutex);
sl@0
    94
    }
sl@0
    95
sl@0
    96
    template <typename L, typename Pr>
sl@0
    97
    void wait(L& lock, Pr pred)
sl@0
    98
    {
sl@0
    99
        if (!lock)
sl@0
   100
            throw lock_error();
sl@0
   101
sl@0
   102
        while (!pred())
sl@0
   103
            do_wait(lock.m_mutex);
sl@0
   104
    }
sl@0
   105
sl@0
   106
    template <typename L>
sl@0
   107
    bool timed_wait(L& lock, const xtime& xt)
sl@0
   108
    {
sl@0
   109
        if (!lock)
sl@0
   110
            throw lock_error();
sl@0
   111
sl@0
   112
        return do_timed_wait(lock.m_mutex, xt);
sl@0
   113
    }
sl@0
   114
sl@0
   115
    template <typename L, typename Pr>
sl@0
   116
    bool timed_wait(L& lock, const xtime& xt, Pr pred)
sl@0
   117
    {
sl@0
   118
        if (!lock)
sl@0
   119
            throw lock_error();
sl@0
   120
sl@0
   121
        while (!pred())
sl@0
   122
        {
sl@0
   123
            if (!do_timed_wait(lock.m_mutex, xt))
sl@0
   124
                return false;
sl@0
   125
        }
sl@0
   126
sl@0
   127
        return true;
sl@0
   128
    }
sl@0
   129
sl@0
   130
private:
sl@0
   131
    detail::condition_impl m_impl;
sl@0
   132
sl@0
   133
    template <typename M>
sl@0
   134
    void do_wait(M& mutex)
sl@0
   135
    {
sl@0
   136
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
sl@0
   137
        m_impl.enter_wait();
sl@0
   138
#endif
sl@0
   139
sl@0
   140
        typedef detail::thread::lock_ops<M>
sl@0
   141
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
sl@0
   142
# define lock_ops lock_ops_  // HP confuses lock_ops witht the template
sl@0
   143
#endif
sl@0
   144
            lock_ops;
sl@0
   145
sl@0
   146
        typename lock_ops::lock_state state;
sl@0
   147
        lock_ops::unlock(mutex, state);
sl@0
   148
sl@0
   149
#if defined(BOOST_HAS_PTHREADS)
sl@0
   150
        m_impl.do_wait(state.pmutex);
sl@0
   151
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
sl@0
   152
        m_impl.do_wait();
sl@0
   153
#endif
sl@0
   154
sl@0
   155
        lock_ops::lock(mutex, state);
sl@0
   156
#undef lock_ops
sl@0
   157
    }
sl@0
   158
sl@0
   159
    template <typename M>
sl@0
   160
    bool do_timed_wait(M& mutex, const xtime& xt)
sl@0
   161
    {
sl@0
   162
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
sl@0
   163
        m_impl.enter_wait();
sl@0
   164
#endif
sl@0
   165
sl@0
   166
        typedef detail::thread::lock_ops<M>
sl@0
   167
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
sl@0
   168
# define lock_ops lock_ops_  // HP confuses lock_ops witht the template
sl@0
   169
#endif
sl@0
   170
            lock_ops;
sl@0
   171
sl@0
   172
        typename lock_ops::lock_state state;
sl@0
   173
        lock_ops::unlock(mutex, state);
sl@0
   174
sl@0
   175
        bool ret = false;
sl@0
   176
sl@0
   177
#if defined(BOOST_HAS_PTHREADS)
sl@0
   178
        ret = m_impl.do_timed_wait(xt, state.pmutex);
sl@0
   179
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
sl@0
   180
        ret = m_impl.do_timed_wait(xt);
sl@0
   181
#endif
sl@0
   182
sl@0
   183
        lock_ops::lock(mutex, state);
sl@0
   184
#undef lock_ops
sl@0
   185
sl@0
   186
        return ret;
sl@0
   187
    }
sl@0
   188
};
sl@0
   189
#ifdef BOOST_MSVC
sl@0
   190
#   pragma warning(pop)
sl@0
   191
#endif
sl@0
   192
} // namespace boost
sl@0
   193
sl@0
   194
// Change Log:
sl@0
   195
//    8 Feb 01  WEKEMPF Initial version.
sl@0
   196
//   22 May 01  WEKEMPF Modified to use xtime for time outs.
sl@0
   197
//   23 May 01  WEKEMPF Removed "duration" timed_waits, as they are too
sl@0
   198
//                      difficult to use with spurious wakeups.
sl@0
   199
//    3 Jan 03  WEKEMPF Modified for DLL implementation.
sl@0
   200
sl@0
   201
#endif // BOOST_CONDITION_WEK070601_HPP