<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    <condition_variable>
#include    <mutex>

#include    "../Characters/Format.h"
#include    "../Characters/String_Constant.h"
#include    "../Characters/StringBuilder.h"
#include    "../Characters/ToString.h"
#include    "../Containers/Mapping.h"
#include    "../Debug/BackTrace.h"
#include    "../Debug/Trace.h"
#include    "../Execution/Sleep.h"
#include    "../Execution/Synchronized.h"
#include    "../Execution/WaitableEvent.h"

#include    "Common.h"
#include    "Thread.h"

#if     qPlatform_POSIX
#include    "Platform/POSIX/SignalBlock.h"
#endif

#include    "SignalHandlers.h"


using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   Characters::String_Constant;
using   Containers::Mapping;
using   Containers::Set;
using   Time::DurationSecondsType;



// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1





// maybe useful while debugging signal code, but VERY unsafe
// and could easily be the source of bugs/deadlocks!
#ifndef qDoDbgTraceOnSignalHandlers_
#define qDoDbgTraceOnSignalHandlers_            0
#endif



// maybe useful while debugging signal code, but VERY unsafe
// and could easily be the source of bugs/deadlocks!
#ifndef qDoBacktraceOnFirstPassSignalHandler_
#define qDoBacktraceOnFirstPassSignalHandler_    0
#endif




// VERY UNSURE???
// Started experimenting(enabling) this with Stroika v2.0a135 -- LGP 2016-03-21
//#define qConditionVariableSetSafeFromSignalHandler_ 0
#ifndef qConditionVariableSetSafeFromSignalHandler_
#define qConditionVariableSetSafeFromSignalHandler_ 1
#endif





/*
 ********************************************************************************
 **************************** Configuration::DefaultNames ***********************
 ********************************************************************************
 */
namespace   Stroika {
    namespace   Foundation {
        namespace   Configuration {
            constexpr   EnumNames<Execution::SignalHandler::Type>    DefaultNames<Execution::SignalHandler::Type>::k;
        }
    }
}





/*
 ********************************************************************************
 *************************** Execution::SignalHandler ***************************
 ********************************************************************************
 */
Characters::String  SignalHandler::ToString () const
{
    Characters::StringBuilder sb;
    sb += L"{";
    sb += L"type: " + Characters::ToString (GetType ()) + L", ";
    // rough guess what to print...
    Function<void(SignalID)>::STDFUNCTION   stdFuncTarget = static_cast<Function<void(SignalID)>::STDFUNCTION> (fCall_);
    if (stdFuncTarget.target_type () == typeid (void(SignalID))) {
        sb += L"target: " + Characters::Format (L"%p", reinterpret_cast<const void*> (stdFuncTarget.target<void(SignalID)> ()));
    }
    else if (stdFuncTarget.target_type () == typeid (Function<void(SignalID)>)) {
        sb += L"target: " + Characters::Format (L"%p", reinterpret_cast<const void*> (stdFuncTarget.target<Function<void(SignalID)>> ()));
    }
    else {
        // type only/mainly interesting if not one of the above so we're printing nullptr
        sb += L"target-type: " + Characters::String::FromNarrowSDKString (stdFuncTarget.target_type ().name ());
    }
    sb += L"}";
    return sb.str ();
}






/*
 ********************************************************************************
 *********** Execution::SignalHandlerRegistry::SafeSignalsManager ***************
 ********************************************************************************
 */
DISABLE_COMPILER_MSC_WARNING_START(4351)
/*
 *  Design note:
 *      Though it would be logical to use a BlockQueue<> here to implement the signal forwarding,
 *      we cannot since that code allocates memory, and could deadlock.
 */
