Boost logo

Boost Users :

From: Dragan Milenkovic (tyrant_at_[hidden])
Date: 2003-10-16 01:20:10


>
>
>Date: Tue, 14 Oct 2003 16:02:25 +0300
>From: "Peter Dimov" <pdimov_at_[hidden]>
>To: "Boost Users mailing list" <boost-users_at_[hidden]>
>Subject: Re: [Boost-users] shared_from_this
>
>Dragan Milenkovic wrote:
>
>
>>Hello, people,
>>
>>I've been using enable_shared_from_this a LOT, mostly for implementing
>>the Observer pattern (an object holds a list of weak pointers to it's
>>observers).
>>
>>
[snip]

>>Also, any comments on the designs I used? Better observers?
>>
>>
>
>It is hard to say; you'll need to go into more detail about the observers.
>If they are only notified on destruction of the observed entity, the typical
>shared_ptr approach is to reverse/eliminate the dependency and make the
>observers store weak pointers to the "observee".
>
>For other notification scenarios, there is the usual tradeoff between
>polling and messaging. I prefer polling most of the time since this
>eliminates the need to store an observer list and makes it possible to
>"observe" classes that weren't specifically designed for this, but there may
>be a performance cost.
>
>
Well this (new) question is about observers in general, concurrent
programming and C++.
I believe to be making my way up the learning curve, but this seems to
be a bit of problem.

The proper destruction... Here is what I've been thinking.
First the destruction of the subject (observee). As proposed in "Design
Patterns",
the subject could notify the observers about being destroyed, so the
observers can handle
that situation. But in my (more or less limited) experience, most often
the observer is the
one that controls the life-time of the subject (possibly by the means of
shared_ptr).
So this really presents no problem...

But how to synchronize the destruction of the observer with a nofication
originating from
another thread? The observer's destructor would most likely perform
Subject::unregister...
But a call to Observer::update might have already been dispatched...
The possible solutions I can think of are:

1. Make Subject::unregister have a postcodition stating that the
observer will receive
notifications no more (as of the moment the function returns). The words
that come
into my mind while thinking of possible implementations are: mutex,
condition,
dead-lock, inconsistency... What should the observer be allowed to do
from inside
the update function? Inspect only? I guess that could work...

2. Subject holds weak_ptr<Observer> and removes dead observers. I like
it because
of simplicity, but it (possibly) requires that Observer inherits
enable_shared_from_this.
In my design, the subject usualy passes a pointer to itself in the
Observer::update method...
Better yet - a shared_ptr, as it is more clean to compare shared
pointer, especially inside
the container. And how does it get shared_ptr to itself?
shared_from_this() again.
Is it really necessary? Although it does make the code easier to maintain.

I might be wrong, but I get the impression that there is not much
information on
multithreading and destruction in C++. Destruction the way it is, makes
C++ my language
of preference. The lectures usually starts with a queue or a buffer with
one mutex and one (or two)
conditional variables, but it doesn't get any better. How is the queue
destroyed? What about
consumer which is waiting on a conditional variable?
What is the common way of dealing with all this? Java-like interrupt?
That's basically what I've
been doing.

Many thanks,
Dragan Milenkovic


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