|
Boost Users : |
From: todd (todd_at_[hidden])
Date: 2004-02-08 01:10:20
On Sun, 08 Feb 2004 09:59:21 +0000, Steve Folly wrote
> Ah - so since my object will always be holding a referece, and I can
> provide my intrusive_ptr_release function to release when the ref
> count is 1? Is that what you meant?
Most implementations delete when the count falls to 0.
> And all my helper functions will be based on an intrusive pointer, rather
> than the shared pointer?
Yes
> I've noticed that the shared_ptr mechanism is thread safe, but the intrusive
> pointer isn't. I don't think that will be a problem because we
> enforce a policy of only accessing them from one thread anyway.
Why do you say that? Here's a simplified example (it lacks some border cases
that most people don't need):
============
class ref_counted: boost::noncopyable
{
public:
ref_counted():
num_refs(0)
{
}
virtual ~ref_counted()
{
}
long mutable volatile num_refs;
};
inline void intrusive_ptr_add_ref(const ref_counted* p)
{
thread_safe_increment(p->num_refs);
}
inline void intrusive_ptr_release(const ref_counted* p)
{
if(!thread_safe_decrement(p->num_refs))
delete p;
}
============
Here's how to use it:
class my_class: public ref_counted
{
// ...
};
intrusive_ptr<my_class> p = new my_class;
You'll have to write the thread_safe_* functions for each OS you use. For
Win32 (MSVC):
extern "C"
{
long __cdecl _InterlockedIncrement(long volatile *);
long __cdecl _InterlockedDecrement(long volatile *);
}
#pragma intrinsic (_InterlockedIncrement, _InterlockedDecrement)
inline long thread_safe_increment(long volatile& i)
{
return _InterlockedIncrement(&i);
}
inline long thread_safe_decrement(long volatile& i)
{
return _InterlockedDecrement(&i);
}
The intrinsic interlocked functions are so fast (only 3 instructions ea.) that
I don't bother using a non-thread-safe version for single-threaded apps.
Todd
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net