Changeset 215620 in webkit


Ignore:
Timestamp:
Apr 21, 2017 11:35:42 AM (7 years ago)
Author:
keith_miller@apple.com
Message:

Add signaling API
https://bugs.webkit.org/show_bug.cgi?id=170976

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Update various uses of sigaction to use the new signaling API.
Also switch VMTraps to use the thread message system instead of
rolling it's own.

  • jit/ExecutableAllocator.h:

(JSC::isJITPC):

  • runtime/VMTraps.cpp:

(JSC::installSignalHandler):
(JSC::VMTraps::VMTraps):
(JSC::VMTraps::SignalSender::send):
(JSC::handleSigusr1): Deleted.
(JSC::handleSigtrap): Deleted.
(JSC::installSignalHandlers): Deleted.

  • runtime/VMTraps.h:
  • tools/SigillCrashAnalyzer.cpp:

(JSC::installCrashHandler):
(JSC::handleCrash): Deleted.

  • wasm/WasmFaultSignalHandler.cpp:

(JSC::Wasm::trapHandler):
(JSC::Wasm::enableFastMemory):

Source/WTF:

This patch adds a bunch of new functionality to WTF. First, it add
a new data structure of a lockless bag. The LocklessBag class can
be used as either a multi-writer multi-reader lockless bag or a
multi-writer single consumer lockless bag.

Next, this patch adds an abstraction around sigaction in WTF.
Basically, you can add a handler, which can be an arbitrary
lambda. Although it should still be safe for the signal you are
handling. the signal handler manager will then do all the
appropriate handling of chaining:

In the SIGUSR case we always forward the signal to any other
non-default handler installed before us. We need to do this,
otherwise, since it's not possible to tell if a SIGUSR was
intended exlusively for our handlers. Signal handlers don't record
how many times they were sent only that there is at least one
unhandled signal.

In the faulting cases we require that every handle be able to
recognise a fault they installed, vs crashes. If none of our
handlers claim to have handled the fault we will forward the
fault. If a handler was installed before the first fault handler
we simply call that handler and rely on them to take the
appropriate action. If no handler was installed before our first
handler we restore the default handler and allow the fault to
happen again.

Finally, this patch adds a signal based messaging system. This
system allows the user to run an arbitrary lambda from the SIGUSR2
signal handler of any target WTF::Thread. This is already in use
for the VMTraps API which allows us to kill rogue VMs by sending
the VM's running WTF::Thread a SIGUSR and requesting it jetison
all optimized code and throw an uncatchable exception from all
function entries/loop backedges. In the future, we will also use
this API for Wasm to reset the instruction caches in currently
executing Wasm threads.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/Atomics.h:

(WTF::Atomic::Atomic):

  • wtf/LocklessBag.h: Added.

(WTF::LocklessBag::LocklessBag):
(WTF::LocklessBag::add):
(WTF::LocklessBag::iterate):
(WTF::LocklessBag::consumeAll):

  • wtf/ThreadMessage.cpp: Added.

(WTF::ThreadMessageData::ThreadMessageData):
(WTF::initializeThreadMessages):
(WTF::sendMessageScoped):

  • wtf/ThreadMessage.h: Added.

(WTF::sendMessage):

  • wtf/Threading.cpp:

(WTF::initializeThreading):

  • wtf/Threading.h:

(WTF::Thread::threadMessages):

  • wtf/ThreadingPthreads.cpp:

(WTF::Thread::currentMayBeNull):
(WTF::Thread::current):
(WTF::Thread::signal):

  • wtf/threads/Signals.cpp: Added.

(WTF::jscSignalHandler):
(WTF::installSignalHandler):

  • wtf/threads/Signals.h: Added.

(WTF::toSystemSignal):
(WTF::fromSystemSignal):

Tools:

Add tests for ThreadMessages.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WTF/ThreadMessages.cpp: Added.

(runThreadMessageTest):
(TEST):

