Can Q_GLOBAL_STATIC replace KStaticDelete ?
Matthias Kretz
kretz at kde.org
Thu Jan 18 23:48:02 GMT 2007
On Thursday 18 January 2007 23:45, Thiago Macieira wrote:
> Matthias Kretz wrote:
> >The problem is that if thread 1 inits this_##NAME and then executes the
> > code in the macro (creating a new object and returning it) while thread
> > 2 does the same, the internal flag that the local static has been
> > initialized might still be unset so that thread 2 creates a second
> > QGlobalStatic object which tells the macro that the object has not been
> > created yet.
>
> That's what I said :-)
I think we're misunderstanding each other right now. Let's try and pin down
the misunderstanding...
You're saying that Q_GLOBAL_STATIC is threadsafe because of
QBasicAtomicPointer, which makes the assignment of the object pointer atomic.
And I understood that you were saying that Q_GLOBAL_STATIC does not need
threadsafe local statics, right?
I said that Q_GLOBAL_STATIC is not threadsafe if initialization of local
statics is not atomic. Because if two QGlobalStatic objects are created (one
in each thread, a really rare race condition, but it can happen as my
testcase shows) QBasicAtomicPointer can't help anymore.
> And that's where QBasicAtomicPointer comes in (not QAtomicPointer because
> that isn't POD). It allows us to atomically set the pointer without the
> need for a guard variable.
How about using the code below for doing what Q_GLOBAL_STATIC is supposed to
do (it could use a little more logic to return 0 after destruction, but
that's not necessary here). The idea is to use QBasicAtomicPointer to guard
against concurrent initialization of the local static:
--
________________________________________________________
Matthias Kretz (Germany) <><
http://Vir.homelinux.org/
MatthiasKretz at gmx.net, kretz at kde.org,
Matthias.Kretz at urz.uni-heidelberg.de
-------------- next part --------------
template<typename T>
class KCleanUpGlobalStatic
{
public:
T *pointer;
inline ~KCleanUpGlobalStatic()
{
delete pointer;
pointer = 0;
}
};
#define K_GLOBAL_STATIC(TYPE, NAME) \
static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_ATOMIC_INIT(0); \
TYPE *NAME() \
{ \
if (!_k_static_##NAME) { \
TYPE *x = new TYPE; \
if (!_k_static_##NAME.testAndSet(0, x)) { \
delete x; \
} else { \
static KCleanUpGlobalStatic<A> cleanUpObject = { _k_static_##NAME }; \
} \
} \
return _k_static_##NAME; \
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20070119/1bdbd834/attachment.sig>
More information about the kde-core-devel
mailing list