source: NonGTP/Boost/boost/detail/sp_counted_base_pt.hpp @ 857

Revision 857, 3.0 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
2#define BOOST_DETAIL_SP_COUNTED_BASE_PT_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_pt.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#include <typeinfo>
22#include <pthread.h>
23
24namespace boost
25{
26
27namespace detail
28{
29
30class sp_counted_base
31{
32private:
33
34    sp_counted_base( sp_counted_base const & );
35    sp_counted_base & operator= ( sp_counted_base const & );
36
37    long use_count_;        // #shared
38    long weak_count_;       // #weak + (#shared != 0)
39
40    mutable pthread_mutex_t m_;
41
42public:
43
44    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
45    {
46// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
47
48#if defined(__hpux) && defined(_DECTHREADS_)
49        pthread_mutex_init( &m_, pthread_mutexattr_default );
50#else
51        pthread_mutex_init( &m_, 0 );
52#endif
53    }
54
55    virtual ~sp_counted_base() // nothrow
56    {
57        pthread_mutex_destroy( &m_ );
58    }
59
60    // dispose() is called when use_count_ drops to zero, to release
61    // the resources managed by *this.
62
63    virtual void dispose() = 0; // nothrow
64
65    // destroy() is called when weak_count_ drops to zero.
66
67    virtual void destroy() // nothrow
68    {
69        delete this;
70    }
71
72    virtual void * get_deleter( std::type_info const & ti ) = 0;
73
74    void add_ref_copy()
75    {
76        pthread_mutex_lock( &m_ );
77        ++use_count_;
78        pthread_mutex_unlock( &m_ );
79    }
80
81    bool add_ref_lock() // true on success
82    {
83        pthread_mutex_lock( &m_ );
84        bool r = use_count_ == 0? false: ( ++use_count_, true );
85        pthread_mutex_unlock( &m_ );
86        return r;
87    }
88
89    void release() // nothrow
90    {
91        pthread_mutex_lock( &m_ );
92        long new_use_count = --use_count_;
93        pthread_mutex_unlock( &m_ );
94
95        if( new_use_count == 0 )
96        {
97            dispose();
98            weak_release();
99        }
100    }
101
102    void weak_add_ref() // nothrow
103    {
104        pthread_mutex_lock( &m_ );
105        ++weak_count_;
106        pthread_mutex_unlock( &m_ );
107    }
108
109    void weak_release() // nothrow
110    {
111        pthread_mutex_lock( &m_ );
112        long new_weak_count = --weak_count_;
113        pthread_mutex_unlock( &m_ );
114
115        if( new_weak_count == 0 )
116        {
117            destroy();
118        }
119    }
120
121    long use_count() const // nothrow
122    {
123        pthread_mutex_lock( &m_ );
124        long r = use_count_;
125        pthread_mutex_unlock( &m_ );
126
127        return r;
128    }
129};
130
131} // namespace detail
132
133} // namespace boost
134
135#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.