Location:
trunk
Files:
6 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r215618 r215620  
     12017-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
    1292017-04-21  Michael Saboff  <msaboff@apple.com>
    230
  • trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h

    r214571 r215620  
    8282extern JS_EXPORTDATA uintptr_t endOfFixedExecutableMemoryPool;
    8383
     84inline bool isJITPC(void* pc)
     85{
     86    return reinterpret_cast<void*>(startOfFixedExecutableMemoryPool) <= pc
     87        && pc < reinterpret_cast<void*>(endOfFixedExecutableMemoryPool);
     88}
     89
    8490typedef void (*JITWriteSeparateHeapsFunction)(off_t, const void*, size_t);
    8591extern JS_EXPORTDATA JITWriteSeparateHeapsFunction jitWriteSeparateHeapsFunction;
  • trunk/Source/JavaScriptCore/runtime/VMTraps.cpp

    r215522 r215620  
    4141#include "Watchdog.h"
    4242#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>
    4745
    4846namespace JSC {
     
    5452
    5553#if ENABLE(SIGNAL_BASED_VM_TRAPS)
    56 
    57 struct sigaction originalSigusr1Action;
    58 struct sigaction originalSigtrapAction;
    5954
    6055struct SignalContext {
     
    133128}
    134129
    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) {
     130static 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
    140144        VM* vm = activeVMAndStackBounds.value().vm;
    141145        if (vm) {
    142             StackBounds stackBounds = activeVMAndStackBounds.value().stackBounds;
    143146            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, &currentAction);
    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, &currentAction, 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    });
    216159}
    217160
     
    401344        static std::once_flag once;
    402345        std::call_once(once, [] {
    403             installSignalHandlers();
     346            installSignalHandler();
    404347        });
    405348    }
     
    461404            auto optionalOwnerThread = vm.ownerThread();
    462405            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                });
    464419                break;
    465420            }
  • trunk/Source/JavaScriptCore/runtime/VMTraps.h

    r213930 r215620  
    4343    enum class Error {
    4444        None,
    45         LockUnavailable
     45        LockUnavailable,
     46        NotJITCode
    4647    };
    4748
  • trunk/Source/JavaScriptCore/tools/SigillCrashAnalyzer.cpp

    r213886 r215620  
    3838#endif
    3939
    40 #if HAVE(SIGNAL_H)
    41 #include <signal.h>
    42 #endif
     40#include <wtf/threads/Signals.h>
    4341
    4442namespace JSC {
     
    142140};
    143141
    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 form
    155         // without checking for the SA_SIGINFO flag. If the original handler is of the
    156         // sa_handler form, it will just ignore the 2nd and 3rd arguments since sa_handler is a
    157         // 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, &currentAction);
    176 
    177         if (currentAction.sa_sigaction != handleCrash) {
    178             // This means that there's a client handler installed after us. This also means
    179             // that the client handler thinks it was able to recover from the SIGILL, and
    180             // did not uninstall itself. We can't argue with this because the crash isn't
    181             // known to be from a JavaScriptCore source. Hence, restore the client handler
    182             // and keep going.
    183             sigaction(SIGILL, &currentAction, nullptr);
    184         }
    185     }
    186 }
    187 
    188142static void installCrashHandler()
    189143{
    190144#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    });
    198155#endif
    199156}
  • trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp

    r215340 r215620  
    3636#include "WasmThunks.h"
    3737
    38 #include <signal.h>
    3938#include <wtf/Lock.h>
    4039#include <wtf/NeverDestroyed.h>
     40#include <wtf/threads/Signals.h>
    4141
    4242namespace JSC { namespace Wasm {
     
    5151#if ENABLE(WEBASSEMBLY_FAST_MEMORY)
    5252
    53 static struct sigaction oldSigBusHandler;
    54 static struct sigaction oldSigSegvHandler;
    5553static bool fastHandlerInstalled { false };
    5654
    57 static void trapHandler(int signal, siginfo_t* sigInfo, void* ucontext)
     55static SignalAction trapHandler(int, siginfo_t* sigInfo, void* ucontext)
    5856{
    5957    mcontext_t& context = static_cast<ucontext_t*>(ucontext)->uc_mcontext;
     
    6462    // First we need to make sure we are in JIT code before we can aquire any locks. Otherwise,
    6563    // 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)) {
    6965        bool faultedInActiveFastMemory = false;
    7066        {
     
    9086                    MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(ExceptionType::OutOfBoundsMemoryAccess);
    9187                    MachineContext::instructionPointer(context) = exceptionStub.code().executableAddress();
    92                     return;
     88                    return SignalAction::Handled;
    9389                }
    9490            }
    9591        }
    9692    }
    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;
    10394}
    10495
     
    134125
    135126#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        });
    137130
    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        });
    152134
    153135        codeLocations.construct();
  • trunk/Source/WTF/ChangeLog

    r215614 r215620  
     12017-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
    1742017-04-21  Konstantin Tokarev  <annulen@yandex.ru>
    275
  • trunk/Source/WTF/WTF.xcodeproj/project.pbxproj

    r215571 r215620  
    150150                515F79561CFD3A6900CCED93 /* CrossThreadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 515F79551CFD3A6900CCED93 /* CrossThreadQueue.h */; };
    151151                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 */; };
    152157                539EB0631D55284200C82EF7 /* LEBDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 539EB0621D55284200C82EF7 /* LEBDecoder.h */; };
    153158                53EC253E1E95AD30000831B9 /* PriorityQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EC253C1E95AD30000831B9 /* PriorityQueue.h */; };
     
    549554                515F794D1CFC9F4A00CCED93 /* CrossThreadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadTask.h; sourceTree = "<group>"; };
    550555                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>"; };
    551561                539EB0621D55284200C82EF7 /* LEBDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LEBDecoder.h; sourceTree = "<group>"; };
    552562                53EC253C1E95AD30000831B9 /* PriorityQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityQueue.h; sourceTree = "<group>"; };
     
    10651075                                0F60F32E1DFCBD1B00416D6C /* LockedPrintStream.h */,
    10661076                                A8A472C3151A825A004123FF /* Locker.h */,
     1077                                5311BD551EA7E15A00525281 /* LocklessBag.h */,
    10671078                                513E170A1CD7D5BF00E3650B /* LoggingAccumulator.h */,
    10681079                                0F30BA8C1E78708E002CA847 /* LoggingHashID.h */,
     
    11901201                                E3200AB61E9A536D003B59D2 /* ThreadHolder.h */,
    11911202                                A8A47330151A825B004123FF /* ThreadHolderPthreads.cpp */,
     1203                                5311BD5B1EA822F900525281 /* ThreadMessage.cpp */,
     1204                                5311BD591EA81A9600525281 /* ThreadMessage.h */,
    11921205                                A8A47332151A825B004123FF /* Threading.cpp */,
    11931206                                A8A47333151A825B004123FF /* Threading.h */,
     
    13171330                                A8A4733A151A825B004123FF /* BinarySemaphore.cpp */,
    13181331                                A8A4733B151A825B004123FF /* BinarySemaphore.h */,
     1332                                5311BD511EA71CAD00525281 /* Signals.cpp */,
     1333                                5311BD571EA7E1A100525281 /* Signals.h */,
    13191334                        );
    13201335                        path = threads;
     
    14621477                                0F8F2B91172E00FC007DBDA5 /* CompilationThread.h in Headers */,
    14631478                                A8A47398151A825B004123FF /* Compiler.h in Headers */,
     1479                                5311BD561EA7E15A00525281 /* LocklessBag.h in Headers */,
    14641480                                0FDB698E1B7C643A000C1078 /* Condition.h in Headers */,
    14651481                                A8A4748C151A8264004123FF /* config.h in Headers */,
     
    15271543                                26147B0A15DDCCDC00DDB907 /* IntegerToStringConversion.h in Headers */,
    15281544                                7CDD7FF8186D291E007433CD /* IteratorAdaptors.h in Headers */,
     1545                                5311BD581EA7E1A100525281 /* Signals.h in Headers */,
    15291546                                7CDD7FFA186D2A54007433CD /* IteratorRange.h in Headers */,
    15301547                                93AC91A818942FC400244939 /* LChar.h in Headers */,
     
    16341651                                A8A47441151A825B004123FF /* StringImpl.h in Headers */,
    16351652                                A8A47442151A825B004123FF /* StringOperators.h in Headers */,
     1653                                5311BD5A1EA81A9600525281 /* ThreadMessage.h in Headers */,
    16361654                                0FDDBFA81666DFA300C55FEF /* StringPrintStream.h in Headers */,
    16371655                                1A6EB1E0187D0BD30030126F /* StringView.h in Headers */,
     
    18581876                                A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */,
    18591877                                A5BA15FB182435A600A82E69 /* StringCF.cpp in Sources */,
     1878                                5311BD5C1EA822F900525281 /* ThreadMessage.cpp in Sources */,
    18601879                                A8A47440151A825B004123FF /* StringImpl.cpp in Sources */,
    18611880                                A5BA15FC182435A600A82E69 /* StringImplCF.cpp in Sources */,
     1881                                5311BD531EA71CAD00525281 /* Signals.cpp in Sources */,
    18621882                                A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */,
    18631883                                A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */,
  • trunk/Source/WTF/wtf/Atomics.h

    r215220 r215620  
    173173    {
    174174        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    {
    175181    }
    176182
  • trunk/Source/WTF/wtf/CMakeLists.txt

    r215614 r215620  
    6363    LockedPrintStream.h
    6464    Locker.h
     65    LocklessBag.h
    6566    LoggingHashID.h
    6667    LoggingHashMap.h
     
    131132    SystemTracing.h
    132133    ThreadHolder.cpp
     134    ThreadMessage.h
    133135    ThreadSafeRefCounted.h
    134136    ThreadSpecific.h
     
    186188
    187189    threads/BinarySemaphore.h
     190    threads/Signals.h
    188191
    189192    unicode/CharacterNames.h
     
    240243    StackStats.cpp
    241244    StringPrintStream.cpp
     245    ThreadMessage.cpp
    242246    Threading.cpp
    243247    TimeWithDynamicClockType.cpp
     
    280284
    281285    threads/BinarySemaphore.cpp
     286    threads/Signals.cpp
    282287
    283288    unicode/UTF8.cpp
  • trunk/Source/WTF/wtf/Threading.cpp

    r215265 r215620  
    3535#include <wtf/RandomNumberSeed.h>
    3636#include <wtf/ThreadHolder.h>
     37#include <wtf/ThreadMessage.h>
    3738#include <wtf/WTFThreadData.h>
    3839#include <wtf/text/StringView.h>
     
    179180        initializeDates();
    180181        Thread::initializePlatformThreading();
     182#if USE(PTHREADS)
     183        initializeThreadMessages();
     184#endif
    181185    });
    182186}
  • trunk/Source/WTF/wtf/Threading.h

    r215265 r215620  
    4343#include <wtf/Expected.h>
    4444#include <wtf/Locker.h>
     45#include <wtf/LocklessBag.h>
    4546#include <wtf/Noncopyable.h>
    4647#include <wtf/PlatformRegisters.h>
     
    5758namespace WTF {
    5859
     60class ThreadMessageData;
     61
    5962using ThreadIdentifier = uint32_t;
    6063typedef void (*ThreadFunction)(void* argument);
     
    7679    // Returns Thread object.
    7780    WTF_EXPORT_PRIVATE static Thread& current();
     81    WTF_EXPORT_PRIVATE static Thread* currentMayBeNull();
    7882
    7983    // Returns ThreadIdentifier directly. It is useful if the user only cares about identity
     
    133137    static void initializePlatformThreading();
    134138
    135 private:
     139#if USE(PTHREADS)
     140    LocklessBag<ThreadMessageData*>& threadMessages() { return m_threadMessages; }
     141#endif
     142
     143protected:
    136144    Thread();
    137145
     
    178186#if USE(PTHREADS)
    179187    pthread_t m_handle;
     188
     189    LocklessBag<ThreadMessageData*> m_threadMessages;
    180190#if OS(DARWIN)
    181191    mach_port_t m_platformThread;
  • trunk/Source/WTF/wtf/ThreadingPthreads.cpp

    r215270 r215620  
    265265}
    266266
    267 Thread& Thread::current()
     267Thread* Thread::currentMayBeNull()
    268268{
    269269    ThreadHolder* data = ThreadHolder::current();
    270270    if (data)
    271         return data->thread();
     271        return &data->thread();
     272    return nullptr;
     273}
     274
     275Thread& Thread::current()
     276{
     277    if (Thread* current = currentMayBeNull())
     278        return *current;
    272279
    273280    // Not a WTF-created thread, ThreadIdentifier is not established yet.
     
    287294{
    288295    std::unique_lock<std::mutex> locker(m_mutex);
     296    if (hasExited())
     297        return false;
    289298    int errNo = pthread_kill(m_handle, signalNumber);
    290299    return !errNo; // A 0 errNo means success.
  • trunk/Tools/ChangeLog

    r215615 r215620  
     12017-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
    1152017-04-20  Conrad Shultz  <conrad_shultz@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r215587 r215620  
    175175                52D673EE1AFB127300FA19FE /* WKPageCopySessionStateWithFiltering.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52D673EC1AFB126800FA19FE /* WKPageCopySessionStateWithFiltering.cpp */; };
    176176                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 */; };
    177178                531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531C1D8D1DF8EF72006E979F /* LEBDecoder.cpp */; };
    178179                536770341CC8022800D425B1 /* WebScriptObjectDescription.mm in Sources */ = {isa = PBXBuildFile; fileRef = 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */; };
     
    11171118                52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame.cpp; sourceTree = "<group>"; };
    11181119                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>"; };
    11191121                531C1D8D1DF8EF72006E979F /* LEBDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LEBDecoder.cpp; sourceTree = "<group>"; };
    11201122                536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObjectDescription.mm; sourceTree = "<group>"; };
     
    21782180                                5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */,
    21792181                                9329AA281DE3F81E003ABD07 /* TextBreakIterator.cpp */,
     2182                                5311BD5D1EA9490D00525281 /* ThreadMessages.cpp */,
    21802183                                0F2C20B71DCD544800542D9E /* Time.cpp */,
    21812184                                5C5E633D1D0B67940085A025 /* UniqueRef.cpp */,
     
    26982701                                531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */,
    26992702                                7C83DEE81D0A590C00FEBCF3 /* ListHashSet.cpp in Sources */,
     2703                                5311BD5E1EA9490E00525281 /* ThreadMessages.cpp in Sources */,
    27002704                                7C83DF1D1D0A590C00FEBCF3 /* Lock.cpp in Sources */,
    27012705                                7C83DEED1D0A590C00FEBCF3 /* MathExtras.cpp in Sources */,
Note: See TracChangeset for help on using the changeset viewer.