[haiku-development] Re: invalid BMessengers

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Thu, 07 Aug 2008 00:49:56 +0200

On 2008-08-06 at 20:59:08 [+0200], Stephan Assmus <superstippi@xxxxxx> wrote:
[...]
> The problem I am seeing in the above code is:
> 
>             if (looper) {
>                 if (handler->Looper() != looper)
>                     error = B_MISMATCHED_VALUES;
>             } else {
>                 ...
> 
> This check means the handler pointer needs to be valid, but I think this is
> unintentional. Do you think we could simply remove this check? If the
> BHandler does not belong to the BLooper, the error should be detected
> later, no?

The next check is when a message sent with this messenger arrives at the 
looper. I find this a little late.

> If one would want to check whether or not the BHandler belongs
> to the specified looper, without accessing the BHandler object because it
> may be stale, one would have to see if the handler is in the looper's
> handler list. If I am not missing something, this would require to lock the
> looper, which can not be done in the BMessenger constructor, or can it? At
> least not while holding the gLooperList lock. The gLooperList lock alone
> also can't be enough for this, since although the looper can't go away,
> someone else may still be messing with it (like, adding/removing BHandlers).

Locking the looper instead of locking the looper list would allow to verify 
that the handler belongs to the looper without dereferencing it, but I 
believe this is not desirable as it can lead to deadlocks. An alternative 
method to verify the validity of the handler object would be to iterate 
through the token space, but this is not really supported yet and wouldn't be 
particularly fast.

To sum it up, I don't think allowing to pass invalid BHandler object pointers 
around is anything we need or should support.

If for some reason you need to wait with constructing a BMessenger from a 
BHandler whose life time you don't control, you could instead store its 
token. You can convert it cheaply at any time using the token space (cf. 
headers/private/app/TokenSpace.h). While you hold the token space lock, the 
object associated with the token won't go away. The BMessenger::Private class 
allows you to construct a BMessenger from looper port and handler token.

Obviously using those private classes is acceptable only in Haiku code itself.

CU, Ingo

Other related posts: