Title: [216257] trunk/Source/WebCore
Revision
216257
Author
wenson_hs...@apple.com
Date
2017-05-05 12:20:32 -0700 (Fri, 05 May 2017)

Log Message

Add SPI to WebItemProviderPasteboard to synchronously load data with a given timeout
https://bugs.webkit.org/show_bug.cgi?id=171725
<rdar://problem/32014052>

Reviewed by Beth Dakin.

Adds a synchronousTimeout: argument to doAfterLoadingProvidedContentIntoFileURLs:. If a positive timeout
interval is specified by the client, then we will block the main thread for at most that amount of time after
beginning to load from the item providers.

To do this, we introduce another `dispatch_group_t` in parallel to the `fileLoadingGroup` that is entered and
left in the same places. However, instead of attaching a handler block, we simply perform a synchronous wait for
either the time limit to be reached, or the item providers to finish loading.

No new tests -- no change in behavior yet.

* platform/ios/WebItemProviderPasteboard.h:
* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:]):
(-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (216256 => 216257)


--- trunk/Source/WebCore/ChangeLog	2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/ChangeLog	2017-05-05 19:20:32 UTC (rev 216257)
@@ -1,3 +1,26 @@
+2017-05-05  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        Add SPI to WebItemProviderPasteboard to synchronously load data with a given timeout
+        https://bugs.webkit.org/show_bug.cgi?id=171725
+        <rdar://problem/32014052>
+
+        Reviewed by Beth Dakin.
+
+        Adds a synchronousTimeout: argument to doAfterLoadingProvidedContentIntoFileURLs:. If a positive timeout
+        interval is specified by the client, then we will block the main thread for at most that amount of time after
+        beginning to load from the item providers.
+
+        To do this, we introduce another `dispatch_group_t` in parallel to the `fileLoadingGroup` that is entered and
+        left in the same places. However, instead of attaching a handler block, we simply perform a synchronous wait for
+        either the time limit to be reached, or the item providers to finish loading.
+
+        No new tests -- no change in behavior yet.
+
+        * platform/ios/WebItemProviderPasteboard.h:
+        * platform/ios/WebItemProviderPasteboard.mm:
+        (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:]):
+        (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]):
+
 2017-05-05  Chris Dumez  <cdu...@apple.com>
 
         Clean up Attr.idl

Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h (216256 => 216257)


--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h	2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h	2017-05-05 19:20:32 UTC (rev 216257)
@@ -47,10 +47,11 @@
 @end
 
 /*! A WebItemProviderRegistrationInfoList represents a series of registration calls used to set up a
- @discussion single item provider. The order of items specified in the list (lowest indices first) is
- the order in which objects or data are registered to the item provider, and therefore indicates the
- relative fidelity of each item. Private UTI types, such as those vended through the injected editing
- bundle SPI, are considered to be higher fidelity than the other default types.
+ single item provider.
+ @discussion The order of items specified in the list (lowest indices first) is the order in which
+ objects or data are registered to the item provider, and therefore indicates the relative fidelity
+ of each item. Private UTI types, such as those vended through the injected editing bundle SPI, are
+ considered to be higher fidelity than the other default types.
  */
 WEBCORE_EXPORT @interface WebItemProviderRegistrationInfoList : NSObject
 
