Changeset 215620 in webkit
- Timestamp:
- Apr 21, 2017 11:35:42 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r215618 r215620 1 2017-04-20 Keith Miller <keith_miller@apple.com> 2 3 Add signaling API 4 https://bugs.webkit.org/show_bug.cgi?id=170976 5 6 Reviewed by Filip Pizlo. 7 8 Update various uses of sigaction to use the new signaling API. 9 Also switch VMTraps to use the thread message system instead of 10 rolling it's own. 11 12 * jit/ExecutableAllocator.h: 13 (JSC::isJITPC): 14 * runtime/VMTraps.cpp: 15 (JSC::installSignalHandler): 16 (JSC::VMTraps::VMTraps): 17 (JSC::VMTraps::SignalSender::send): 18 (JSC::handleSigusr1): Deleted. 19 (JSC::handleSigtrap): Deleted. 20 (JSC::installSignalHandlers): Deleted. 21 * runtime/VMTraps.h: 22 * tools/SigillCrashAnalyzer.cpp: 23 (JSC::installCrashHandler): 24 (JSC::handleCrash): Deleted. 25 * wasm/WasmFaultSignalHandler.cpp: 26 (JSC::Wasm::trapHandler): 27 (JSC::Wasm::enableFastMemory): 28 1 29 2017-04-21 Michael Saboff <msaboff@apple.com> 2 30 -
trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h
r214571 r215620 82 82 extern JS_EXPORTDATA uintptr_t endOfFixedExecutableMemoryPool; 83 83 84 inline bool isJITPC(void* pc) 85 { 86 return reinterpret_cast<void*>(startOfFixedExecutableMemoryPool) <= pc 87 && pc < reinterpret_cast<void*>(endOfFixedExecutableMemoryPool); 88 } 89 84 90 typedef void (*JITWriteSeparateHeapsFunction)(off_t, const void*, size_t); 85 91 extern JS_EXPORTDATA JITWriteSeparateHeapsFunction jitWriteSeparateHeapsFunction; -
trunk/Source/JavaScriptCore/runtime/VMTraps.cpp
r215522 r215620 41 41 #include "Watchdog.h" 42 42 #include <wtf/ProcessID.h> 43 44 #if OS(DARWIN) 45 #include <signal.h> 46 #endif 43 #include <wtf/ThreadMessage.h> 44 #include <wtf/threads/Signals.h> 47 45 48 46 namespace JSC { … … 54 52 55 53 #if ENABLE(SIGNAL_BASED_VM_TRAPS) 56 57 struct sigaction originalSigusr1Action;58 struct sigaction originalSigtrapAction;59 54 60 55 struct SignalContext { … … 133 128 } 134 129 135 static void handleSigusr1(int signalNumber, siginfo_t* info, void* uap) 136 { 137 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext); 138 auto activeVMAndStackBounds = findActiveVMAndStackBounds(context); 139 if (activeVMAndStackBounds) { 130 static void installSignalHandler() 131 { 132 installSignalHandler(Signal::Trap, [] (int, siginfo_t*, void* uap) -> SignalAction { 133 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext); 134 135 if (!isJITPC(context.trapPC)) 136 return SignalAction::NotHandled; 137 138 // FIXME: This currently eats all traps including jit asserts we should make sure this 139 // always works. https://bugs.webkit.org/show_bug.cgi?id=171039 140 auto activeVMAndStackBounds = findActiveVMAndStackBounds(context); 141 if (!activeVMAndStackBounds) 142 return SignalAction::Handled; // Let the SignalSender try again later. 143 140 144 VM* vm = activeVMAndStackBounds.value().vm; 141 145 if (vm) { 142 StackBounds stackBounds = activeVMAndStackBounds.value().stackBounds;143 146 VMTraps& traps = vm->traps(); 144 if (traps.needTrapHandling()) 145 traps.tryInstallTrapBreakpoints(context, stackBounds); 146 } 147 } 148 149 auto originalAction = originalSigusr1Action.sa_sigaction; 150 if (originalAction) 151 originalAction(signalNumber, info, uap); 152 } 153 154 static void handleSigtrap(int signalNumber, siginfo_t* info, void* uap) 155 { 156 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext); 157 auto activeVMAndStackBounds = findActiveVMAndStackBounds(context); 158 if (!activeVMAndStackBounds) 159 return; // Let the SignalSender try again later. 160 161 VM* vm = activeVMAndStackBounds.value().vm; 162 if (vm) { 163 VMTraps& traps = vm->traps(); 164 if (!traps.needTrapHandling()) 165 return; // The polling code beat us to handling the trap already. 166 167 auto expectedSuccess = traps.tryJettisonCodeBlocksOnStack(context); 168 if (!expectedSuccess) 169 return; // Let the SignalSender try again later. 170 if (expectedSuccess.value()) 171 return; // We've success jettison the codeBlocks. 172 } 173 174 // If we get here, then this SIGTRAP is not due to a VMTrap. Let's do the default action. 175 auto originalAction = originalSigtrapAction.sa_sigaction; 176 if (originalAction) { 177 // It is always safe to just invoke the original handler using the sa_sigaction form 178 // without checking for the SA_SIGINFO flag. If the original handler is of the 179 // sa_handler form, it will just ignore the 2nd and 3rd arguments since sa_handler is a 180 // subset of sa_sigaction. This is what the man pages says the OS does anyway. 181 originalAction(signalNumber, info, uap); 182 } 183 184 // Pre-emptively restore the default handler but we may roll it back below. 185 struct sigaction currentAction; 186 struct sigaction defaultAction; 187 defaultAction.sa_handler = SIG_DFL; 188 sigfillset(&defaultAction.sa_mask); 189 defaultAction.sa_flags = 0; 190 sigaction(SIGTRAP, &defaultAction, ¤tAction); 191 192 if (currentAction.sa_sigaction != handleSigtrap) { 193 // This means that there's a client handler installed after us. This also means 194 // that the client handler thinks it was able to recover from the SIGTRAP, and 195 // did not uninstall itself. We can't argue with this because the signal isn't 196 // known to be from a VMTraps signal. Hence, restore the client handler 197 // and keep going. 198 sigaction(SIGTRAP, ¤tAction, nullptr); 199 } 200 } 201 202 static void installSignalHandlers() 203 { 204 typedef void (* SigactionHandler)(int, siginfo_t *, void *); 205 struct sigaction action; 206 207 action.sa_sigaction = reinterpret_cast<SigactionHandler>(handleSigusr1); 208 sigfillset(&action.sa_mask); 209 action.sa_flags = SA_SIGINFO; 210 sigaction(SIGUSR1, &action, &originalSigusr1Action); 211 212 action.sa_sigaction = reinterpret_cast<SigactionHandler>(handleSigtrap); 213 sigfillset(&action.sa_mask); 214 action.sa_flags = SA_SIGINFO; 215 sigaction(SIGTRAP, &action, &originalSigtrapAction); 147 if (!traps.needTrapHandling()) 148 return SignalAction::Handled; // The polling code beat us to handling the trap already. 149 150 auto expectedSuccess = traps.tryJettisonCodeBlocksOnStack(context); 151 if (!expectedSuccess) 152 return SignalAction::Handled; // Let the SignalSender try again later. 153 if (expectedSuccess.value()) 154 return SignalAction::Handled; // We've success jettison the codeBlocks. 155 } 156 157 return SignalAction::Handled; 158 }); 216 159 } 217 160 … … 401 344 static std::once_flag once; 402 345 std::call_once(once, [] { 403 installSignalHandler s();346 installSignalHandler(); 404 347 }); 405 348 } … … 461 404 auto optionalOwnerThread = vm.ownerThread(); 462 405 if (optionalOwnerThread) { 463 optionalOwnerThread.value()->signal(SIGUSR1); 406 sendMessage(*optionalOwnerThread.value().get(), [] (siginfo_t*, ucontext_t* ucontext) -> void { 407 SignalContext context(ucontext->uc_mcontext); 408 auto activeVMAndStackBounds = findActiveVMAndStackBounds(context); 409 if (activeVMAndStackBounds) { 410 VM* vm = activeVMAndStackBounds.value().vm; 411 if (vm) { 412 StackBounds stackBounds = activeVMAndStackBounds.value().stackBounds; 413 VMTraps& traps = vm->traps(); 414 if (traps.needTrapHandling()) 415 traps.tryInstallTrapBreakpoints(context, stackBounds); 416 } 417 } 418 }); 464 419 break; 465 420 } -
trunk/Source/JavaScriptCore/runtime/VMTraps.h
r213930 r215620 43 43 enum class Error { 44 44 None, 45 LockUnavailable 45 LockUnavailable, 46 NotJITCode 46 47 }; 47 48 -
trunk/Source/JavaScriptCore/tools/SigillCrashAnalyzer.cpp
r213886 r215620 38 38 #endif 39 39 40 #if HAVE(SIGNAL_H) 41 #include <signal.h> 42 #endif 40 #include <wtf/threads/Signals.h> 43 41 44 42 namespace JSC { … … 142 140 }; 143 141 144 struct sigaction originalSigIllAction;145 146 static void handleCrash(int signalNumber, siginfo_t* info, void* uap)147 {148 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext);149 SigillCrashAnalyzer& analyzer = SigillCrashAnalyzer::instance();150 auto crashSource = analyzer.analyze(context);151 152 auto originalAction = originalSigIllAction.sa_sigaction;153 if (originalAction) {154 // It is always safe to just invoke the original handler using the sa_sigaction form155 // without checking for the SA_SIGINFO flag. If the original handler is of the156 // sa_handler form, it will just ignore the 2nd and 3rd arguments since sa_handler is a157 // subset of sa_sigaction. This is what the man pages says the OS does anyway.158 originalAction(signalNumber, info, uap);159 }160 161 if (crashSource == SigillCrashAnalyzer::CrashSource::JavaScriptCore) {162 // Restore the default handler so that we can get a core dump.163 struct sigaction defaultAction;164 defaultAction.sa_handler = SIG_DFL;165 sigfillset(&defaultAction.sa_mask);166 defaultAction.sa_flags = 0;167 sigaction(SIGILL, &defaultAction, nullptr);168 } else if (!originalAction) {169 // Pre-emptively restore the default handler but we may roll it back below.170 struct sigaction currentAction;171 struct sigaction defaultAction;172 defaultAction.sa_handler = SIG_DFL;173 sigfillset(&defaultAction.sa_mask);174 defaultAction.sa_flags = 0;175 sigaction(SIGILL, &defaultAction, ¤tAction);176 177 if (currentAction.sa_sigaction != handleCrash) {178 // This means that there's a client handler installed after us. This also means179 // that the client handler thinks it was able to recover from the SIGILL, and180 // did not uninstall itself. We can't argue with this because the crash isn't181 // known to be from a JavaScriptCore source. Hence, restore the client handler182 // and keep going.183 sigaction(SIGILL, ¤tAction, nullptr);184 }185 }186 }187 188 142 static void installCrashHandler() 189 143 { 190 144 #if CPU(X86_64) || CPU(ARM64) 191 struct sigaction action; 192 action.sa_sigaction = reinterpret_cast<void (*)(int, siginfo_t *, void *)>(handleCrash); 193 sigfillset(&action.sa_mask); 194 action.sa_flags = SA_SIGINFO; 195 sigaction(SIGILL, &action, &originalSigIllAction); 196 #else 197 UNUSED_PARAM(handleCrash); 145 installSignalHandler(Signal::Ill, [] (int, siginfo_t*, void* uap) { 146 SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext); 147 148 if (!isJITPC(context.machinePC)) 149 return SignalAction::NotHandled; 150 151 SigillCrashAnalyzer& analyzer = SigillCrashAnalyzer::instance(); 152 analyzer.analyze(context); 153 return SignalAction::NotHandled; 154 }); 198 155 #endif 199 156 } -
trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp
r215340 r215620 36 36 #include "WasmThunks.h" 37 37 38 #include <signal.h>39 38 #include <wtf/Lock.h> 40 39 #include <wtf/NeverDestroyed.h> 40 #include <wtf/threads/Signals.h> 41 41 42 42 namespace JSC { namespace Wasm { … … 51 51 #if ENABLE(WEBASSEMBLY_FAST_MEMORY) 52 52 53 static struct sigaction oldSigBusHandler;54 static struct sigaction oldSigSegvHandler;55 53 static bool fastHandlerInstalled { false }; 56 54 57 static void trapHandler(int signal, siginfo_t* sigInfo, void* ucontext)55 static SignalAction trapHandler(int, siginfo_t* sigInfo, void* ucontext) 58 56 { 59 57 mcontext_t& context = static_cast<ucontext_t*>(ucontext)->uc_mcontext; … … 64 62 // First we need to make sure we are in JIT code before we can aquire any locks. Otherwise, 65 63 // we might have crashed in code that is already holding one of the locks we want to aquire. 66 if (reinterpret_cast<void*>(startOfFixedExecutableMemoryPool) <= faultingInstruction 67 && faultingInstruction < reinterpret_cast<void*>(endOfFixedExecutableMemoryPool)) { 68 64 if (isJITPC(faultingInstruction)) { 69 65 bool faultedInActiveFastMemory = false; 70 66 { … … 90 86 MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(ExceptionType::OutOfBoundsMemoryAccess); 91 87 MachineContext::instructionPointer(context) = exceptionStub.code().executableAddress(); 92 return ;88 return SignalAction::Handled; 93 89 } 94 90 } 95 91 } 96 92 } 97 98 // Since we only use fast memory in processes we control, if we restore we will just fall back to the default handler. 99 if (signal == SIGBUS) 100 sigaction(signal, &oldSigBusHandler, nullptr); 101 else 102 sigaction(signal, &oldSigSegvHandler, nullptr); 93 return SignalAction::NotHandled; 103 94 } 104 95 … … 134 125 135 126 #if ENABLE(WEBASSEMBLY_FAST_MEMORY) 136 struct sigaction action; 127 installSignalHandler(Signal::Bus, [] (int signal, siginfo_t* sigInfo, void* ucontext) { 128 return trapHandler(signal, sigInfo, ucontext); 129 }); 137 130 138 action.sa_sigaction = trapHandler; 139 sigfillset(&action.sa_mask); 140 action.sa_flags = SA_SIGINFO; 141 142 // Installing signal handlers fails when 143 // 1. specificied sig is incorrect (invalid values or signal numbers which cannot be handled), or 144 // 2. second or third parameter points incorrect pointers. 145 // Thus, we must not fail in the following attempts. 146 int ret = 0; 147 ret = sigaction(SIGBUS, &action, &oldSigBusHandler); 148 RELEASE_ASSERT(!ret); 149 150 ret = sigaction(SIGSEGV, &action, &oldSigSegvHandler); 151 RELEASE_ASSERT(!ret); 131 installSignalHandler(Signal::SegV, [] (int signal, siginfo_t* sigInfo, void* ucontext) { 132 return trapHandler(signal, sigInfo, ucontext); 133 }); 152 134 153 135 codeLocations.construct(); -
trunk/Source/WTF/ChangeLog
r215614 r215620 1 2017-04-20 Keith Miller <keith_miller@apple.com> 2 3 Add signaling API 4 https://bugs.webkit.org/show_bug.cgi?id=170976 5 6 Reviewed by Filip Pizlo. 7 8 This patch adds a bunch of new functionality to WTF. First, it add 9 a new data structure of a lockless bag. The LocklessBag class can 10 be used as either a multi-writer multi-reader lockless bag or a 11 multi-writer single consumer lockless bag. 12 13 Next, this patch adds an abstraction around sigaction in WTF. 14 Basically, you can add a handler, which can be an arbitrary 15 lambda. Although it should still be safe for the signal you are 16 handling. the signal handler manager will then do all the 17 appropriate handling of chaining: 18 19 In the SIGUSR case we always forward the signal to any other 20 non-default handler installed before us. We need to do this, 21 otherwise, since it's not possible to tell if a SIGUSR was 22 intended exlusively for our handlers. Signal handlers don't record 23 how many times they were sent only that there is at least one 24 unhandled signal. 25 26 In the faulting cases we require that every handle be able to 27 recognise a fault they installed, vs crashes. If none of our 28 handlers claim to have handled the fault we will forward the 29 fault. If a handler was installed before the first fault handler 30 we simply call that handler and rely on them to take the 31 appropriate action. If no handler was installed before our first 32 handler we restore the default handler and allow the fault to 33 happen again. 34 35 Finally, this patch adds a signal based messaging system. This 36 system allows the user to run an arbitrary lambda from the SIGUSR2 37 signal handler of any target WTF::Thread. This is already in use 38 for the VMTraps API which allows us to kill rogue VMs by sending 39 the VM's running WTF::Thread a SIGUSR and requesting it jetison 40 all optimized code and throw an uncatchable exception from all 41 function entries/loop backedges. In the future, we will also use 42 this API for Wasm to reset the instruction caches in currently 43 executing Wasm threads. 44 45 * WTF.xcodeproj/project.pbxproj: 46 * wtf/Atomics.h: 47 (WTF::Atomic::Atomic): 48 * wtf/LocklessBag.h: Added. 49 (WTF::LocklessBag::LocklessBag): 50 (WTF::LocklessBag::add): 51 (WTF::LocklessBag::iterate): 52 (WTF::LocklessBag::consumeAll): 53 * wtf/ThreadMessage.cpp: Added. 54 (WTF::ThreadMessageData::ThreadMessageData): 55 (WTF::initializeThreadMessages): 56 (WTF::sendMessageScoped): 57 * wtf/ThreadMessage.h: Added. 58 (WTF::sendMessage): 59 * wtf/Threading.cpp: 60 (WTF::initializeThreading): 61 * wtf/Threading.h: 62 (WTF::Thread::threadMessages): 63 * wtf/ThreadingPthreads.cpp: 64 (WTF::Thread::currentMayBeNull): 65 (WTF::Thread::current): 66 (WTF::Thread::signal): 67 * wtf/threads/Signals.cpp: Added. 68 (WTF::jscSignalHandler): 69 (WTF::installSignalHandler): 70 * wtf/threads/Signals.h: Added. 71 (WTF::toSystemSignal): 72 (WTF::fromSystemSignal): 73 1 74 2017-04-21 Konstantin Tokarev <annulen@yandex.ru> 2 75 -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r215571 r215620 150 150 515F79561CFD3A6900CCED93 /* CrossThreadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 515F79551CFD3A6900CCED93 /* CrossThreadQueue.h */; }; 151 151 52183012C99E476A84EEBEA8 /* SymbolImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F72BBDB107FA424886178B9E /* SymbolImpl.cpp */; }; 152 5311BD531EA71CAD00525281 /* Signals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5311BD511EA71CAD00525281 /* Signals.cpp */; }; 153 5311BD561EA7E15A00525281 /* LocklessBag.h in Headers */ = {isa = PBXBuildFile; fileRef = 5311BD551EA7E15A00525281 /* LocklessBag.h */; }; 154 5311BD581EA7E1A100525281 /* Signals.h in Headers */ = {isa = PBXBuildFile; fileRef = 5311BD571EA7E1A100525281 /* Signals.h */; }; 155 5311BD5A1EA81A9600525281 /* ThreadMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 5311BD591EA81A9600525281 /* ThreadMessage.h */; }; 156 5311BD5C1EA822F900525281 /* ThreadMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5311BD5B1EA822F900525281 /* ThreadMessage.cpp */; }; 152 157 539EB0631D55284200C82EF7 /* LEBDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 539EB0621D55284200C82EF7 /* LEBDecoder.h */; }; 153 158 53EC253E1E95AD30000831B9 /* PriorityQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EC253C1E95AD30000831B9 /* PriorityQueue.h */; }; … … 549 554 515F794D1CFC9F4A00CCED93 /* CrossThreadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadTask.h; sourceTree = "<group>"; }; 550 555 515F79551CFD3A6900CCED93 /* CrossThreadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadQueue.h; sourceTree = "<group>"; }; 556 5311BD511EA71CAD00525281 /* Signals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Signals.cpp; sourceTree = "<group>"; }; 557 5311BD551EA7E15A00525281 /* LocklessBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocklessBag.h; sourceTree = "<group>"; }; 558 5311BD571EA7E1A100525281 /* Signals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Signals.h; sourceTree = "<group>"; }; 559 5311BD591EA81A9600525281 /* ThreadMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadMessage.h; sourceTree = "<group>"; }; 560 5311BD5B1EA822F900525281 /* ThreadMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadMessage.cpp; sourceTree = "<group>"; }; 551 561 539EB0621D55284200C82EF7 /* LEBDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LEBDecoder.h; sourceTree = "<group>"; }; 552 562 53EC253C1E95AD30000831B9 /* PriorityQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityQueue.h; sourceTree = "<group>"; }; … … 1065 1075 0F60F32E1DFCBD1B00416D6C /* LockedPrintStream.h */, 1066 1076 A8A472C3151A825A004123FF /* Locker.h */, 1077 5311BD551EA7E15A00525281 /* LocklessBag.h */, 1067 1078 513E170A1CD7D5BF00E3650B /* LoggingAccumulator.h */, 1068 1079 0F30BA8C1E78708E002CA847 /* LoggingHashID.h */, … … 1190 1201 E3200AB61E9A536D003B59D2 /* ThreadHolder.h */, 1191 1202 A8A47330151A825B004123FF /* ThreadHolderPthreads.cpp */, 1203 5311BD5B1EA822F900525281 /* ThreadMessage.cpp */, 1204 5311BD591EA81A9600525281 /* ThreadMessage.h */, 1192 1205 A8A47332151A825B004123FF /* Threading.cpp */, 1193 1206 A8A47333151A825B004123FF /* Threading.h */, … … 1317 1330 A8A4733A151A825B004123FF /* BinarySemaphore.cpp */, 1318 1331 A8A4733B151A825B004123FF /* BinarySemaphore.h */, 1332 5311BD511EA71CAD00525281 /* Signals.cpp */, 1333 5311BD571EA7E1A100525281 /* Signals.h */, 1319 1334 ); 1320 1335 path = threads; … … 1462 1477 0F8F2B91172E00FC007DBDA5 /* CompilationThread.h in Headers */, 1463 1478 A8A47398151A825B004123FF /* Compiler.h in Headers */, 1479 5311BD561EA7E15A00525281 /* LocklessBag.h in Headers */, 1464 1480 0FDB698E1B7C643A000C1078 /* Condition.h in Headers */, 1465 1481 A8A4748C151A8264004123FF /* config.h in Headers */, … … 1527 1543 26147B0A15DDCCDC00DDB907 /* IntegerToStringConversion.h in Headers */, 1528 1544 7CDD7FF8186D291E007433CD /* IteratorAdaptors.h in Headers */, 1545 5311BD581EA7E1A100525281 /* Signals.h in Headers */, 1529 1546 7CDD7FFA186D2A54007433CD /* IteratorRange.h in Headers */, 1530 1547 93AC91A818942FC400244939 /* LChar.h in Headers */, … … 1634 1651 A8A47441151A825B004123FF /* StringImpl.h in Headers */, 1635 1652 A8A47442151A825B004123FF /* StringOperators.h in Headers */, 1653 5311BD5A1EA81A9600525281 /* ThreadMessage.h in Headers */, 1636 1654 0FDDBFA81666DFA300C55FEF /* StringPrintStream.h in Headers */, 1637 1655 1A6EB1E0187D0BD30030126F /* StringView.h in Headers */, … … 1858 1876 A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */, 1859 1877 A5BA15FB182435A600A82E69 /* StringCF.cpp in Sources */, 1878 5311BD5C1EA822F900525281 /* ThreadMessage.cpp in Sources */, 1860 1879 A8A47440151A825B004123FF /* StringImpl.cpp in Sources */, 1861 1880 A5BA15FC182435A600A82E69 /* StringImplCF.cpp in Sources */, 1881 5311BD531EA71CAD00525281 /* Signals.cpp in Sources */, 1862 1882 A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */, 1863 1883 A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */, -
trunk/Source/WTF/wtf/Atomics.h
r215220 r215620 173 173 { 174 174 return transaction(func, std::memory_order_relaxed, abortLikelihood); 175 } 176 177 Atomic() = default; 178 constexpr Atomic(T initial) 179 : value(std::forward<T>(initial)) 180 { 175 181 } 176 182 -
trunk/Source/WTF/wtf/CMakeLists.txt
r215614 r215620 63 63 LockedPrintStream.h 64 64 Locker.h 65 LocklessBag.h 65 66 LoggingHashID.h 66 67 LoggingHashMap.h … … 131 132 SystemTracing.h 132 133 ThreadHolder.cpp 134 ThreadMessage.h 133 135 ThreadSafeRefCounted.h 134 136 ThreadSpecific.h … … 186 188 187 189 threads/BinarySemaphore.h 190 threads/Signals.h 188 191 189 192 unicode/CharacterNames.h … … 240 243 StackStats.cpp 241 244 StringPrintStream.cpp 245 ThreadMessage.cpp 242 246 Threading.cpp 243 247 TimeWithDynamicClockType.cpp … … 280 284 281 285 threads/BinarySemaphore.cpp 286 threads/Signals.cpp 282 287 283 288 unicode/UTF8.cpp -
trunk/Source/WTF/wtf/Threading.cpp
r215265 r215620 35 35 #include <wtf/RandomNumberSeed.h> 36 36 #include <wtf/ThreadHolder.h> 37 #include <wtf/ThreadMessage.h> 37 38 #include <wtf/WTFThreadData.h> 38 39 #include <wtf/text/StringView.h> … … 179 180 initializeDates(); 180 181 Thread::initializePlatformThreading(); 182 #if USE(PTHREADS) 183 initializeThreadMessages(); 184 #endif 181 185 }); 182 186 } -
trunk/Source/WTF/wtf/Threading.h
r215265 r215620 43 43 #include <wtf/Expected.h> 44 44 #include <wtf/Locker.h> 45 #include <wtf/LocklessBag.h> 45 46 #include <wtf/Noncopyable.h> 46 47 #include <wtf/PlatformRegisters.h> … … 57 58 namespace WTF { 58 59 60 class ThreadMessageData; 61 59 62 using ThreadIdentifier = uint32_t; 60 63 typedef void (*ThreadFunction)(void* argument); … … 76 79 // Returns Thread object. 77 80 WTF_EXPORT_PRIVATE static Thread& current(); 81 WTF_EXPORT_PRIVATE static Thread* currentMayBeNull(); 78 82 79 83 // Returns ThreadIdentifier directly. It is useful if the user only cares about identity … … 133 137 static void initializePlatformThreading(); 134 138 135 private: 139 #if USE(PTHREADS) 140 LocklessBag<ThreadMessageData*>& threadMessages() { return m_threadMessages; } 141 #endif 142 143 protected: 136 144 Thread(); 137 145 … … 178 186 #if USE(PTHREADS) 179 187 pthread_t m_handle; 188 189 LocklessBag<ThreadMessageData*> m_threadMessages; 180 190 #if OS(DARWIN) 181 191 mach_port_t m_platformThread; -
trunk/Source/WTF/wtf/ThreadingPthreads.cpp
r215270 r215620 265 265 } 266 266 267 Thread & Thread::current()267 Thread* Thread::currentMayBeNull() 268 268 { 269 269 ThreadHolder* data = ThreadHolder::current(); 270 270 if (data) 271 return data->thread(); 271 return &data->thread(); 272 return nullptr; 273 } 274 275 Thread& Thread::current() 276 { 277 if (Thread* current = currentMayBeNull()) 278 return *current; 272 279 273 280 // Not a WTF-created thread, ThreadIdentifier is not established yet. … … 287 294 { 288 295 std::unique_lock<std::mutex> locker(m_mutex); 296 if (hasExited()) 297 return false; 289 298 int errNo = pthread_kill(m_handle, signalNumber); 290 299 return !errNo; // A 0 errNo means success. -
trunk/Tools/ChangeLog
r215615 r215620 1 2017-04-20 Keith Miller <keith_miller@apple.com> 2 3 Add signaling API 4 https://bugs.webkit.org/show_bug.cgi?id=170976 5 6 Reviewed by Filip Pizlo. 7 8 Add tests for ThreadMessages. 9 10 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 11 * TestWebKitAPI/Tests/WTF/ThreadMessages.cpp: Added. 12 (runThreadMessageTest): 13 (TEST): 14 1 15 2017-04-20 Conrad Shultz <conrad_shultz@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r215587 r215620 175 175 52D673EE1AFB127300FA19FE /* WKPageCopySessionStateWithFiltering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52D673EC1AFB126800FA19FE /* WKPageCopySessionStateWithFiltering.cpp */; }; 176 176 52E5CE4914D21EAB003B2BD8 /* ParentFrame_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */; }; 177 5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5311BD5D1EA9490D00525281 /* ThreadMessages.cpp */; }; 177 178 531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531C1D8D1DF8EF72006E979F /* LEBDecoder.cpp */; }; 178 179 536770341CC8022800D425B1 /* WebScriptObjectDescription.mm in Sources */ = {isa = PBXBuildFile; fileRef = 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */; }; … … 1117 1118 52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame.cpp; sourceTree = "<group>"; }; 1118 1119 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame_Bundle.cpp; sourceTree = "<group>"; }; 1120 5311BD5D1EA9490D00525281 /* ThreadMessages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadMessages.cpp; sourceTree = "<group>"; }; 1119 1121 531C1D8D1DF8EF72006E979F /* LEBDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LEBDecoder.cpp; sourceTree = "<group>"; }; 1120 1122 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObjectDescription.mm; sourceTree = "<group>"; }; … … 2178 2180 5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */, 2179 2181 9329AA281DE3F81E003ABD07 /* TextBreakIterator.cpp */, 2182 5311BD5D1EA9490D00525281 /* ThreadMessages.cpp */, 2180 2183 0F2C20B71DCD544800542D9E /* Time.cpp */, 2181 2184 5C5E633D1D0B67940085A025 /* UniqueRef.cpp */, … … 2698 2701 531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */, 2699 2702 7C83DEE81D0A590C00FEBCF3 /* ListHashSet.cpp in Sources */, 2703 5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */, 2700 2704 7C83DF1D1D0A590C00FEBCF3 /* Lock.cpp in Sources */, 2701 2705 7C83DEED1D0A590C00FEBCF3 /* MathExtras.cpp in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.