class   SignalHandlerRegistry::SafeSignalsManager::Rep_ {
public:
    Rep_ ()
    {
        fBlockingQueuePusherThread_ = Thread {
            [this] ()
            {<commit_msg>cleanup some signalhandler atomic useage with qStroika_FeatureSupported_Valgrind<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    <condition_variable>
#include    <mutex>

#include    "../Characters/Format.h"
#include    "../Characters/String_Constant.h"
#include    "../Characters/StringBuilder.h"
#include    "../Characters/ToString.h"
#include    "../Containers/Mapping.h"
#include    "../Debug/BackTrace.h"
#include    "../Debug/Trace.h"
#include    "../Execution/Sleep.h"
#include    "../Execution/Synchronized.h"
#include    "../Execution/WaitableEvent.h"

#include    "Common.h"
#include    "Thread.h"

#if     qPlatform_POSIX
#include    "Platform/POSIX/SignalBlock.h"
#endif

#include    "SignalHandlers.h"


using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Execution;
using   namespace   Stroika::Foundation::Memory;

using   Characters::String_Constant;
using   Containers::Mapping;
using   Containers::Set;
using   Time::DurationSecondsType;



// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1





// maybe useful while debugging signal code, but VERY unsafe
// and could easily be the source of bugs/deadlocks!
#ifndef qDoDbgTraceOnSignalHandlers_
#define qDoDbgTraceOnSignalHandlers_            0
#endif



// maybe useful while debugging signal code, but VERY unsafe
// and could easily be the source of bugs/deadlocks!
#ifndef qDoBacktraceOnFirstPassSignalHandler_
#define qDoBacktraceOnFirstPassSignalHandler_    0
#endif




// VERY UNSURE???
// Started experimenting(enabling) this with Stroika v2.0a135 -- LGP 2016-03-21
//#define qConditionVariableSetSafeFromSignalHandler_ 0
#ifndef qConditionVariableSetSafeFromSignalHandler_
#define qConditionVariableSetSafeFromSignalHandler_ 1
#endif





/*
 ********************************************************************************
 **************************** Configuration::DefaultNames ***********************
 ********************************************************************************
 */
namespace   Stroika {
    namespace   Foundation {
        namespace   Configuration {
            constexpr   EnumNames<Execution::SignalHandler::Type>    DefaultNames<Execution::SignalHandler::Type>::k;
        }
    }
}





/*
 ********************************************************************************
 *************************** Execution::SignalHandler ***************************
 ********************************************************************************
 */
Characters::String  SignalHandler::ToString () const
{
    Characters::StringBuilder sb;
    sb += L"{";
    sb += L"type: " + Characters::ToString (GetType ()) + L", ";
    // rough guess what to print...
    Function<void(SignalID)>::STDFUNCTION   stdFuncTarget = static_cast<Function<void(SignalID)>::STDFUNCTION> (fCall_);
    if (stdFuncTarget.target_type () == typeid (void(SignalID))) {
        sb += L"target: " + Characters::Format (L"%p", reinterpret_cast<const void*> (stdFuncTarget.target<void(SignalID)> ()));
    }
    else if (stdFuncTarget.target_type () == typeid (Function<void(SignalID)>)) {
        sb += L"target: " + Characters::Format (L"%p", reinterpret_cast<const void*> (stdFuncTarget.target<Function<void(SignalID)>> ()));
    }
    else {
        // type only/mainly interesting if not one of the above so we're printing nullptr
        sb += L"target-type: " + Characters::String::FromNarrowSDKString (stdFuncTarget.target_type ().name ());
    }
    sb += L"}";
    return sb.str ();
}






/*
 ********************************************************************************
 *********** Execution::SignalHandlerRegistry::SafeSignalsManager ***************
 ********************************************************************************
 */
DISABLE_COMPILER_MSC_WARNING_START(4351)
/*
 *  Design note:
 *      Though it would be logical to use a BlockQueue<> here to implement the signal forwarding,
 *      we cannot since that code allocates memory, and could deadlock.
 */
class   SignalHandlerRegistry::SafeSignalsManager::Rep_ {
public:
    Rep_ ()
    {
#if     qStroika_FeatureSupported_Valgrind
        VALGRIND_HG_DISABLE_CHECKING (&fIncomingSignalCounts_, sizeof(fIncomingSignalCounts_)); // helgrind doesnt seem to understand std::atomic
        VALGRIND_HG_DISABLE_CHECKING (&fLastSignalRecieved_, sizeof(fLastSignalRecieved_));     // helgrind doesnt seem to understand std::atomic
#endif
        fBlockingQueuePusherThread_ = Thread {
            [this] ()
            {
{'fraction_non_alphanumeric': 0.23965923102791167, 'fraction_numerical': 0.006725703396480215, 'mean_word_length': 4.407272727272727, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '373657', 'n_tokens_mistral': 2528, 'n_tokens_neox': 2387, 'n_words': 543}