diff options
author | Alberto Mardegan <alberto.mardegan@nokia.com> | 2009-01-30 13:48:25 +0200 |
---|---|---|
committer | Alberto Mardegan <alberto.mardegan@nokia.com> | 2009-01-30 13:48:25 +0200 |
commit | 3f50128353ac7cd9e5a5b05b110745aaed1518b8 (patch) | |
tree | b43d582f8059934c4626bcec8a80082ecd5f377d | |
parent | fd0b4687e6528050cb56ae419e3473c4e01d7193 (diff) |
Dispatch requested channels waiting for approval
If an incoming channel is waiting for approval and a client requests the same
channel (via EnsureChannel), then the DispatchOperation must finish
immediately.
This patch makes it so that if the channel is found in a dispatch context and
is waiting for approval, HandleWith() is called on the dispatch operation, so
the channel handler will eventually be invoked.
-rw-r--r-- | src/mcd-dispatcher.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c index ed81a315..b99f7538 100644 --- a/src/mcd-dispatcher.c +++ b/src/mcd-dispatcher.c @@ -3090,14 +3090,33 @@ _mcd_dispatcher_reinvoke_handler (McdDispatcher *dispatcher, /* the context will be unreferenced once it leaves the state machine */ } +static McdDispatcherContext * +find_context_from_channel (McdDispatcher *dispatcher, McdChannel *channel) +{ + GList *list; + + g_return_val_if_fail (MCD_IS_CHANNEL (channel), NULL); + for (list = dispatcher->priv->contexts; list != NULL; list = list->next) + { + McdDispatcherContext *context = list->data; + + if (g_list_find (context->channels, channel)) + return context; + } + return NULL; +} + void _mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher, McdChannel *channel, McdChannel *request) { + McdChannelStatus status; + + status = mcd_channel_get_status (channel); + /* if the channel is already dispatched, just reinvoke the handler; if it * is not, @request must mirror the status of @channel */ - if (mcd_channel_get_status (channel) == - MCD_CHANNEL_STATUS_DISPATCHED) + if (status == MCD_CHANNEL_STATUS_DISPATCHED) { g_debug ("reinvoking handler on channel %p", channel); @@ -3114,6 +3133,22 @@ _mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher, } else { + if (status == MCD_CHANNEL_STATUS_DISPATCHING) + { + McdDispatcherContext *context; + + context = find_context_from_channel (dispatcher, channel); + g_debug ("channel %p is in context %p", channel, context); + if (context->approvers_invoked > 0) + { + /* the existing channel is waiting for approval; but since the + * same channel has been requested, the approval operation must + * terminate */ + if (G_LIKELY (context->operation)) + mcd_dispatch_operation_handle_with (context->operation, + NULL, NULL); + } + } g_debug ("channel %p is proxying %p", request, channel); _mcd_channel_set_request_proxy (request, channel); } |