~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to include/builtin-boost/boost/detail/sp_counted_base_w32.hpp

Tags: upstream-0.15.3+svn20934
ImportĀ upstreamĀ versionĀ 0.15.3+svn20934

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 
2
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 
3
 
 
4
// MS compatible compilers support #pragma once
 
5
 
 
6
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 
7
# pragma once
 
8
#endif
 
9
 
 
10
//
 
11
//  detail/sp_counted_base_w32.hpp
 
12
//
 
13
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 
14
//  Copyright 2004-2005 Peter Dimov
 
15
//
 
16
//  Distributed under the Boost Software License, Version 1.0. (See
 
17
//  accompanying file LICENSE_1_0.txt or copy at
 
18
//  http://www.boost.org/LICENSE_1_0.txt)
 
19
//
 
20
//
 
21
//  Lock-free algorithm by Alexander Terekhov
 
22
//
 
23
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 
24
//  formulation
 
25
//
 
26
 
 
27
#include <boost/detail/interlocked.hpp>
 
28
#include <boost/detail/workaround.hpp>
 
29
#include <boost/detail/sp_typeinfo.hpp>
 
30
 
 
31
namespace boost
 
32
{
 
33
 
 
34
namespace detail
 
35
{
 
36
 
 
37
class sp_counted_base
 
38
{
 
39
private:
 
40
 
 
41
    sp_counted_base( sp_counted_base const & );
 
42
    sp_counted_base & operator= ( sp_counted_base const & );
 
43
 
 
44
    long use_count_;        // #shared
 
45
    long weak_count_;       // #weak + (#shared != 0)
 
46
 
 
47
public:
 
48
 
 
49
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 
50
    {
 
51
    }
 
52
 
 
53
    virtual ~sp_counted_base() // nothrow
 
54
    {
 
55
    }
 
56
 
 
57
    // dispose() is called when use_count_ drops to zero, to release
 
58
    // the resources managed by *this.
 
59
 
 
60
    virtual void dispose() = 0; // nothrow
 
61
 
 
62
    // destroy() is called when weak_count_ drops to zero.
 
63
 
 
64
    virtual void destroy() // nothrow
 
65
    {
 
66
        delete this;
 
67
    }
 
68
 
 
69
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 
70
 
 
71
    void add_ref_copy()
 
72
    {
 
73
        BOOST_INTERLOCKED_INCREMENT( &use_count_ );
 
74
    }
 
75
 
 
76
    bool add_ref_lock() // true on success
 
77
    {
 
78
        for( ;; )
 
79
        {
 
80
            long tmp = static_cast< long const volatile& >( use_count_ );
 
81
            if( tmp == 0 ) return false;
 
82
 
 
83
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
 
84
 
 
85
            // work around a code generation bug
 
86
 
 
87
            long tmp2 = tmp + 1;
 
88
            if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
 
89
 
 
90
#else
 
91
 
 
92
            if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
 
93
 
 
94
#endif
 
95
        }
 
96
    }
 
97
 
 
98
    void release() // nothrow
 
99
    {
 
100
        if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
 
101
        {
 
102
            dispose();
 
103
            weak_release();
 
104
        }
 
105
    }
 
106
 
 
107
    void weak_add_ref() // nothrow
 
108
    {
 
109
        BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
 
110
    }
 
111
 
 
112
    void weak_release() // nothrow
 
113
    {
 
114
        if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
 
115
        {
 
116
            destroy();
 
117
        }
 
118
    }
 
119
 
 
120
    long use_count() const // nothrow
 
121
    {
 
122
        return static_cast<long const volatile &>( use_count_ );
 
123
    }
 
124
};
 
125
 
 
126
} // namespace detail
 
127
 
 
128
} // namespace boost
 
129
 
 
130
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED