diff options
Diffstat (limited to 'Source/WebKit2/WebProcess')
17 files changed, 237 insertions, 346 deletions
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h index fa364cd72..dd68e1f9b 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h @@ -182,6 +182,16 @@ private: virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) OVERRIDE; virtual void setNeedsOneShotDrawingSynchronization() OVERRIDE; virtual void scheduleCompositingLayerSync() OVERRIDE; + + virtual CompositingTriggerFlags allowedCompositingTriggers() const + { + return static_cast<CompositingTriggerFlags>( + ThreeDTransformTrigger | + VideoTrigger | + PluginTrigger| + CanvasTrigger | + AnimationTrigger); + } #endif #if ENABLE(TOUCH_EVENTS) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp index c0f612801..907d20c5c 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp @@ -401,6 +401,9 @@ WebGraphicsLayer* toWebGraphicsLayer(GraphicsLayer* layer) void WebGraphicsLayer::syncCompositingStateForThisLayerOnly() { + if (!m_layerTreeTileClient) + m_layerTreeTileClient = layerTreeTileClient(); + updateContentBuffers(); if (!m_modified) @@ -431,12 +434,11 @@ void WebGraphicsLayer::syncCompositingStateForThisLayerOnly() for (size_t i = 0; i < children().size(); ++i) m_layerInfo.children.append(toWebLayerID(children()[i])); - WebLayerTreeTileClient* tileClient = layerTreeTileClient(); - ASSERT(tileClient); + ASSERT(m_layerTreeTileClient); if (m_layerInfo.imageIsUpdated && m_image && !m_layerInfo.imageBackingStoreID) - m_layerInfo.imageBackingStoreID = tileClient->adoptImageBackingStore(m_image.get()); + m_layerInfo.imageBackingStoreID = m_layerTreeTileClient->adoptImageBackingStore(m_image.get()); - tileClient->didSyncCompositingStateForLayer(m_layerInfo); + m_layerTreeTileClient->didSyncCompositingStateForLayer(m_layerInfo); m_modified = false; m_layerInfo.imageIsUpdated = false; if (m_hasPendingAnimations) @@ -612,6 +614,22 @@ void WebGraphicsLayer::recreateBackingStoreIfNeeded() if (m_image) setContentsNeedsDisplay(); } + +void WebGraphicsLayer::setLayerTreeTileClient(WebKit::WebLayerTreeTileClient* client) +{ + if (m_layerTreeTileClient == client) + return; + + for (size_t i = 0; i < children().size(); ++i) { + WebGraphicsLayer* layer = toWebGraphicsLayer(this->children()[i]); + layer->setLayerTreeTileClient(client); + } + + // Have to force detach from remote layer here if layer tile client changes. + if (m_layerTreeTileClient) + m_layerTreeTileClient->didDeleteLayer(id()); + m_layerTreeTileClient = client; +} #endif static PassOwnPtr<GraphicsLayer> createWebGraphicsLayer(GraphicsLayerClient* client) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h index 52955de1e..361fcb286 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h @@ -124,7 +124,7 @@ public: virtual void updateTile(int tileID, const WebKit::UpdateInfo&); virtual void removeTile(int tileID); - void setLayerTreeTileClient(WebKit::WebLayerTreeTileClient* client) { m_layerTreeTileClient = client; } + void setLayerTreeTileClient(WebKit::WebLayerTreeTileClient*); WebKit::WebLayerTreeTileClient* layerTreeTileClient() const; bool isReadyForTileBufferSwap() const; diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp index 6486587d0..1a91d8e3c 100644 --- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp @@ -78,7 +78,7 @@ void EventDispatcher::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection } } -void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent) +void EventDispatcher::wheelEvent(CoreIPC::Connection*, uint64_t pageID, const WebWheelEvent& wheelEvent) { #if ENABLE(THREADED_SCROLLING) MutexLocker locker(m_scrollingCoordinatorsMutex); @@ -96,7 +96,7 @@ void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEven } #if ENABLE(GESTURE_EVENTS) -void EventDispatcher::gestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) +void EventDispatcher::gestureEvent(CoreIPC::Connection*, uint64_t pageID, const WebGestureEvent& gestureEvent) { #if ENABLE(THREADED_SCROLLING) MutexLocker locker(m_scrollingCoordinatorsMutex); diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h index 7cd2f9550..f8c459af5 100644 --- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h @@ -66,9 +66,9 @@ private: void didReceiveEventDispatcherMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage); // Message handlers - void wheelEvent(uint64_t pageID, const WebWheelEvent&); + void wheelEvent(CoreIPC::Connection*, uint64_t pageID, const WebWheelEvent&); #if ENABLE(GESTURE_EVENTS) - void gestureEvent(uint64_t pageID, const WebGestureEvent&); + void gestureEvent(CoreIPC::Connection*, uint64_t pageID, const WebGestureEvent&); #endif // This is called on the main thread. diff --git a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp index 266a3a95d..341fb69e4 100644 --- a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp +++ b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp @@ -52,6 +52,8 @@ PassRefPtr<LayerTreeHostQt> LayerTreeHostQt::create(WebPage* webPage) LayerTreeHostQt::~LayerTreeHostQt() { + if (m_rootLayer) + toWebGraphicsLayer(m_rootLayer.get())->setLayerTreeTileClient(0); } LayerTreeHostQt::LayerTreeHostQt(WebPage* webPage) diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp index 9fdca9051..39b3bc8e5 100644 --- a/Source/WebKit2/WebProcess/WebProcess.cpp +++ b/Source/WebKit2/WebProcess/WebProcess.cpp @@ -949,7 +949,7 @@ void WebProcess::garbageCollectJavaScriptObjects() } #if ENABLE(PLUGIN_PROCESS) -void WebProcess::pluginProcessCrashed(const String& pluginPath) +void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath) { m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath); } diff --git a/Source/WebKit2/WebProcess/WebProcess.h b/Source/WebKit2/WebProcess/WebProcess.h index b6fff7f2f..1e50284c0 100644 --- a/Source/WebKit2/WebProcess/WebProcess.h +++ b/Source/WebKit2/WebProcess/WebProcess.h @@ -73,6 +73,11 @@ struct WebPageGroupData; struct WebPreferencesStore; struct WebProcessCreationParameters; +#if PLATFORM(MAC) +class SecItemResponseData; +class SecKeychainItemResponseData; +#endif + class WebProcess : public ChildProcess, private CoreIPC::Connection::QueueClient { public: static WebProcess& shared(); @@ -182,7 +187,7 @@ private: #endif #if ENABLE(PLUGIN_PROCESS) - void pluginProcessCrashed(const String& pluginPath); + void pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath); #endif void startMemorySampler(const SandboxExtension::Handle&, const String&, const double); @@ -199,6 +204,11 @@ private: void getWebCoreStatistics(uint64_t callbackID); void garbageCollectJavaScriptObjects(); +#if PLATFORM(MAC) + void secItemResponse(CoreIPC::Connection*, uint64_t requestID, const SecItemResponseData&); + void secKeychainItemResponse(CoreIPC::Connection*, uint64_t requestID, const SecKeychainItemResponseData&); +#endif + // ChildProcess virtual bool shouldTerminate(); virtual void terminate(); diff --git a/Source/WebKit2/WebProcess/WebProcess.messages.in b/Source/WebKit2/WebProcess/WebProcess.messages.in index b991f44c5..641cc7df1 100644 --- a/Source/WebKit2/WebProcess/WebProcess.messages.in +++ b/Source/WebKit2/WebProcess/WebProcess.messages.in @@ -75,4 +75,9 @@ messages -> WebProcess { GetWebCoreStatistics(uint64_t callbackID) GarbageCollectJavaScriptObjects() + +#if PLATFORM(MAC) + SecItemResponse(uint64_t requestID, WebKit::SecItemResponseData response) DispatchOnConnectionQueue + SecKeychainItemResponse(uint64_t requestID, WebKit::SecKeychainItemResponseData response) DispatchOnConnectionQueue +#endif } diff --git a/Source/WebKit2/WebProcess/com.apple.WebProcess.sb b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb index 80c707806..41c00ac2e 100644 --- a/Source/WebKit2/WebProcess/com.apple.WebProcess.sb +++ b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb @@ -151,6 +151,7 @@ (global-name "com.apple.SecurityServer") (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.SystemConfiguration.PPPController") + (global-name "com.apple.SystemConfiguration.SCNetworkReachability") (global-name "com.apple.audio.VDCAssistant") (global-name "com.apple.audio.audiohald") (global-name "com.apple.audio.coreaudiod") diff --git a/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm b/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm deleted file mode 100644 index cb50465f9..000000000 --- a/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "CoreIPCClientRunLoop.h" - -#import <WebCore/ResourceHandle.h> -#import <wtf/RetainPtr.h> - -using namespace WebCore; - -@interface WKFunctionAdapter : NSObject -{ -@public - WebKit::FunctionWithContext function; - void* context; -} -- (void)perform; -@end - -@implementation WKFunctionAdapter - -- (void)perform -{ - function(context); -} - -@end - -namespace WebKit { - -static CFArrayRef createCoreIPCRunLoopModesArray() -{ - // Ideally we'd like to list all modes here that might be used for run loops while we are handling networking. - // We have to explicitly include the run loop mode used for synchronous loads in WebCore so we don't get deadlock - // when those loads call security functions that are shimmed. - const void* values[2] = { kCFRunLoopCommonModes, ResourceHandle::synchronousLoadRunLoopMode() }; - return CFArrayCreate(0, values, 2, &kCFTypeArrayCallBacks); -} - -static NSArray *coreIPCRunLoopModesArray() -{ - static CFArrayRef modes = createCoreIPCRunLoopModesArray(); - return (NSArray *)modes; -} - -void callOnCoreIPCClientRunLoopAndWait(FunctionWithContext function, void* context) -{ - // FIXME: It would fit better with WebKit2 coding style to use a WTF Function here. - // To do that we'd need to make dispatch have an overload that takes an array of run loop modes or find some - // other way to specify that we want to include the synchronous load run loop mode. - RetainPtr<WKFunctionAdapter> adapter(AdoptNS, [[WKFunctionAdapter alloc] init]); - adapter->function = function; - adapter->context = context; - [adapter.get() performSelectorOnMainThread:@selector(perform) withObject:nil waitUntilDone:YES modes:coreIPCRunLoopModesArray()]; -} - -} diff --git a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h index ae80130ad..1c7fe33c6 100644 --- a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h +++ b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h @@ -30,6 +30,9 @@ namespace WebKit { void initializeKeychainItemShim(); +class SecKeychainItemResponseData; +void didReceiveSecKeychainItemResponse(uint64_t requestID, const SecKeychainItemResponseData&); + } #endif // KeychainItemShimMethods_h diff --git a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm index 0f1ac9317..5f71ae46b 100644 --- a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm +++ b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm @@ -28,7 +28,7 @@ #if defined(BUILDING_ON_SNOW_LEOPARD) -#import "CoreIPCClientRunLoop.h" +#import "KeychainShimResponseMap.h" #import "SecKeychainItemRequestData.h" #import "SecKeychainItemResponseData.h" #import "WebProcess.h" @@ -40,34 +40,30 @@ namespace WebKit { // Methods to allow the shim to manage memory for its own AttributeList contents. -static HashSet<SecKeychainAttributeList*>& shimManagedAttributeLists() +static HashSet<SecKeychainAttributeList*>& managedAttributeLists() { - DEFINE_STATIC_LOCAL(HashSet<SecKeychainAttributeList*>, set, ()); - return set; + AtomicallyInitializedStatic(HashSet<SecKeychainAttributeList*>&, managedAttributeLists = *new HashSet<SecKeychainAttributeList*>); + + return managedAttributeLists; } -static void freeAttributeListContents(SecKeychainAttributeList* attrList) +static Mutex& managedAttributeListsMutex() { - ASSERT(shimManagedAttributeLists().contains(attrList)); - ASSERT(attrList); - - for (size_t i = 0; i < attrList->count; ++i) - free(attrList->attr[i].data); - - shimManagedAttributeLists().remove(attrList); + AtomicallyInitializedStatic(Mutex&, managedAttributeListsMutex = *new Mutex); + return managedAttributeListsMutex; } static void allocateAttributeListContents(const Vector<KeychainAttribute>& attributes, SecKeychainAttributeList* attrList) { - ASSERT(isMainThread()); - if (!attrList) return; - - ASSERT(!shimManagedAttributeLists().contains(attrList)); + + MutexLocker locker(managedAttributeListsMutex()); + + ASSERT(!managedAttributeLists().contains(attrList)); ASSERT(attributes.size() == attrList->count); - shimManagedAttributeLists().add(attrList); + managedAttributeLists().add(attrList); for (size_t i = 0; i < attrList->count; ++i) { ASSERT(attributes[i].tag == attrList->attr[i].tag); @@ -87,15 +83,20 @@ static void allocateAttributeListContents(const Vector<KeychainAttribute>& attri } // Methods to allow the shim to manage memory for its own KeychainItem content data. -static HashSet<void*>& shimManagedKeychainItemContents() +static HashSet<void*>& managedKeychainItemContents() +{ + AtomicallyInitializedStatic(HashSet<void*>&, managedKeychainItemContents = *new HashSet<void*>); + return managedKeychainItemContents; +} + +static Mutex& managedKeychainItemContentsMutex() { - DEFINE_STATIC_LOCAL(HashSet<void*>, set, ()); - return set; + AtomicallyInitializedStatic(Mutex&, managedKeychainItemContentsMutex = *new Mutex); + return managedKeychainItemContentsMutex; } static void allocateKeychainItemContentData(CFDataRef cfData, UInt32* length, void** data) { - ASSERT(isMainThread()); ASSERT((length && data) || (!length && !data)); if (!data) return; @@ -109,184 +110,107 @@ static void allocateKeychainItemContentData(CFDataRef cfData, UInt32* length, vo *length = CFDataGetLength(cfData); *data = malloc(*length); CFDataGetBytes(cfData, CFRangeMake(0, *length), (UInt8*)*data); - shimManagedKeychainItemContents().add(*data); + + MutexLocker locker(managedKeychainItemContentsMutex()); + managedKeychainItemContents().add(*data); } -// FIXME (https://bugs.webkit.org/show_bug.cgi?id=60975) - Once CoreIPC supports sync messaging from a secondary thread, -// we can remove FreeAttributeListContext, FreeKeychainItemDataContext, KeychainItemAPIContext, and these 5 main-thread methods, -// and we can have the shim methods call out directly from whatever thread they're called on. +static bool webFreeAttributeListContent(SecKeychainAttributeList* attrList) +{ + MutexLocker locker(managedAttributeListsMutex()); -struct FreeAttributeListContext { - SecKeychainAttributeList* attrList; - bool freed; -}; + if (!managedAttributeLists().contains(attrList)) + return false; -static void webFreeAttributeListContentOnMainThread(void* voidContext) -{ - FreeAttributeListContext* context = (FreeAttributeListContext*)voidContext; - - if (!shimManagedAttributeLists().contains(context->attrList)) { - context->freed = false; - return; - } + for (size_t i = 0; i < attrList->count; ++i) + free(attrList->attr[i].data); - freeAttributeListContents(context->attrList); - context->freed = true; + managedAttributeLists().remove(attrList); + return true; } -static bool webFreeAttributeListContent(SecKeychainAttributeList* attrList) +static bool webFreeKeychainItemContent(void* data) { - FreeAttributeListContext context; - context.attrList = attrList; - - callOnCoreIPCClientRunLoopAndWait(webFreeAttributeListContentOnMainThread, &context); + MutexLocker locker(managedKeychainItemContentsMutex()); - return context.freed; -} + HashSet<void*>::iterator it = managedKeychainItemContents().find(data); + if (it == managedKeychainItemContents().end()) + return false; -struct FreeKeychainItemDataContext { - void* data; - bool freed; -}; + managedKeychainItemContents().remove(it); + return true; +} -static void webFreeKeychainItemContentOnMainThread(void* voidContext) +static KeychainShimResponseMap<SecKeychainItemResponseData>& responseMap() { - FreeKeychainItemDataContext* context = (FreeKeychainItemDataContext*)voidContext; - - if (!shimManagedKeychainItemContents().contains(context->data)) { - context->freed = false; - return; - } - - shimManagedKeychainItemContents().remove(context->data); - free(context->data); - context->freed = true; + AtomicallyInitializedStatic(KeychainShimResponseMap<SecKeychainItemResponseData>&, responseMap = *new KeychainShimResponseMap<SecKeychainItemResponseData>); + return responseMap; } -static bool webFreeKeychainItemContent(void* data) +static uint64_t generateSecKeychainItemRequestID() { - FreeKeychainItemDataContext context; - context.data = data; - - callOnCoreIPCClientRunLoopAndWait(webFreeKeychainItemContentOnMainThread, &context); - - return context.freed; + static int64_t uniqueSecKeychainItemRequestID; + return OSAtomicIncrement64Barrier(&uniqueSecKeychainItemRequestID); } -struct SecKeychainItemContext { - SecKeychainItemRef item; - - SecKeychainAttributeList* attributeList; - SecItemClass initialItemClass; - UInt32 length; - const void* data; - - SecItemClass* resultItemClass; - UInt32* resultLength; - void** resultData; - - OSStatus resultCode; -}; +void didReceiveSecKeychainItemResponse(uint64_t requestID, const SecKeychainItemResponseData& response) +{ + responseMap().didReceiveResponse(requestID, adoptPtr(new SecKeychainItemResponseData(response))); +} -static void webSecKeychainItemCopyContentOnMainThread(void* voidContext) +static PassOwnPtr<SecKeychainItemResponseData> sendSeqKeychainItemRequest(const SecKeychainItemRequestData& request) { - SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; + uint64_t requestID = generateSecKeychainItemRequestID(); + if (!WebProcess::shared().connection()->send(Messages::WebProcessProxy::SecKeychainItemRequest(requestID, request), 0)) + return nullptr; - SecKeychainItemRequestData requestData(context->item, context->attributeList); - SecKeychainItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemCopyContent(requestData), Messages::WebProcessProxy::SecKeychainItemCopyContent::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; - ASSERT_NOT_REACHED(); - return; - } - - allocateAttributeListContents(response.attributes(), context->attributeList); - allocateKeychainItemContentData(response.data(), context->resultLength, context->resultData); - if (context->resultItemClass) - *context->resultItemClass = response.itemClass(); - context->resultCode = response.resultCode(); + return responseMap().waitForResponse(requestID); } static OSStatus webSecKeychainItemCopyContent(SecKeychainItemRef item, SecItemClass* itemClass, SecKeychainAttributeList* attrList, UInt32* length, void** outData) { - SecKeychainItemContext context; - memset(&context, 0, sizeof(SecKeychainItemContext)); - context.item = item; - context.resultItemClass = itemClass; - context.attributeList = attrList; - context.resultLength = length; - context.resultData = outData; + SecKeychainItemRequestData request(SecKeychainItemRequestData::CopyContent, item, attrList); + OwnPtr<SecKeychainItemResponseData> response = sendSeqKeychainItemRequest(request); + if (!response) { + ASSERT_NOT_REACHED(); + return errSecInteractionNotAllowed; + } - callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemCopyContentOnMainThread, &context); + if (itemClass) + *itemClass = response->itemClass(); + allocateAttributeListContents(response->attributes(), attrList); + allocateKeychainItemContentData(response->data(), length, outData); - // FIXME: should return context.resultCode. Returning noErr is a workaround for <rdar://problem/9520886>; + // FIXME: should return response->resultCode(). Returning noErr is a workaround for <rdar://problem/9520886>; // the authentication should fail anyway, since on error no data will be returned. return noErr; } -static void webSecKeychainItemCreateFromContentOnMainThread(void* voidContext) +static OSStatus webSecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList* attrList, UInt32 length, const void* data, SecKeychainItemRef *item) { - SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; - - SecKeychainItemRequestData requestData(context->initialItemClass, context->attributeList, context->length, context->data); - SecKeychainItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemCreateFromContent(requestData), Messages::WebProcessProxy::SecKeychainItemCreateFromContent::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; + SecKeychainItemRequestData request(SecKeychainItemRequestData::CreateFromContent, itemClass, attrList, length, data); + OwnPtr<SecKeychainItemResponseData> response = sendSeqKeychainItemRequest(request); + if (!response) { ASSERT_NOT_REACHED(); - return; + return errSecInteractionNotAllowed; } - if (response.keychainItem()) - CFRetain(response.keychainItem()); - context->item = response.keychainItem(); - context->resultCode = response.resultCode(); -} - -static OSStatus webSecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList* attrList, UInt32 length, const void* data, SecKeychainItemRef *item) -{ - SecKeychainItemContext context; - memset(&context, 0, sizeof(SecKeychainItemContext)); - context.initialItemClass = itemClass; - context.attributeList = attrList; - context.length = length; - context.data = data; - - callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemCreateFromContentOnMainThread, &context); - if (item) - *item = context.item; - else - CFRelease(context.item); + *item = RetainPtr<SecKeychainItemRef>(response->keychainItem()).leakRef(); - return context.resultCode; + return response->resultCode(); } -static void webSecKeychainItemModifyContentOnMainThread(void* voidContext) +static OSStatus webSecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList* attrList, UInt32 length, const void* data) { - SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; - - SecKeychainItemRequestData requestData(context->item, context->attributeList, context->length, context->data); - SecKeychainItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemModifyContent(requestData), Messages::WebProcessProxy::SecKeychainItemModifyContent::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; + SecKeychainItemRequestData request(SecKeychainItemRequestData::ModifyContent, itemRef, (SecKeychainAttributeList*)attrList, length, data); + OwnPtr<SecKeychainItemResponseData> response = sendSeqKeychainItemRequest(request); + if (!response) { ASSERT_NOT_REACHED(); - return; + return errSecInteractionNotAllowed; } - - context->resultCode = response.resultCode(); -} -static OSStatus webSecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList* attrList, UInt32 length, const void* data) -{ - SecKeychainItemContext context; - context.item = itemRef; - context.attributeList = (SecKeychainAttributeList*)attrList; - context.length = length; - context.data = data; - - callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemModifyContentOnMainThread, &context); - - return context.resultCode; + return response->resultCode(); } void initializeKeychainItemShim() diff --git a/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.h b/Source/WebKit2/WebProcess/mac/KeychainShimResponseMap.h index 28f3f4797..b4a78e648 100644 --- a/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.h +++ b/Source/WebKit2/WebProcess/mac/KeychainShimResponseMap.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,12 +23,47 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -namespace WebKit { +#ifndef KeychainShimResponseMap_h +#define KeychainShimResponseMap_h -typedef void (*FunctionWithContext)(void* context); +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/ThreadingPrimitives.h> -// Call the function on a thread where it's safe to send a synchronous CoreIPC message. -// We can't use WTF's callOnMainThreadAndWait because it doesn't support enough run loop modes. -void callOnCoreIPCClientRunLoopAndWait(FunctionWithContext, void* context); +template<typename T> +class KeychainShimResponseMap { +public: + PassOwnPtr<T> waitForResponse(uint64_t requestID) + { + while (true) { + MutexLocker locker(m_mutex); -} + if (OwnPtr<T> response = m_responses.take(requestID)) + return response.release(); + + m_condition.wait(m_mutex); + } + + return nullptr; + } + + void didReceiveResponse(uint64_t requestID, PassOwnPtr<T> response) + { + MutexLocker locker(m_mutex); + ASSERT(!m_responses.contains(requestID)); + + m_responses.set(requestID, response); + m_condition.signal(); + } + +private: + Mutex m_mutex; + ThreadCondition m_condition; + + HashMap<uint64_t, OwnPtr<T> > m_responses; +}; + + + +#endif // KeychainShimResponseMap_h diff --git a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h index 9d67ed982..7c8d4791d 100644 --- a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h +++ b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h @@ -30,6 +30,9 @@ namespace WebKit { void initializeSecItemShim(); +class SecItemResponseData; +void didReceiveSecItemResponse(uint64_t requestID, const SecItemResponseData&); + } #endif // SecItemShimMethods_h diff --git a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm index 5b2b75ce8..c3575744f 100644 --- a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm +++ b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm @@ -28,7 +28,7 @@ #if !defined(BUILDING_ON_SNOW_LEOPARD) -#import "CoreIPCClientRunLoop.h" +#import "KeychainShimResponseMap.h" #import "SecItemRequestData.h" #import "SecItemResponseData.h" #import "WebProcess.h" @@ -39,122 +39,68 @@ namespace WebKit { -// FIXME (https://bugs.webkit.org/show_bug.cgi?id=60975) - Once CoreIPC supports sync messaging from a secondary thread, -// we can remove SecItemAPIContext and these 4 main-thread methods, and we can have the shim methods call out directly -// from whatever thread they're on. - -struct SecItemAPIContext { - CFDictionaryRef query; - CFDictionaryRef attributesToUpdate; - CFTypeRef resultObject; - OSStatus resultCode; -}; - -static void webSecItemCopyMatchingMainThread(void* voidContext) +static KeychainShimResponseMap<SecItemResponseData>& responseMap() { - SecItemAPIContext* context = (SecItemAPIContext*)voidContext; - - SecItemRequestData requestData(context->query); - SecItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemCopyMatching(requestData), Messages::WebProcessProxy::SecItemCopyMatching::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; - ASSERT_NOT_REACHED(); - return; - } - - context->resultObject = response.resultObject().leakRef(); - context->resultCode = response.resultCode(); + AtomicallyInitializedStatic(KeychainShimResponseMap<SecItemResponseData>&, responseMap = *new KeychainShimResponseMap<SecItemResponseData>); + return responseMap; } -static OSStatus webSecItemCopyMatching(CFDictionaryRef query, CFTypeRef* result) +static uint64_t generateSecItemRequestID() { - SecItemAPIContext context; - context.query = query; - - callOnCoreIPCClientRunLoopAndWait(webSecItemCopyMatchingMainThread, &context); - - if (result) - *result = context.resultObject; - return context.resultCode; + static int64_t uniqueSecItemRequestID; + return OSAtomicIncrement64Barrier(&uniqueSecItemRequestID); } -static void webSecItemAddOnMainThread(void* voidContext) +void didReceiveSecItemResponse(uint64_t requestID, const SecItemResponseData& response) { - SecItemAPIContext* context = (SecItemAPIContext*)voidContext; - - SecItemRequestData requestData(context->query); - SecItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemAdd(requestData), Messages::WebProcessProxy::SecItemAdd::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; - ASSERT_NOT_REACHED(); - return; - } - - context->resultObject = response.resultObject().leakRef(); - context->resultCode = response.resultCode(); + responseMap().didReceiveResponse(requestID, adoptPtr(new SecItemResponseData(response))); } -static OSStatus webSecItemAdd(CFDictionaryRef query, CFTypeRef* result) +static PassOwnPtr<SecItemResponseData> sendSeqItemRequest(SecItemRequestData::Type requestType, CFDictionaryRef query, CFDictionaryRef attributesToMatch = 0) { - SecItemAPIContext context; - context.query = query; - - callOnCoreIPCClientRunLoopAndWait(webSecItemAddOnMainThread, &context); - - if (result) - *result = context.resultObject; - return context.resultCode; + uint64_t requestID = generateSecItemRequestID(); + if (!WebProcess::shared().connection()->send(Messages::WebProcessProxy::SecItemRequest(requestID, SecItemRequestData(requestType, query, attributesToMatch)), 0)) + return nullptr; + + return responseMap().waitForResponse(requestID); } -static void webSecItemUpdateOnMainThread(void* voidContext) +static OSStatus webSecItemCopyMatching(CFDictionaryRef query, CFTypeRef* result) { - SecItemAPIContext* context = (SecItemAPIContext*)voidContext; - - SecItemRequestData requestData(context->query, context->attributesToUpdate); - SecItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemUpdate(requestData), Messages::WebProcessProxy::SecItemUpdate::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; - ASSERT_NOT_REACHED(); - return; - } - - context->resultCode = response.resultCode(); + OwnPtr<SecItemResponseData> response = sendSeqItemRequest(SecItemRequestData::CopyMatching, query); + if (!response) + return errSecInteractionNotAllowed; + + *result = response->resultObject().leakRef(); + return response->resultCode(); } -static OSStatus webSecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) +static OSStatus webSecItemAdd(CFDictionaryRef query, CFTypeRef* result) { - SecItemAPIContext context; - context.query = query; - context.attributesToUpdate = attributesToUpdate; - - callOnCoreIPCClientRunLoopAndWait(webSecItemUpdateOnMainThread, &context); + OwnPtr<SecItemResponseData> response = sendSeqItemRequest(SecItemRequestData::Add, query); + if (!response) + return errSecInteractionNotAllowed; - return context.resultCode; + *result = response->resultObject().leakRef(); + return response->resultCode(); } -static void webSecItemDeleteOnMainThread(void* voidContext) +static OSStatus webSecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) { - SecItemAPIContext* context = (SecItemAPIContext*)voidContext; + OwnPtr<SecItemResponseData> response = sendSeqItemRequest(SecItemRequestData::Update, query, attributesToUpdate); + if (!response) + return errSecInteractionNotAllowed; - SecItemRequestData requestData(context->query); - SecItemResponseData response; - if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemDelete(requestData), Messages::WebProcessProxy::SecItemDelete::Reply(response), 0)) { - context->resultCode = errSecInteractionNotAllowed; - ASSERT_NOT_REACHED(); - return; - } - - context->resultCode = response.resultCode(); + return response->resultCode(); } static OSStatus webSecItemDelete(CFDictionaryRef query) { - SecItemAPIContext context; - context.query = query; + OwnPtr<SecItemResponseData> response = sendSeqItemRequest(SecItemRequestData::Delete, query); + if (!response) + return errSecInteractionNotAllowed; - callOnCoreIPCClientRunLoopAndWait(webSecItemDeleteOnMainThread, &context); - - return context.resultCode; + return response->resultCode(); } void initializeSecItemShim() diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm index e96ab4834..7d67e1e68 100644 --- a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm +++ b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm @@ -272,4 +272,18 @@ void WebProcess::platformTerminate() { } +void WebProcess::secItemResponse(CoreIPC::Connection*, uint64_t requestID, const SecItemResponseData& response) +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + didReceiveSecItemResponse(requestID, response); +#endif +} + +void WebProcess::secKeychainItemResponse(CoreIPC::Connection*, uint64_t requestID, const SecKeychainItemResponseData& response) +{ +#if defined(BUILDING_ON_SNOW_LEOPARD) + didReceiveSecKeychainItemResponse(requestID, response); +#endif +} + } // namespace WebKit |
