1 /* 2 * Copyright 2007, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "FileSystemClient.h" 28 #include "JavaSharedClient.h" 29 #include "TimerClient.h" 30 #include "SkDeque.h" 31 #include "SkThread.h" 32 33 namespace android { 34 TimerClient* JavaSharedClient::GetTimerClient() 35 { 36 return gTimerClient; 37 } 38 39 CookieClient* JavaSharedClient::GetCookieClient() 40 { 41 return gCookieClient; 42 } 43 44 PluginClient* JavaSharedClient::GetPluginClient() 45 { 46 return gPluginClient; 47 } 48 49 KeyGeneratorClient* JavaSharedClient::GetKeyGeneratorClient() 50 { 51 return gKeyGeneratorClient; 52 } 53 54 FileSystemClient* JavaSharedClient::GetFileSystemClient() 55 { 56 return gFileSystemClient; 57 } 58 59 void JavaSharedClient::SetTimerClient(TimerClient* client) 60 { 61 gTimerClient = client; 62 } 63 64 void JavaSharedClient::SetCookieClient(CookieClient* client) 65 { 66 gCookieClient = client; 67 } 68 69 void JavaSharedClient::SetPluginClient(PluginClient* client) 70 { 71 gPluginClient = client; 72 } 73 74 void JavaSharedClient::SetKeyGeneratorClient(KeyGeneratorClient* client) 75 { 76 gKeyGeneratorClient = client; 77 } 78 79 void JavaSharedClient::SetFileSystemClient(FileSystemClient* client) 80 { 81 gFileSystemClient = client; 82 } 83 84 TimerClient* JavaSharedClient::gTimerClient = NULL; 85 CookieClient* JavaSharedClient::gCookieClient = NULL; 86 PluginClient* JavaSharedClient::gPluginClient = NULL; 87 KeyGeneratorClient* JavaSharedClient::gKeyGeneratorClient = NULL; 88 FileSystemClient* JavaSharedClient::gFileSystemClient = NULL; 89 90 /////////////////////////////////////////////////////////////////////////// 91 92 struct FuncPtrRec { 93 void (*fProc)(void* payload); 94 void* fPayload; 95 }; 96 97 static SkMutex gFuncPtrQMutex; 98 static SkDeque gFuncPtrQ(sizeof(FuncPtrRec)); 99 100 void JavaSharedClient::EnqueueFunctionPtr(void (*proc)(void* payload), 101 void* payload) 102 { 103 gFuncPtrQMutex.acquire(); 104 105 FuncPtrRec* rec = (FuncPtrRec*)gFuncPtrQ.push_back(); 106 rec->fProc = proc; 107 rec->fPayload = payload; 108 109 gFuncPtrQMutex.release(); 110 111 gTimerClient->signalServiceFuncPtrQueue(); 112 } 113 114 void JavaSharedClient::ServiceFunctionPtrQueue() 115 { 116 // Don't let execution block the WebViewCore thread for too long. 117 void (*proc)(void*) = 0; 118 void* payload = 0; 119 const FuncPtrRec* rec; 120 121 // we have to copy the proc/payload (if present). we do this so we 122 // don't call the proc inside the mutex (possible deadlock!) 123 gFuncPtrQMutex.acquire(); 124 rec = (const FuncPtrRec*)gFuncPtrQ.front(); 125 if (rec) { 126 proc = rec->fProc; 127 payload = rec->fPayload; 128 gFuncPtrQ.pop_front(); 129 } 130 bool scheduleAdditionalCall = (gFuncPtrQ.count() > 0); 131 gFuncPtrQMutex.release(); 132 133 if (rec) 134 proc(payload); 135 if (scheduleAdditionalCall) 136 gTimerClient->signalServiceFuncPtrQueue(); 137 } 138 } 139