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 719455 - g_file_make_directory_with_parents() can erroneously throw G_IO_ERROR_EXISTS
g_file_make_directory_with_parents() can erroneously throw G_IO_ERROR_EXISTS
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
unspecified
Other Linux
: Normal minor
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2013-11-28 00:37 UTC by Philip Chimento
Modified: 2014-12-19 06:35 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Illustration of the problem (539 bytes, text/x-python-script)
2013-11-28 00:37 UTC, Philip Chimento
  Details
Patch that fixes the problem (1.40 KB, patch)
2013-11-28 01:51 UTC, Philip Chimento
none Details | Review
Updated patch (1.40 KB, patch)
2013-12-04 03:04 UTC, Philip Chimento
committed Details | Review
Apply code review comment to surrounding code as well (1.60 KB, patch)
2013-12-04 03:06 UTC, Philip Chimento
committed Details | Review
Here's a separate patch that explains the flow of my_error. (3.04 KB, patch)
2014-12-02 17:40 UTC, Philip Chimento
committed Details | Review

Description Philip Chimento 2013-11-28 00:37:03 UTC
Created attachment 262986 [details]
Illustration of the problem

If two processes are calling g_file_make_directory_with_parents() on two different directories that have a common ancestor directory that does not exist yet, then one of the calls sometimes fails with G_IO_ERROR_EXISTS (from the race to create the common ancestor) even though the directory specified by the GFile has not been created.

That's convoluted but the attached Python script should illustrate it. Basically it's a violation of the invariant of "G_IO_ERROR_EXISTS means g_file_make_directory_with_parents() was not necessary because all the necessary directories already existed."
Comment 1 Philip Chimento 2013-11-28 01:51:33 UTC
Created attachment 262990 [details] [review]
Patch that fixes the problem

Here's a patch.
Comment 2 Christian Persch 2013-11-28 10:22:02 UTC
+      if (my_error != NULL && my_error->code == G_IO_ERROR_EXISTS)

You also need to check the error domain. Use |if (g_error_matches(...))|.
Comment 3 Christian Persch 2013-11-28 10:26:58 UTC
+      if (my_error != NULL && my_error->code == G_IO_ERROR_EXISTS)

You also need to check the error domain. Use |if (g_error_matches(...))|.
Comment 4 Philip Chimento 2013-12-04 03:04:57 UTC
Created attachment 263478 [details] [review]
Updated patch
Comment 5 Philip Chimento 2013-12-04 03:06:18 UTC
Created attachment 263479 [details] [review]
Apply code review comment to surrounding code as well

This patch also applies the comment about using g_error_matches() to the rest of the surrounding code in that function.
Comment 6 Philip Chimento 2014-12-02 15:16:16 UTC
Ping?
Comment 7 Allison Karlitskaya (desrt) 2014-12-02 16:01:38 UTC
Review of attachment 263479 [details] [review]:

This is a nice clean up.  Thanks.
Comment 8 Allison Karlitskaya (desrt) 2014-12-02 16:06:03 UTC
Review of attachment 263478 [details] [review]:

The handling of 'my_error' in this function is extremely confusing (particularly with respect to how it is allowed to 'leak' out of this loop, past the for loop, all the way to the end), but I believe this patch to be correct...

If you're up for it, we could use another patch adding some comments about what's going on there (or you could roll it into this one if you prefer).
Comment 9 Philip Chimento 2014-12-02 17:05:43 UTC
Sure, I'd be happy to add some clarifying comments to this patch. Thanks very much for the review.
Comment 10 Philip Chimento 2014-12-02 17:40:14 UTC
Created attachment 292011 [details] [review]
Here's a separate patch that explains the flow of my_error.

---

gfile: Explain nonobvious use of my_error

In g_file_make_directory_with_parents(), the my_error variable is used
for several different purposes throughout the whole function, not all of
which are obvious. This explains the situation with some comments.
Comment 11 Allison Karlitskaya (desrt) 2014-12-18 07:27:16 UTC
I've committed all three patches, with some minor style changes to the
comments.

Thanks for the help!
Comment 12 Philip Chimento 2014-12-19 06:35:56 UTC
Awesome, thank you!