Boost logo

Boost Users :

Subject: Re: [Boost-users] Am I doing something wrong here? Boost threads & intrusive_ptr crash
From: Nigel Rantor (wiggly_at_[hidden])
Date: 2009-06-11 10:37:52


Space Ship Traveller wrote:
> Hi,
[snip]
> Here is the function which is used to post a notification. REF(t) is
> simply a macro for boost::intrusive_ptr<t>.

Can you confirm which of the following REF(INotificationSource) maps to?

boost::intrusive_ptr<INotificationSource> note

or

boost::intrusive_ptr<INotificationSource>& note

More concretely, is the parameter:

1 - a reference to an already existing intrusive_ptr

2 - a new intrusive_ptr using a copy constructor

3 - a new intrusive_ptr accepting a raw pointer

If it is the third one then there is nothing to stop some particular
interleaving of instructions decrementing the ref count to zero between
your check and the construction of the parameter.

Whether or not this causes an obvious error when you attempt to create a
new intrusive_ptr from it will depend a lot of things.

For example, I have a test I just made and I can get this to fail hard
and to simply create a new intrusive_ptr from an invalid pointer,
depending on what I do....

> void Loop::postNotification (REF(INotificationSource) note, bool urgent)
> {
> using namespace boost;
> typedef boost::mutex::scoped_lock scoped_lock;
>
>
> // Lock the event loop notification queue
> // Add note to the end of the queue
> // Interrupt event loop thread if urgent
>
>
> // We should probably lock around m_currentThread, it might not be set
> before we read it..?
> if (this_thread::get_id() == m_currentThread) {
> note->processEvents(this, NOTIFICATION);
> } else {
> {
> // Enqueue the notification to be processed
> scoped_lock lock(m_notifications.lock);
> m_notifications.sources->push(note); (*)
> }
>
>
> if (urgent) {
> // Interrupt event loop thread so that it processes notifications more
> quickly
> m_urgentNotificationPipe->notifyEventLoop();
> }
> }
> }
>
> I'm experiencing a very infrequent crash at the line marked with (*).
> The note is a reference counted pointer (boost::intrusive_ptr), but by
> the time we get here, this pointer is invalid, even though there are
> still references to it in the system. The odd thing is, further up the
> chain (and on the same thread), I'm checking to ensure that note is
> valid, i.e.
>
> //... display update system, separate thread from event-loop.
> ensure(ctx->notificationSource);
> loop->postNotification(ctx->notificationSource);
> //...
>
> After writing this far in the email, I'm starting to see something where
> there could be an error. Is it possible that the object reference count
> is being messed up due to multi-threading issues? I.e. if the object is
> being passed around on two separate threads, having the reference count
> incremented and decremented at the same time? Actually, it seems obvious
> that this could be a problem...
>
> Are there any "patterns" for using reference counted objects across
> different threads?
>
> Any feedback is appreciated.
>
> Kind regards,
> Samuel
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


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