[haiku-3rdparty-dev] Re: port problems

  • From: Sean Healy <jalopeura@xxxxxxxxxxx>
  • To: "haiku-3rdparty-dev@xxxxxxxxxxxxx" <haiku-3rdparty-dev@xxxxxxxxxxxxx>
  • Date: Thu, 2 Jun 2016 19:57:12 -0700

Has anyone ever run into BLooper hanging during port_buffer_size_etc(), even though there are messages in the port queue?

Okay, I figured it out. I am storing objects as void* to pass them around. At one point in the code, when I cast the void* back into my looper subclass, I had accidentally cast it back into my handler subclass instead.

My handler subclass adds a pointer member to BHandler; BLooper also adds members to BHandler, the first of which is also a pointer: fDirectTarget. My looper subclass adds an identically named member field to BLooper. So even though I thought I was writing to the MyLooper version of the member field, the compiler was actually writing to the MyHandler version, and thus overwriting the looper's fDirectTarget.

Only the looper's copy of the pointer was overwritten, and since messages are ultimately posted using not the looper's copy, but rather a copy acquired from the token space (a copy which was of course still valid), PostMessage() did not report an error.

In the process of adding a message to the (valid) direct target, a 0-byte message would be written to the port; when the looper thread took over, the looper would wake up and run through a cycle of its loop. It would use the overwritten fDirectTarget and therefore get a NULL message, and then end up blocking on port_buffer_size_etc until the whole thing happened all over again.

So when I called port_count(), there were still messages in the queue. But by the time I attached the hanging team to the debugger and saw that the looper was blocked on port_buffer_size_etc(), the looper had already processed all the those 0-byte messages - but it never found any BMessages in its message queue, because that direct target pointer was invalid.

Other related posts: