Duplicate file handles created by FSEventStreamCreate
Originator: | therzok | ||
Number: | rdar://7359453 | Date Originated: | Oct 8, 2019 at 7:51 PM |
Status: | Open | Resolved: | |
Product: | macOS | Product Version: | 10.14.4 |
Classification: | Reproducible: | Yes |
Basic Information Please provide a descriptive title for your feedback: Duplicate file handles created by FSEventStreamCreate Which area are you seeing an issue with? Core Foundation API What type of issue are you reporting? Incorrect/Unexpected Behavior Description Please describe the issue and what steps we can take to reproduce it: I couldn't find Core Services as a category, so I guessed the best place to put it was under Core Foundation. There is a hard limit (by default) for macOS apps for 256 file handles per process. But this limit can easily be reached via FSEventStreamCreate, as it duplicates handles for every directory segment under the path we're watching. Given an application that has to deal with user environments, having event streams created for a few deeply nested directories can easily exhaust the number of handles an app can possibly create, leading to undefined behaviour on the application from then on. The initial assumption was that migrating from multiple FSEventStreams with one root path - to one FSEventStream with multiple root paths would deduplicate the file handles being used. It seems to not be the case. A sample source file attached below can reproduce this issue, where watching something in the lines of: ``` ~/Documents ~/Documents ~/Applications ``` Creates this set of file handles: ``` fw 8417 therzok 4r DIR 1,4 4544 625235 /Users/therzok/Documents fw 8417 therzok 5r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 6r DIR 1,4 192 170037 /Users fw 8417 therzok 7r DIR 1,4 4544 625235 /Users/therzok/Documents fw 8417 therzok 8r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 9r DIR 1,4 192 170037 /Users fw 8417 therzok 10r DIR 1,4 384 1138601 /Users/therzok/Applications fw 8417 therzok 11r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 12r DIR 1,4 192 170037 /Users ``` The expected set of handles should be something like: ``` fw 8417 therzok 4r DIR 1,4 4544 625235 /Users/therzok/Documents fw 8417 therzok 5r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 6r DIR 1,4 192 170037 /Users fw 8417 therzok 7r DIR 1,4 4544 625235 /Users/therzok/Applications ``` A workaround I've also tried was using a larger cone of watching, such as, "~", but that causes a huge spike in the amount of notifications received for the app, causing high energy consumptions and overall having a big toll on the user machine. Code attachment: #import <Foundation/Foundation.h> static void cb(ConstFSEventStreamRef streamRef, void *pClientCallBackInfo, size_t numEvents, void *pEventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { } int main(int argc, const char * argv[]) { @autoreleasepool { // Get the current user documents directory NSArray<NSString *> *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsPath = [pathArray firstObject]; pathArray = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES); NSString *applicationDirectory = [pathArray firstObject]; // Append the documents directory twice and the directory's parent once NSArray<NSString *> *pathsToWatch = [NSArray arrayWithObjects: documentsPath, documentsPath, applicationDirectory, nil]; FSEventStreamRef stream = FSEventStreamCreate(NULL, &cb, NULL, (__bridge CFArrayRef)pathsToWatch, kFSEventStreamEventIdSinceNow, 0, kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents); dispatch_queue_t queue = dispatch_queue_create("fw", DISPATCH_QUEUE_SERIAL); FSEventStreamSetDispatchQueue(stream, queue); FSEventStreamStart(stream); // now run lsof -p on the process to see open handles // At this point, we have a lot of duplicate handles: /* fw 8417 therzok 4r DIR 1,4 4544 625235 /Users/therzok/Documents fw 8417 therzok 5r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 6r DIR 1,4 192 170037 /Users fw 8417 therzok 7r DIR 1,4 4544 625235 /Users/therzok/Documents fw 8417 therzok 8r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 9r DIR 1,4 192 170037 /Users fw 8417 therzok 10r DIR 1,4 384 1138601 /Users/therzok/Applications fw 8417 therzok 11r DIR 1,4 4896 625234 /Users/therzok fw 8417 therzok 12r DIR 1,4 192 170037 /Users */ sleep(100000); } return 0; }
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!