After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 744788 - The life cycle of cached resources message is inconsistent with normal messages
The life cycle of cached resources message is inconsistent with normal messages
Status: RESOLVED FIXED
Product: libsoup
Classification: Core
Component: Misc
2.49.x
Other Linux
: Normal normal
: ---
Assigned To: libsoup-maint@gnome.bugs
libsoup-maint@gnome.bugs
Depends on: 731153
Blocks: 745067
 
 
Reported: 2015-02-19 14:11 UTC by Carlos Garcia Campos
Modified: 2015-03-02 08:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
kick the message queue when a cached resource finishes (5.21 KB, patch)
2015-02-19 14:15 UTC, Carlos Garcia Campos
none Details | Review
Do not unqueue messages of cached resources until finished (10.46 KB, patch)
2015-02-19 14:16 UTC, Carlos Garcia Campos
committed Details | Review
kick the message queue when a cached resource finishes (5.07 KB, patch)
2015-03-02 08:28 UTC, Carlos Garcia Campos
committed Details | Review

Description Carlos Garcia Campos 2015-02-19 14:11:43 UTC
There are two problems here:

 1- We are not kicking the queue when marking a cached resource message as FINISHING, so the message is never unqueued unless there's another request that kicks the queue.

 2- We are marking the messages as FINISHING when sending the response, instead of when io has completed, so the message can be unqueued while the client is still reading the stream.
Comment 1 Carlos Garcia Campos 2015-02-19 14:15:44 UTC
Created attachment 297274 [details] [review]
kick the message queue when a cached resource finishes
Comment 2 Carlos Garcia Campos 2015-02-19 14:16:18 UTC
Created attachment 297275 [details] [review]
Do not unqueue messages of cached resources until finished
Comment 3 Dan Winship 2015-02-28 20:09:01 UTC
Comment on attachment 297274 [details] [review]
kick the message queue when a cached resource finishes

>+	session = item->session;
> 	async_send_request_return_result (item, g_object_ref (stream), NULL);
>+	soup_session_kick_queue (session);

Is the separate "session" variable because item might get freed by async_send_request_return_result()? Because if so, then it might also be possible for the session itself to be freed (if the caller unrefs the session from inside the callback), in which case we'd want to take an extra ref on session here.

(It's also possible that that can't happen because it's guaranteed that something else (a GTask or whatever) will always be holding a ref on the session at this point... I'm not sure.)

Other than that possibility, this looks right.
Comment 4 Carlos Garcia Campos 2015-03-02 07:00:43 UTC
(In reply to Dan Winship from comment #3)
> Comment on attachment 297274 [details] [review] [review]
> kick the message queue when a cached resource finishes
> 
> >+	session = item->session;
> > 	async_send_request_return_result (item, g_object_ref (stream), NULL);
> >+	soup_session_kick_queue (session);
> 
> Is the separate "session" variable because item might get freed by
> async_send_request_return_result()?

Yes.

> Because if so, then it might also be
> possible for the session itself to be freed (if the caller unrefs the
> session from inside the callback), in which case we'd want to take an extra
> ref on session here.

Yes, I guess it's harmaless to take a ref and it will be safer.

> (It's also possible that that can't happen because it's guaranteed that
> something else (a GTask or whatever) will always be holding a ref on the
> session at this point... I'm not sure.)

I'll check anyway, if in doubt, I'll take a ref.

> Other than that possibility, this looks right.

Thanks.
Comment 5 Carlos Garcia Campos 2015-03-02 08:25:23 UTC
(In reply to Carlos Garcia Campos from comment #4)
> (In reply to Dan Winship from comment #3)
> > Comment on attachment 297274 [details] [review] [review] [review]
> > kick the message queue when a cached resource finishes
> > 
> > >+	session = item->session;
> > > 	async_send_request_return_result (item, g_object_ref (stream), NULL);
> > >+	soup_session_kick_queue (session);
> > 
> > Is the separate "session" variable because item might get freed by
> > async_send_request_return_result()?
> 
> Yes.
> 
> > Because if so, then it might also be
> > possible for the session itself to be freed (if the caller unrefs the
> > session from inside the callback), in which case we'd want to take an extra
> > ref on session here.
> 
> Yes, I guess it's harmaless to take a ref and it will be safer.
> 
> > (It's also possible that that can't happen because it's guaranteed that
> > something else (a GTask or whatever) will always be holding a ref on the
> > session at this point... I'm not sure.)
> 
> I'll check anyway, if in doubt, I'll take a ref.
> 
> > Other than that possibility, this looks right.
> 
> Thanks.

Ok, this is what happens here. async_return_from_cache() can be called from idle_return_from_cache_cb, scheduled when the resources is FRESH, or from conditional_get_ready_cb, when the conditional request finishes if the resources needs validation. In this case, the conditional request finishes and message_completed callback is called, this kicks the queue, and conditional_get_ready_cb is also called that calls async_return_from_cache. This does the following (for the original message):

1.- sets item state to FINISHING
2.- calls async_send_request_return_result
3.- kicks the queue

When the task is completed in step 2, the async run queue is processed (because of the previous kick_queue in message_completed callback of the conditional request), and since the original message was queued before the conditional one, and the state was switched to FINISHING in state 1, the item is processed and finished. In step 3, the item has already been unqueued. This doesn't happen when async_return_from_cache is called because the resource is FRESH.

So, I think the right solution here is moving the step 1 after 2.
Comment 6 Carlos Garcia Campos 2015-03-02 08:28:50 UTC
Created attachment 298255 [details] [review]
kick the message queue when a cached resource finishes
Comment 7 Carlos Garcia Campos 2015-03-02 08:31:33 UTC
(In reply to Carlos Garcia Campos from comment #6)
> Created attachment 298255 [details] [review] [review]
> kick the message queue when a cached resource finishes

I've just realized that this was changed in the next patch anyway, to avoid finishing the message before the io has completed. But still, it's better to land the right patch just in case we end up reverting the second one for whatever reason at some point.
Comment 8 Carlos Garcia Campos 2015-03-02 08:48:17 UTC
Comment on attachment 298255 [details] [review]
kick the message queue when a cached resource finishes

Pushed.
Comment 9 Carlos Garcia Campos 2015-03-02 08:48:35 UTC
Comment on attachment 297275 [details] [review]
Do not unqueue messages of cached resources until finished

Pushed.