-
Notifications
You must be signed in to change notification settings - Fork 282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve NSFileManager thread safety #306
Conversation
I have been thinking about this. Both of the proposed long term solutions have problems: So, what do you think of changing the code to keep error information in a thread-local variable rather than as an instance variable? I think that would allow us to have instances (including the shared instance) be thread safe like the current apple implementation, avoiding either changing the methods to pass extra information or having lots of temporary instances created. |
Ah yes, great idea. Should I just replace the |
I guess using |
GSCurrentThreadDictionary() is much less efficient, but more reliable for cleanup because the dictionary and its contents will reliably be destroyed at thread end. |
ccef81f
to
9cf2647
Compare
9cf2647
to
f62ecfa
Compare
Thanks. I ended up using the TLS macros because it didn’t seem too involved to make that work. The only slightly tricky part is support for ARC, as the current RETAIN/RELEASE() etc. macros don’t work for this case, but I think I got it working too. If you see any issues with this approach I can also switch out the getter/setter to use GSCurrentThreadDictionary(). |
Actually, after sleeping on it, I think you made the right choice. The automatic cleanup at the end of the thread does not ensure cleanup at the end of the lifetime of an NSFileManager instance, and we'd probably want to do that anyway. So the simpler and more efficient macros seem good. |
Great. Is this good to merge then or did you still want to review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good to me. Thanks.
This is a shallow fix for possible crashes when concurrently calling various APIs which internally use
+[NSFileManager defaultManager]
, such as-[NSData writeToFile:options:error:]
.Guards access to the
_lastError
instance variable with a lock, so that concurrent invocations of NSFileManager methods modifying the variable will not e.g. cause over-release of objects.This is mainly meant to fix crashes when no error occurs. Note however that the actual error handling is not made thread safe with this fix, i.e. if an error occurs while another method is concurrently using the file manager APIs there can still be crashes and incorrect control flow. I see two ways to fix this properly:
_lastError
instance variable with local error variables that are passed through the method calls.defaultManager
with individual NSFileManager objects in the various APIs using NSFileManager.Both of these seem somewhat involved, so I wanted to get this shallow fix in first. If preferred I’m happy to keep the patch locally for now.