@@ -88,6 +89,7 @@
 
 // The given completion block is always dispatched on the main thread.
 - (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action;
+- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action synchronousTimeout:(NSTimeInterval)synchronousTimeout;
 
 @end
 

Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (216256 => 216257)


--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2017-05-05 19:20:32 UTC (rev 216257)
@@ -422,6 +422,11 @@
 
 - (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action
 {
+    [self doAfterLoadingProvidedContentIntoFileURLs:action synchronousTimeout:0];
+}
+
+- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action synchronousTimeout:(NSTimeInterval)synchronousTimeout
+{
     auto changeCountBeforeLoading = _changeCount;
     auto typeToFileURLMaps = adoptNS([[NSMutableArray alloc] initWithCapacity:[_itemProviders count]]);
 
@@ -464,6 +469,8 @@
         return;
     }
 
+    auto setFileURLsLock = adoptNS([[NSLock alloc] init]);
+    auto synchronousFileLoadingGroup = adoptOSObject(dispatch_group_create());
     auto fileLoadingGroup = adoptOSObject(dispatch_group_create());
     for (NSUInteger index = 0; index < [itemProvidersWithFiles count]; ++index) {
         RetainPtr<UIItemProvider> itemProvider = [itemProvidersWithFiles objectAtIndex:index];
@@ -471,20 +478,19 @@
         NSUInteger indexInItemProviderArray = [[indicesOfItemProvidersWithFiles objectAtIndex:index] unsignedIntegerValue];
         RetainPtr<NSString> suggestedName = [itemProvider suggestedName];
         dispatch_group_enter(fileLoadingGroup.get());
-        [itemProvider loadFileRepresentationForTypeIdentifier:typeIdentifier.get() completionHandler:[indexInItemProviderArray, suggestedName, typeIdentifier, typeToFileURLMaps, fileLoadingGroup] (NSURL *url, NSError *error) {
+        dispatch_group_enter(synchronousFileLoadingGroup.get());
+        [itemProvider loadFileRepresentationForTypeIdentifier:typeIdentifier.get() completionHandler:[synchronousFileLoadingGroup, setFileURLsLock, indexInItemProviderArray, suggestedName, typeIdentifier, typeToFileURLMaps, fileLoadingGroup] (NSURL *url, NSError *error) {
             // After executing this completion block, UIKit removes the file at the given URL. However, we need this data to persist longer for the web content process.
             // To address this, we hard link the given URL to a new temporary file in the temporary directory. This follows the same flow as regular file upload, in
             // WKFileUploadPanel.mm. The temporary files are cleaned up by the system at a later time.
-            RetainPtr<NSURL> destinationURL = temporaryFileURLForDataInteractionContent(url.pathExtension, suggestedName.get());
-            if (!destinationURL || error || ![[NSFileManager defaultManager] linkItemAtURL:url toURL:destinationURL.get() error:nil]) {
-                dispatch_group_leave(fileLoadingGroup.get());
-                return;
+            RetainPtr<NSURL> destinationURL = temporaryFileURLForDataInteractionContent(url.pathExtension, suggestedName.get() ?: url.lastPathComponent);
+            if (destinationURL && !error && [[NSFileManager defaultManager] linkItemAtURL:url toURL:destinationURL.get() error:nil]) {
+                [setFileURLsLock lock];
+                [typeToFileURLMaps setObject:[NSDictionary dictionaryWithObject:destinationURL.get() forKey:typeIdentifier.get()] atIndexedSubscript:indexInItemProviderArray];
+                [setFileURLsLock unlock];
             }
-
-            dispatch_async(dispatch_get_main_queue(), [indexInItemProviderArray, typeIdentifier, destinationURL, typeToFileURLMaps, fileLoadingGroup] {
-                [typeToFileURLMaps setObject:[NSDictionary dictionaryWithObject:destinationURL.get() forKey:typeIdentifier.get()] atIndexedSubscript:indexInItemProviderArray];
-                dispatch_group_leave(fileLoadingGroup.get());
-            });
+            dispatch_group_leave(fileLoadingGroup.get());
+            dispatch_group_leave(synchronousFileLoadingGroup.get());
         }];
     }
 
@@ -495,6 +501,9 @@
 
         completionBlock([retainedSelf fileURLsForDataInteraction]);
     });
+
+    if (synchronousTimeout > 0)
+        dispatch_group_wait(synchronousFileLoadingGroup.get(), dispatch_time(DISPATCH_TIME_NOW, synchronousTimeout * NSEC_PER_SEC));
 }
 
 - (WebItemProviderRegistrationInfoList *)registrationInfoAtIndex:(NSUInteger)index
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to