implementing IN_PROGRESS
Havoc Pennington
hp at redhat.com
Sat Feb 25 13:34:55 PST 2006
On Sat, 2006-02-25 at 21:40 +0100, Thiago Macieira wrote:
> * no modification to the dispatch lock
> * when calling to user (binding) code, the binding has the option to
> return HANDLED, NOT_HANDLED and (new one) PARTIALLY_HANDLED.
> * when receiving a PARTIALLY_HANDLED return code, the code would pop
> the
> message from the queue just as if it had been fully handled and place
> it
> in a new queue, allocated on the stack, local to the function.
> * after all other locks have been released, call the binding again for
> all
> the PARTIALLY_HANDLED messages. There is no return code: the binding
> MUST
> handle it fully.
But the dispatch lock won't be released while the partially handled
messages are on the stack - it can only be released when the current
call stack unwinds all the way back to the app handler. What am I
missing?
Here's the "normal case":
BindingMainLoopIterate
calls dbus_connection_dispatch (TAKES DISPATCH LOCK)
calls binding code to handle a message
calls application code associated with the message
(DROPS DISPATCH LOCK)
BindingMainLoopIterate
... repeats
Here's the bug:
BindingMainLoopIterate
calls dbus_connection_dispatch (TAKES DISPATCH LOCK)
calls binding code to handle a message
calls application code associated with the message
calls BindingMainLoopIterate [1]
calls dbus_connection_dispatch (DEADLOCKS ON DISPATCH LOCK)
I understand you to be saying:
BindingMainLoopIterate
calls dbus_connection_dispatch (TAKES DISPATCH LOCK)
calls binding code to handle a message (SAVES A RECURSION FLAG)
calls application code associated with the message
calls BindingMainLoopIterate [1]
calls dbus_connection_dispatch or similar
calls binding to handle a message
returns PARTIALLY_HANDLED since recursion flag set
waits for dispatch lock to be dropped [2]
calls binding to handle PARTIALLY_HANDLED messages
My proposal is:
BindingMainLoopIterate
calls dbus_connection_dispatch (TAKES DISPATCH LOCK)
calls binding code to handle a message
calls application code associated with the message
calls BindingMainLoopIterate [1]
calls dbus_connection_dispatch or similar
if dispatch lock held by another thread:
(not possible with this call stack,
since we hold it in this thread)
else:
return IN_PROGRESS or COMPLETED, do nothing
(DROPS DISPATCH LOCK)
BindingMainLoopIterate
... this would look like the "normal case" above
[1]
the "calls BindingMainLoopIterate" could also be a direct call to any of
the DBusConnection methods that take the dispatch lock and it would
deadlock with today's libdbus.
This is probably the answer to my question in my last mail about why
block_pending_call() doesn't take the dispatch lock - it would deadlock
in this case. I guess maybe we could say the dispatch lock doesn't cover
the whole message queue, only the "current" message, but I still suspect
the locking is a bit off.
[2]
this is where I don't understand your proposal - I don't think the
dispatch lock is ever dropped.
Havoc
More information about the dbus
mailing list