Signals & threads - low level C API [Newbie question]

Krishna R sith.list at gmail.com
Fri Jan 26 20:59:48 PST 2007


Hmm looks like this may not be it. It works great except that the filter
func is never called to rcv the *first* message sent.

Subsequent sends are rcvd fine. I see that the select gets unblocked when
the first time data comes in and read_write_dispatch gets called. But in
turn never calls the filterfunc! Why? Doing verbose output i see for the
first time i send message, it does a iteration_unlocked and never calls
connection_dispatch. All subsequent sends call connectio_dispatch which in
turn calls the filter func.

dbus_read_write_dispatch() code snippet...

if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
    {
      dbus_connection_dispatch (connection);
    }
... else
    {
     ...   _dbus_connection_do_iteration_unlocked (connection,

So why is the dstatus != DATA_REMAINS the first time and works all other
times is the question i couldnt answer myself.

Thanks,
-K

On 1/26/07, Krishna R <sith.list at gmail.com> wrote:
>
> Thanks that makes sense. The select method blocking on the readset of the
> sockets for rcving thread works fine. The documentation says DO NOT use
> get_socket and use DBUSWatch, but i guess  i am ok since this is a simple
> app and only this thread is recving data and there is no main loop etc?
>
> This what i had to do...if there are other newbies trying the same
> thing...
>
>     // Get the socket descriptor of dbus connection of this process
>     if (!dbus_connection_get_socket(pConnection,&socketfd)) {
>
>         return NULL;
>     }
>
>     FD_ZERO(&readSet);
>     FD_SET(socketfd, &readSet);
>
>     while(1)
>     {
>         retVal = select(socketfd+1, &readSet, NULL, NULL, NULL); // block
>
>         if (-1 == retVal) // The socket might no loger be available
>         {
>             if (!dbus_connection_read_write_dispatch (pConnection, 0))
>             {
>                 // If this returns FALSE, the connection is disconnected
>                 // and we dont want to spin in this loop forever
>                 return NULL; // exit from thread
>
>             }
>
>         }
>         else if (FD_ISSET(socketfd, &readSet))
>         {
>             dbus_connection_read_write_dispatch (pConnection, 0);
>         }
>     }
>
> Thanks for your help again.
> --K
>
> On 1/26/07, Havoc Pennington < hp at redhat.com> wrote:
> >
> > Krishna R wrote:
> > > Do i still need the main loop you are talking about in the above
> > simple
> > > scenario?
> > >
> >
> > The problem is that there's a lock on the socket. When
> > read_write_dispatch() blocks, it will hold this lock. That means
> > dbus_connection_flush() can't acquire it in order to flush.
> >
> > You can imagine various libdbus fixes to make it smarter about this
> > situation, but if you don't want to hack on libdbus you probably have to
> >   only call read_write_dispatch() when you know it won't block, which is
> >
> > normally done with a main loop as Thiago suggests. As a hack you could
> > also just call dbus_connection_get_socket() and poll()/select() on it
> > manually in a simple loop.
> >
> > An even worse hack would be to try and wake up the poll by creating an
> > EINTR (raise some bogus signal), but I don't know if that will work and
> > it probably isn't that portable across unix flavors if it does.
> >
> > Another bad hack would be to put a short timeout on the
> > read_write_dispatch so it never blocks too long.
> >
> > Havoc
> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freedesktop.org/archives/dbus/attachments/20070126/9974f472/attachment.html


More information about the dbus mailing list