Set thread names for additional threads in system. (#1103)
* Set thread names for additional threads in system. * Fix linting errors. * Add additional thread names for Mac and Windows. * Use const reference for SetThreadName. * Fix more linting errors. * Fix PortAudio compiler error. * Add missed thread names. * VOX tone atomic doesn't need seq_cst. * Only wake up non-RT playback thread if FIFO is less than half full. * Only wake up the TX/RX threads after all audio received. * Optimized RADE is only for radio integrations. * Add missed changes. * Need to build integ in order for lint to work. * remove invalid target. * Fix additional Linux compiler failures from previous changes. * Additional compiler fixes. * Exclude duplicate tests. * Fix macOS CI failure.pull/1094/head
parent
e5705cc77e
commit
539bd55969
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
cd build_linux
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
|
||||
# Partially build so we have all required .h and .c/.cpp files
|
||||
make -j$(nproc) build_mimalloc build_rade build_codec2
|
||||
make -j$(nproc) build_mimalloc build_rade build_codec2 build_rade_integ
|
||||
|
||||
- name: Run clang-tidy on codebase
|
||||
working-directory: ${{github.workspace}}/build_linux
|
||||
|
|
@ -340,6 +340,22 @@ jobs:
|
|||
native-audio: USE_NATIVE_AUDIO=0
|
||||
- sanitizer: WITH_UBSAN=1
|
||||
native-audio: USE_NATIVE_AUDIO=0
|
||||
- os: ubuntu-22.04
|
||||
sanitizer: WITH_RTSAN=1
|
||||
- os: ubuntu-22.04
|
||||
sanitizer: WITH_TSAN=1
|
||||
- os: ubuntu-22.04
|
||||
sanitizer: WITH_ASAN=1
|
||||
- os: ubuntu-22.04
|
||||
sanitizer: WITH_UBSAN=1
|
||||
- os: ubuntu-22.04-arm
|
||||
sanitizer: WITH_RTSAN=1
|
||||
- os: ubuntu-22.04-arm
|
||||
sanitizer: WITH_TSAN=1
|
||||
- os: ubuntu-22.04-arm
|
||||
sanitizer: WITH_ASAN=1
|
||||
- os: ubuntu-22.04-arm
|
||||
sanitizer: WITH_UBSAN=1
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: lint
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
cd build_osx
|
||||
CC=clang CXX=clang++ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
|
||||
# Partially build so we have all required .h and .c/.cpp files
|
||||
make -j$(nproc) build_mimalloc build_rade build_codec2
|
||||
make -j$(nproc) build_mimalloc build_rade build_codec2 build_rade_integ
|
||||
|
||||
- name: Run clang-tidy on codebase
|
||||
working-directory: ${{github.workspace}}/build_osx
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
|
|||
# Build RADE.
|
||||
# (TBD - allow override with own build, similar to Codec2)
|
||||
include(cmake/BuildRADE.cmake)
|
||||
include(cmake/BuildRADEForIntegrations.cmake)
|
||||
|
||||
#
|
||||
# Build codec2
|
||||
|
|
|
|||
|
|
@ -6,14 +6,17 @@ if [[ "${TARGET}" == "all" ]]; then
|
|||
export APPNAME="FreeDV"
|
||||
export APPEXEC=../build_linux/src/freedv
|
||||
export APPRUN="AppRun.sh"
|
||||
export RADE_SRC="rade_src"
|
||||
elif [[ "${TARGET}" == "freedv-flex" ]]; then
|
||||
export APPNAME="FreeDV-FlexRadio"
|
||||
export APPEXEC=../build_linux/src/integrations/flex/freedv-flex
|
||||
export APPRUN="AppRun-FlexRadio.sh"
|
||||
export RADE_SRC="rade_integ_src"
|
||||
elif [[ "${TARGET}" == "freedv-ka9q" ]]; then
|
||||
export APPNAME="FreeDV-KA9Q"
|
||||
export APPEXEC=../build_linux/src/integrations/ka9q/freedv-ka9q
|
||||
export APPRUN="AppRun-KA9Q.sh"
|
||||
export RADE_SRC="rade_integ_src"
|
||||
fi
|
||||
|
||||
DESKTOP_FILE="$APPNAME.desktop"
|
||||
|
|
@ -81,9 +84,9 @@ cd -
|
|||
echo "Copying rade_src..."
|
||||
# ls freedv-rade/freedv-gui/build_linux/rade_src/model
|
||||
# model05/ model17/ model18/ model19/ model19_check3/ model_bbfm_01/
|
||||
cp -r "$BUILDDIR/build_linux/rade_src" "$APPDIR/."
|
||||
cp -r "$BUILDDIR/build_linux/$RADE_SRC" "$APPDIR/."
|
||||
cd "$APPDIR/usr/bin"
|
||||
ln -s "../../rade_src/model19_check3" "model19_check3"
|
||||
ln -s "../../$RADE_SRC/model19_check3" "model19_check3"
|
||||
cd -
|
||||
|
||||
# Create the output
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ ExternalProject_Add(build_rade
|
|||
SOURCE_DIR rade_src
|
||||
BINARY_DIR rade_build
|
||||
GIT_REPOSITORY https://github.com/drowe67/radae.git
|
||||
GIT_TAG ms-disable-python-gc
|
||||
GIT_TAG main
|
||||
CMAKE_ARGS ${RADE_CMAKE_ARGS}
|
||||
#CMAKE_CACHE_ARGS -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
|
||||
INSTALL_COMMAND ""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
if(CMAKE_CROSSCOMPILING)
|
||||
set(RADE_CMAKE_ARGS ${RADE_CMAKE_ARGS} -DPython3_ROOT_DIR=${Python3_ROOT_DIR} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
|
||||
elseif(APPLE)
|
||||
set(RADE_CMAKE_ARGS ${RADE_CMAKE_ARGS} -DPython3_ROOT_DIR=${Python3_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
if(BUILD_OSX_UNIVERSAL)
|
||||
set(RADE_CMAKE_ARGS ${RADE_CMAKE_ARGS} -DBUILD_OSX_UNIVERSAL=1)
|
||||
endif(BUILD_OSX_UNIVERSAL)
|
||||
|
||||
set(RADE_CMAKE_ARGS ${RADE_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DOPUS_URL=https://github.com/xiph/opus/archive/940d4e5af64351ca8ba8390df3f555484c567fbb.zip)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(build_rade_integ
|
||||
SOURCE_DIR rade_integ_src
|
||||
BINARY_DIR rade_integ_build
|
||||
GIT_REPOSITORY https://github.com/drowe67/radae.git
|
||||
GIT_TAG ms-disable-python-gc
|
||||
CMAKE_ARGS ${RADE_CMAKE_ARGS}
|
||||
#CMAKE_CACHE_ARGS -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
|
||||
INSTALL_COMMAND ""
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
)
|
||||
|
||||
ExternalProject_Get_Property(build_rade_integ BINARY_DIR)
|
||||
ExternalProject_Get_Property(build_rade_integ SOURCE_DIR)
|
||||
add_library(rade_integ SHARED IMPORTED)
|
||||
add_dependencies(rade_integ build_rade_integ)
|
||||
include_directories(${SOURCE_DIR}/src)
|
||||
|
||||
set_target_properties(rade_integ PROPERTIES
|
||||
IMPORTED_LOCATION "${BINARY_DIR}/src/librade${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
||||
IMPORTED_IMPLIB "${BINARY_DIR}/src/librade${CMAKE_IMPORT_LIBRARY_SUFFIX}"
|
||||
)
|
||||
list(APPEND FREEDV_PACKAGE_SEARCH_PATHS ${BINARY_DIR}/src)
|
||||
set(rade_integ_BINARY_DIR ${BINARY_DIR})
|
||||
|
||||
add_library(opus_integ STATIC IMPORTED)
|
||||
add_dependencies(opus_integ build_rade_integ)
|
||||
set(FARGAN_INTEG_ARM_CONFIG_H_FILE "${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/config.h")
|
||||
set(FARGAN_INTEG_X86_CONFIG_H_FILE "${BINARY_DIR}/build_opus_x86-prefix/src/build_opus_x86/config.h")
|
||||
|
||||
if(APPLE AND BUILD_OSX_UNIVERSAL)
|
||||
include_directories(
|
||||
${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm
|
||||
${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/dnn
|
||||
${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/celt
|
||||
${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/silk
|
||||
${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/include)
|
||||
set_target_properties(opus_integ PROPERTIES
|
||||
IMPORTED_LOCATION "${BINARY_DIR}/libopus${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
)
|
||||
|
||||
set(FARGAN_INTEG_CONFIG_H_FILE "${BINARY_DIR}/build_opus_arm-prefix/src/build_opus_arm/config.h")
|
||||
else(APPLE AND BUILD_OSX_UNIVERSAL)
|
||||
include_directories(
|
||||
${BINARY_DIR}/build_opus-prefix/src/build_opus
|
||||
${BINARY_DIR}/build_opus-prefix/src/build_opus/dnn
|
||||
${BINARY_DIR}/build_opus-prefix/src/build_opus/celt
|
||||
${BINARY_DIR}/build_opus-prefix/src/build_opus/silk
|
||||
${BINARY_DIR}/build_opus-prefix/src/build_opus/include)
|
||||
set_target_properties(opus_integ PROPERTIES
|
||||
IMPORTED_LOCATION "${BINARY_DIR}/build_opus-prefix/src/build_opus/.libs/libopus${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
)
|
||||
set(FARGAN_INTEG_CONFIG_H_FILE "${BINARY_DIR}/build_opus-prefix/src/build_opus/config.h")
|
||||
set(FARGAN_INTEG_ARM_CONFIG_H_FILE "${FARGAN_CONFIG_H_FILE}")
|
||||
set(FARGAN_INTEG_X86_CONFIG_H_FILE "${FARGAN_CONFIG_H_FILE}")
|
||||
endif(APPLE AND BUILD_OSX_UNIVERSAL)
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/fargan_config_integ.h.in" "${CMAKE_CURRENT_BINARY_DIR}/fargan_config_integ.h")
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef FARGAN_CONFIG_H
|
||||
#define FARGAN_CONFIG_H
|
||||
|
||||
// Include Opus config.h to suppress warnings
|
||||
#ifdef __APPLE__
|
||||
#ifdef __aarch64__
|
||||
#include "@FARGAN_INTEG_ARM_CONFIG_H_FILE@"
|
||||
#else
|
||||
#include "@FARGAN_INTEG_X86_CONFIG_H_FILE@"
|
||||
#endif // __aarch64__
|
||||
#else
|
||||
#include "@FARGAN_INTEG_CONFIG_H_FILE@"
|
||||
#endif // __APPLE__
|
||||
|
||||
#endif // FARGAN_CONFIG_H
|
||||
|
|
@ -114,7 +114,8 @@ static OSStatus SetCurrentIOBufferFrameSize(AudioObjectID inDeviceID,
|
|||
}
|
||||
|
||||
MacAudioDevice::MacAudioDevice(MacAudioEngine* parent, std::string deviceName, int coreAudioId, IAudioEngine::AudioDirection direction, int numChannels, int sampleRate)
|
||||
: coreAudioId_(coreAudioId)
|
||||
: ThreadedObject("MacDevice")
|
||||
, coreAudioId_(coreAudioId)
|
||||
, direction_(direction)
|
||||
, numChannels_(numChannels)
|
||||
, sampleRate_(sampleRate)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
class PortAudioInterface : public ThreadedObject
|
||||
{
|
||||
public:
|
||||
PortAudioInterface() = default;
|
||||
PortAudioInterface()
|
||||
: ThreadedObject("PortAudio") {}
|
||||
virtual ~PortAudioInterface() = default;
|
||||
|
||||
std::future<PaError> Initialize();
|
||||
|
|
@ -55,4 +56,4 @@ public:
|
|||
std::future<const PaStreamInfo*> GetStreamInfo(PaStream* stream);
|
||||
};
|
||||
|
||||
#endif // PORT_AUDIO_INTERFACE_H
|
||||
#endif // PORT_AUDIO_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -365,16 +365,16 @@ void PulseAudioDevice::StreamReadCallback_(pa_stream *s, size_t length, void *us
|
|||
pa_stream_peek(s, &data, &length);
|
||||
if (!data || length == 0)
|
||||
{
|
||||
return; //break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (thisObj->onAudioDataFunction)
|
||||
{
|
||||
thisObj->onAudioDataFunction(*thisObj, const_cast<void*>(data), length / thisObj->getNumChannels() / sizeof(short), thisObj->onAudioDataState);
|
||||
}
|
||||
sem_post(&thisObj->sem_);
|
||||
pa_stream_drop(s);
|
||||
} while (pa_stream_readable_size(s) > 0);
|
||||
sem_post(&thisObj->sem_);
|
||||
}
|
||||
|
||||
void PulseAudioDevice::StreamWriteCallback_(pa_stream *s, size_t length, void *userdata)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include <map>
|
||||
#include "../util/logging/ulog.h"
|
||||
|
||||
#if defined(USE_RTKIT)
|
||||
#include "rtkit.h"
|
||||
#endif // defined(USE_RTKIT)
|
||||
|
||||
PulseAudioEngine::PulseAudioEngine()
|
||||
: initialized_(false)
|
||||
{
|
||||
|
|
@ -73,6 +77,51 @@ void PulseAudioEngine::start()
|
|||
|
||||
pa_context_set_state_callback(context_, [](pa_context*, void* mainloop) {
|
||||
pa_threaded_mainloop *threadedML = static_cast<pa_threaded_mainloop *>(mainloop);
|
||||
|
||||
#if defined(USE_RTKIT)
|
||||
if (pa_threaded_mainloop_in_thread(threadedML))
|
||||
{
|
||||
DBusError error;
|
||||
DBusConnection* bus = nullptr;
|
||||
int result = 0;
|
||||
|
||||
dbus_error_init(&error);
|
||||
if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error)))
|
||||
{
|
||||
log_warn("Could not connect to system bus: %s", error.message);
|
||||
}
|
||||
else
|
||||
{
|
||||
int minNiceLevel = 0;
|
||||
constexpr int ERROR_BUFFER_SIZE = 1024;
|
||||
char tmpBuf[ERROR_BUFFER_SIZE];
|
||||
if ((result = rtkit_get_min_nice_level(bus, &minNiceLevel)) < 0)
|
||||
{
|
||||
#if (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE
|
||||
strerror_r(-result, tmpBuf, ERROR_BUFFER_SIZE);
|
||||
log_warn("rtkit could not get minimum nice level: %s", tmpBuf);
|
||||
#else
|
||||
log_warn("rtkit could not get minimum nice level: %s", strerror_r(-result, tmpBuf, ERROR_BUFFER_SIZE));
|
||||
#endif // (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE
|
||||
}
|
||||
else if ((result = rtkit_make_high_priority(bus, 0, minNiceLevel)) < 0)
|
||||
{
|
||||
#if (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE
|
||||
strerror_r(-result, tmpBuf, ERROR_BUFFER_SIZE);
|
||||
log_warn("rtkit could not make high priority: %s", tmpBuf);
|
||||
#else
|
||||
log_warn("rtkit could not make high priority: %s", strerror_r(-result, tmpBuf, ERROR_BUFFER_SIZE));
|
||||
#endif // (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE
|
||||
}
|
||||
}
|
||||
|
||||
if (bus != nullptr)
|
||||
{
|
||||
dbus_connection_unref(bus);
|
||||
}
|
||||
}
|
||||
#endif // defined(USE_RTKIT)
|
||||
|
||||
pa_threaded_mainloop_signal(threadedML, 0);
|
||||
}, mainloop_);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@
|
|||
thread_local HANDLE WASAPIAudioDevice::HelperTask_ = nullptr;
|
||||
|
||||
WASAPIAudioDevice::WASAPIAudioDevice(ComPtr<IAudioClient> client, ComPtr<IMMDevice> device, IAudioEngine::AudioDirection direction, int sampleRate, int numChannels)
|
||||
: client_(client)
|
||||
: Win32COMObject("WASAPIDev")
|
||||
, client_(client)
|
||||
, device_(device)
|
||||
, renderClient_(nullptr)
|
||||
, captureClient_(nullptr)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@
|
|||
#include "../util/logging/ulog.h"
|
||||
|
||||
WASAPIAudioEngine::WASAPIAudioEngine()
|
||||
: devEnumerator_(nullptr)
|
||||
: Win32COMObject("WASAPIEng")
|
||||
, devEnumerator_(nullptr)
|
||||
, inputDeviceList_(nullptr)
|
||||
, outputDeviceList_(nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
set(PIPELINE_SUBSET
|
||||
../../pipeline/AgcStep.cpp
|
||||
../../pipeline/AudioPipeline.cpp
|
||||
../../pipeline/BandwidthExpandStep.cpp
|
||||
#../../pipeline/BandwidthExpandStep.cpp
|
||||
../../pipeline/IPipelineStep.cpp
|
||||
../../pipeline/LevelAdjustStep.cpp
|
||||
../../pipeline/RADEReceiveStep.cpp
|
||||
|
|
@ -25,8 +25,8 @@ add_library(fdv_integ_audio_pipeline STATIC
|
|||
${PIPELINE_SUBSET})
|
||||
|
||||
target_compile_options(fdv_integ_audio_pipeline PRIVATE ${WARNINGS_AS_ERRORS_FLAGS})
|
||||
target_compile_definitions(fdv_integ_audio_pipeline PRIVATE -DDISABLE_UNIT_TEST)
|
||||
target_link_libraries(fdv_integ_audio_pipeline PRIVATE fdv_os_wrapper rade opus codec2 samplerate agc ebur128 ${SPEEXDSP_LIBRARY})
|
||||
target_compile_definitions(fdv_integ_audio_pipeline PRIVATE -DDISABLE_UNIT_TEST -DFREEDV_INTEGRATION)
|
||||
target_link_libraries(fdv_integ_audio_pipeline PRIVATE fdv_os_wrapper rade_integ opus_integ codec2 samplerate agc ebur128 ${SPEEXDSP_LIBRARY})
|
||||
if(STATIC_SPEEXDSP_BUILT)
|
||||
add_dependencies(fdv_integ_audio_pipeline speex)
|
||||
endif(STATIC_SPEEXDSP_BUILT)
|
||||
|
|
|
|||
|
|
@ -39,9 +39,13 @@
|
|||
#include "../pipeline/RADETransmitStep.h"
|
||||
|
||||
// TBD - need to wrap in "extern C" to avoid linker errors
|
||||
extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#if defined(FREEDV_INTEGRATION)
|
||||
#include "fargan_config_integ.h"
|
||||
#else
|
||||
#include "fargan_config.h"
|
||||
#endif // defined(FREEDV_INTEGRATION)
|
||||
#include "fargan.h"
|
||||
#include "lpcnet.h"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ std::string ReportingController::getVersionString_()
|
|||
#define PSKREPORTER_REPORT_INTERVAL_MS (5*60*1000)
|
||||
|
||||
ReportingController::ReportingController(std::string softwareName, bool rxOnly)
|
||||
: softwareName_(std::move(softwareName))
|
||||
: ThreadedObject("Reporting")
|
||||
, softwareName_(std::move(softwareName))
|
||||
, pskReporterSendTimer_(PSKREPORTER_REPORT_INTERVAL_MS, [&](ThreadedTimer&) {
|
||||
enqueue_([&]() {
|
||||
if (pskReporterConnection_ != nullptr)
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ add_executable(freedv-flex
|
|||
${MIMALLOC_SOURCE_FILE})
|
||||
|
||||
target_compile_options(freedv-flex PRIVATE ${WARNINGS_AS_ERRORS_FLAGS} -Wno-missing-field-initializers)
|
||||
target_compile_definitions(freedv-flex PRIVATE -DFREEDV_INTEGRATION)
|
||||
target_link_libraries(freedv-flex PRIVATE fdv_integ_audio_pipeline fdv_reporting fdv_util)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ constexpr short FLOAT_TO_SHORT_MULTIPLIER = 32767;
|
|||
using namespace std::placeholders;
|
||||
|
||||
FlexVitaTask::FlexVitaTask(std::shared_ptr<IRealtimeHelper> helper, bool randomUdpPort)
|
||||
: socket_(-1)
|
||||
: ThreadedObject("FlexVita")
|
||||
, socket_(-1)
|
||||
, rxStreamId_(0)
|
||||
, txStreamId_(0)
|
||||
, audioSeqNum_(0)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
extern "C"
|
||||
{
|
||||
#include "fargan_config.h"
|
||||
#include "fargan_config_integ.h"
|
||||
#include "fargan.h"
|
||||
#include "lpcnet.h"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@ add_executable(freedv-ka9q
|
|||
${MIMALLOC_SOURCE_FILE})
|
||||
|
||||
target_compile_options(freedv-ka9q PRIVATE ${WARNINGS_AS_ERRORS_FLAGS})
|
||||
target_compile_definitions(freedv-ka9q PRIVATE -DFREEDV_INTEGRATION)
|
||||
target_link_libraries(freedv-ka9q PRIVATE git_version fdv_integ_audio_pipeline fdv_reporting fdv_util fdv_os_wrapper)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
extern "C"
|
||||
{
|
||||
#include "fargan_config.h"
|
||||
#include "fargan_config_integ.h"
|
||||
#include "fargan.h"
|
||||
#include "lpcnet.h"
|
||||
}
|
||||
|
|
|
|||
16
src/main.cpp
16
src/main.cpp
|
|
@ -259,6 +259,8 @@ void MainFrame::handleAudioDeviceChange_(std::string const& newDeviceName)
|
|||
|
||||
void MainApp::UnitTest_()
|
||||
{
|
||||
SetThreadName("UnitTest");
|
||||
|
||||
// List audio devices
|
||||
auto engine = AudioEngineFactory::GetAudioEngine();
|
||||
engine->start();
|
||||
|
|
@ -1009,9 +1011,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ")
|
|||
VAR_FMT("Var: %4.1f"),
|
||||
CLK_OFF_FMT("ClkOff: %+-d")
|
||||
{
|
||||
#if defined(__linux__)
|
||||
pthread_setname_np(pthread_self(), "FreeDV GUI");
|
||||
#endif // defined(__linux__)
|
||||
SetThreadName("GUI");
|
||||
|
||||
terminating_ = false;
|
||||
realigned_ = false;
|
||||
|
|
@ -2657,9 +2657,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent&)
|
|||
{
|
||||
std::thread onOffExec([this]()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
pthread_setname_np(pthread_self(), "FreeDV TurningOn");
|
||||
#endif // defined(__linux__)
|
||||
SetThreadName("TurningOn");
|
||||
|
||||
performFreeDVOn_();
|
||||
|
||||
|
|
@ -2701,9 +2699,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent&)
|
|||
{
|
||||
std::thread onOffExec([this]()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
pthread_setname_np(pthread_self(), "FreeDV TurningOff");
|
||||
#endif // defined(__linux__)
|
||||
SetThreadName("TurningOff");
|
||||
|
||||
performFreeDVOff_();
|
||||
|
||||
|
|
@ -3669,7 +3665,7 @@ void MainFrame::OnTxOutAudioData_(IAudioDevice& dev, void* data, size_t size, vo
|
|||
|
||||
// If VOX tone is enabled, go back through and add the VOX tone
|
||||
// on the left channel.
|
||||
if (cbData->leftChannelVoxTone)
|
||||
if (cbData->leftChannelVoxTone.load(std::memory_order_acquire))
|
||||
{
|
||||
cbData->voxTonePhase += 2.0*M_PI*VOX_TONE_FREQ/dev.getSampleRate();
|
||||
cbData->voxTonePhase -= 2.0*M_PI*floor(cbData->voxTonePhase/(2.0*M_PI));
|
||||
|
|
|
|||
|
|
@ -50,4 +50,7 @@ void StartLowLatencyActivity();
|
|||
// Tells the operating system that we no longer need low latency.
|
||||
void StopLowLatencyActivity();
|
||||
|
||||
// Sets the name of the current thread in the OS.
|
||||
void SetThreadName(std::string const& name);
|
||||
|
||||
#endif // __OS_INTERFACE__
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "os_interface.h"
|
||||
|
||||
static id<NSObject> Activity = nil;
|
||||
|
|
@ -117,3 +120,10 @@ std::string GetOperatingSystemString()
|
|||
{
|
||||
return "macos";
|
||||
}
|
||||
|
||||
void SetThreadName(std::string const& name)
|
||||
{
|
||||
std::string fullName = "FDV ";
|
||||
fullName += name;
|
||||
pthread_setname_np(fullName.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,3 +50,13 @@ std::string GetOperatingSystemString()
|
|||
return "other";
|
||||
#endif // __linux__
|
||||
}
|
||||
|
||||
void SetThreadName(std::string const& name)
|
||||
{
|
||||
std::string fullName = "FDV ";
|
||||
fullName += name;
|
||||
#ifdef __linux__
|
||||
pthread_setname_np(pthread_self(), fullName.c_str());
|
||||
#endif // __linux__
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,3 +63,13 @@ std::string GetOperatingSystemString()
|
|||
{
|
||||
return "windows";
|
||||
}
|
||||
|
||||
void SetThreadName(std::string const& name)
|
||||
{
|
||||
// XXX - assumes ASCII. This is probably fine, though, since
|
||||
// this is debug code.
|
||||
std::string fullName = "FDV ";
|
||||
fullName += name;
|
||||
std::wstring stemp = std::wstring(fullName.begin(), fullName.end());
|
||||
SetThreadDescription(GetCurrentThread(), stemp.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ add_library(fdv_audio_pipeline STATIC
|
|||
)
|
||||
|
||||
target_compile_options(fdv_audio_pipeline PRIVATE ${WARNINGS_AS_ERRORS_FLAGS})
|
||||
target_link_libraries(fdv_audio_pipeline PRIVATE ebur128 agc)
|
||||
target_link_libraries(fdv_audio_pipeline PRIVATE ebur128 agc fdv_os_wrapper)
|
||||
target_include_directories(fdv_audio_pipeline PRIVATE ${CODEC2_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
|
||||
add_dependencies(fdv_audio_pipeline rade opus codec2)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include <pthread.h>
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
extern wxMutex g_mutexProtectingCallbackData;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
|
@ -86,8 +88,11 @@ short* PlaybackStep::execute(short*, int numInputSamples, int* numOutputSamples)
|
|||
{
|
||||
outputFifo_.read(outputSamples_.get(), *numOutputSamples);
|
||||
}
|
||||
|
||||
fileIoThreadSem_.signal();
|
||||
|
||||
if (outputFifo_.numUsed() < (outputFifo_.capacity() / 2))
|
||||
{
|
||||
fileIoThreadSem_.signal();
|
||||
}
|
||||
|
||||
return outputSamples_.get();
|
||||
}
|
||||
|
|
@ -101,6 +106,8 @@ void PlaybackStep::nonRtThreadEntry_()
|
|||
pthread_set_qos_class_self_np(QOS_CLASS_UTILITY, 0);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
SetThreadName("PlayStep");
|
||||
|
||||
while (!nonRtThreadEnding_)
|
||||
{
|
||||
g_mutexProtectingCallbackData.Lock();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include "pipeline_defines.h"
|
||||
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#if !defined(DISABLE_UNIT_TEST)
|
||||
|
|
@ -236,6 +238,8 @@ void RADEReceiveStep::utFeatureThreadEntry_()
|
|||
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, IOPOL_THROTTLE);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
SetThreadName("RADERx");
|
||||
|
||||
float* featureBuf = new float[utFeatures_->capacity()];
|
||||
assert(featureBuf != nullptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include <functional>
|
||||
|
||||
#include "IPipelineStep.h"
|
||||
#include "../freedv_interface.h"
|
||||
#include "rade_api.h"
|
||||
#include "rade_text.h"
|
||||
#include "../util/GenericFIFO.h"
|
||||
|
|
@ -42,9 +41,15 @@
|
|||
#define NUM_FEATURES_TO_STORE (256 * 1024)
|
||||
|
||||
// TBD - need to wrap in "extern C" to avoid linker errors
|
||||
extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#if defined(FREEDV_INTEGRATION)
|
||||
#include "fargan_config_integ.h"
|
||||
#else
|
||||
#include "fargan_config.h"
|
||||
#endif // defined(FREEDV_INTEGRATION)
|
||||
#include "fargan.h"
|
||||
#include "lpcnet.h"
|
||||
}
|
||||
|
||||
class RADEReceiveStep : public IPipelineStep
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include <sys/resource.h>
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define FEATURE_FIFO_SIZE ((RADE_SPEECH_SAMPLE_RATE / LPCNET_FRAME_SIZE) * rade_n_features_in_out(dv_))
|
||||
|
|
@ -246,6 +248,8 @@ void RADETransmitStep::utFeatureThreadEntry_()
|
|||
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, IOPOL_THROTTLE);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
SetThreadName("RADETx");
|
||||
|
||||
float* featureBuf = new float[utFeatures_->capacity()];
|
||||
assert(featureBuf != nullptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,22 @@
|
|||
#include <atomic>
|
||||
|
||||
#include "IPipelineStep.h"
|
||||
#include "../freedv_interface.h"
|
||||
#include "rade_api.h"
|
||||
#include "lpcnet.h"
|
||||
#include "../util/GenericFIFO.h"
|
||||
#include "../util/Semaphore.h"
|
||||
|
||||
// TBD - need to wrap in "extern C" to avoid linker errors
|
||||
extern "C"
|
||||
{
|
||||
#if defined(FREEDV_INTEGRATION)
|
||||
#include "fargan_config_integ.h"
|
||||
#else
|
||||
#include "fargan_config.h"
|
||||
#endif // defined(FREEDV_INTEGRATION)
|
||||
#include "fargan.h"
|
||||
#include "lpcnet.h"
|
||||
}
|
||||
|
||||
// Number of features to store. This is set to be close to the
|
||||
// typical size for RX/TX features for the rade_loss ctest to
|
||||
// avoid contention with normal RADE operation.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include <pthread.h>
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
extern wxMutex g_mutexProtectingCallbackData;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
|
@ -97,6 +99,8 @@ void RecordStep::fileIoThreadEntry_()
|
|||
pthread_set_qos_class_self_np(QOS_CLASS_UTILITY, 0);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
SetThreadName("RecordStep");
|
||||
|
||||
while (!fileIoThreadEnding_)
|
||||
{
|
||||
g_mutexProtectingCallbackData.Lock();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include <pthread.h>
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
TapStep::TapStep(int sampleRate, IPipelineStep* tapStep)
|
||||
|
|
@ -43,6 +45,8 @@ TapStep::TapStep(int sampleRate, IPipelineStep* tapStep)
|
|||
short* fifoInput = new short[SAMPLE_RATE_AT_10MS];
|
||||
assert(fifoInput != nullptr);
|
||||
|
||||
SetThreadName("TapStep");
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// Downgrade thread QoS to Utility to avoid thread contention issues.
|
||||
pthread_set_qos_class_self_np(QOS_CLASS_UTILITY, 0);
|
||||
|
|
|
|||
|
|
@ -531,12 +531,11 @@ void* TxRxThread::Entry() noexcept
|
|||
resetStats_();
|
||||
#endif // defined(ENABLE_PROCESSING_STATS)
|
||||
|
||||
#if defined(__linux__)
|
||||
// Set thread name for debugging
|
||||
const char* threadName = nullptr;
|
||||
if (m_tx) threadName = "FreeDV txThread";
|
||||
else threadName = "FreeDV rxThread";
|
||||
pthread_setname_np(pthread_self(), threadName);
|
||||
#endif // defined(__linux__)
|
||||
if (m_tx) threadName = "txThread";
|
||||
else threadName = "rxThread";
|
||||
SetThreadName(threadName);
|
||||
|
||||
// Make sure we don't start processing until
|
||||
// the main thread is ready.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#endif // defined(WIN32) || defined(__MINGW32__)
|
||||
|
||||
#include "pskreporter.h"
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
//#define PSK_REPORTER_TEST
|
||||
#if defined(PSK_REPORTER_TEST)
|
||||
|
|
@ -270,6 +271,8 @@ bool PskReporter::reportCommon_()
|
|||
{
|
||||
std::unique_lock<std::mutex> lock(recordListMutex_);
|
||||
|
||||
SetThreadName("PSKReport");
|
||||
|
||||
// Header (2) + length (2) + time (4) + sequence # (4) + random identifier (4) +
|
||||
// RX format block + TX format block + RX data + TX data
|
||||
int dgSize = 16 + sizeof(rxFormatHeader) + sizeof(txFormatHeader) + getRxDataSize_() + getTxDataSize_();
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ bool HamlibRigController::RigCompare_(const struct rig_caps *rig1, const struct
|
|||
}
|
||||
|
||||
HamlibRigController::HamlibRigController(std::string rigName, std::string serialPort, const int serialRate, const int civHex, const PttType pttType, std::string pttSerialPort, bool restoreFreqModeOnDisconnect, bool freqOnly)
|
||||
: rigName_(std::move(rigName))
|
||||
: ThreadedObject("hamlib")
|
||||
, rigName_(std::move(rigName))
|
||||
, serialPort_(std::move(serialPort))
|
||||
, serialRate_(serialRate)
|
||||
, civHex_(civHex)
|
||||
|
|
@ -92,7 +93,8 @@ HamlibRigController::HamlibRigController(std::string rigName, std::string serial
|
|||
}
|
||||
|
||||
HamlibRigController::HamlibRigController(int rigIndex, std::string serialPort, const int serialRate, const int civHex, const PttType pttType, std::string pttSerialPort, bool restoreFreqModeOnDisconnect, bool freqOnly)
|
||||
: rigName_(RigIndexToName(rigIndex))
|
||||
: ThreadedObject("hamlib")
|
||||
, rigName_(RigIndexToName(rigIndex))
|
||||
, serialPort_(std::move(serialPort))
|
||||
, serialRate_(serialRate)
|
||||
, civHex_(civHex)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
//=========================================================================
|
||||
|
||||
#include "SerialPortInRigController.h"
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
#define PTT_INPUT_MONITORING_TIME_MS 10
|
||||
|
||||
|
|
@ -80,6 +81,8 @@ bool SerialPortInRigController::getCTS_()
|
|||
|
||||
void SerialPortInRigController::pollThreadEntry_()
|
||||
{
|
||||
SetThreadName("SerialIn");
|
||||
|
||||
while (!threadExiting_)
|
||||
{
|
||||
enqueue_(std::bind(&SerialPortInRigController::pollSerialPort_, this));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
#include "../util/logging/ulog.h"
|
||||
|
||||
SerialPortRigController::SerialPortRigController(std::string serialPort)
|
||||
: serialPortHandle_(COM_HANDLE_INVALID)
|
||||
: ThreadedObject("SerialController")
|
||||
, serialPortHandle_(COM_HANDLE_INVALID)
|
||||
, serialPort_(std::move(serialPort))
|
||||
{
|
||||
// empty
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ using namespace std::chrono_literals;
|
|||
#define OMNI_RIG_WAIT_TIME (200ms)
|
||||
|
||||
OmniRigController::OmniRigController(int rigId, bool restoreOnDisconnect, bool freqOnly)
|
||||
: rigId_(rigId)
|
||||
: ThreadedObject("OmniRig")
|
||||
, rigId_(rigId)
|
||||
, omniRig_(nullptr)
|
||||
, rig_(nullptr)
|
||||
, origFreq_(0)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ add_library(fdv_util STATIC
|
|||
)
|
||||
|
||||
target_compile_options(fdv_util PRIVATE ${WARNINGS_AS_ERRORS_FLAGS})
|
||||
target_link_libraries(fdv_util yyjson)
|
||||
target_link_libraries(fdv_util yyjson fdv_os_wrapper)
|
||||
|
||||
if(UNITTEST)
|
||||
macro(DefineUnitTest utName)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "TcpConnectionHandler.h"
|
||||
#include "logging/ulog.h"
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
|
@ -59,7 +60,8 @@ using namespace std::chrono_literals;
|
|||
#endif // INVALID_SOCKET
|
||||
|
||||
TcpConnectionHandler::TcpConnectionHandler()
|
||||
: enableReconnect_(false)
|
||||
: ThreadedObject("TcpConn")
|
||||
, enableReconnect_(false)
|
||||
, reconnectTimer_(RECONNECT_INTERVAL_MS, [&](ThreadedTimer&) {
|
||||
enqueue_(std::bind(&TcpConnectionHandler::connectImpl_, this));
|
||||
}, false)
|
||||
|
|
@ -178,6 +180,8 @@ void TcpConnectionHandler::connectImpl_()
|
|||
|
||||
std::string portStr = portStream.str();
|
||||
std::thread ipv6ResolveThread([&, portStr, ipv6ResultPromise]() {
|
||||
SetThreadName("ipv6");
|
||||
|
||||
struct addrinfo *result = nullptr;
|
||||
resolveAddresses_(AF_INET6, host_.c_str(), portStr.c_str(), &result);
|
||||
ipv6ResultPromise->set_value(result);
|
||||
|
|
@ -185,6 +189,8 @@ void TcpConnectionHandler::connectImpl_()
|
|||
});
|
||||
|
||||
std::thread ipv4ResolveThread([&, portStr, ipv4ResultPromise]() {
|
||||
SetThreadName("ipv4");
|
||||
|
||||
struct addrinfo *result = nullptr;
|
||||
resolveAddresses_(AF_INET, host_.c_str(), portStr.c_str(), &result);
|
||||
ipv4ResultPromise->set_value(result);
|
||||
|
|
@ -579,9 +585,10 @@ void TcpConnectionHandler::sendImpl_(const char* buf, int length)
|
|||
void TcpConnectionHandler::receiveImpl_()
|
||||
{
|
||||
constexpr int READ_SIZE_BYTES = 1024;
|
||||
|
||||
char buf[READ_SIZE_BYTES];
|
||||
|
||||
SetThreadName("TCPRx");
|
||||
|
||||
while (socket_.load(std::memory_order_acquire) != INVALID_SOCKET)
|
||||
{
|
||||
struct timeval tv = {0, 250000}; // 250ms
|
||||
|
|
|
|||
|
|
@ -21,12 +21,14 @@
|
|||
//=========================================================================
|
||||
|
||||
#include <chrono>
|
||||
#include "../os/os_interface.h"
|
||||
#include "ThreadedObject.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
ThreadedObject::ThreadedObject(ThreadedObject* parent)
|
||||
ThreadedObject::ThreadedObject(std::string name, ThreadedObject* parent)
|
||||
: parent_(parent)
|
||||
, name_(std::move(name))
|
||||
, isDestroying_(false)
|
||||
{
|
||||
// Instantiate thread here rather than the initializer since otherwise
|
||||
|
|
@ -107,6 +109,8 @@ void ThreadedObject::eventLoop_()
|
|||
pthread_set_qos_class_self_np(QOS_CLASS_UTILITY,0);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
SetThreadName(name_);
|
||||
|
||||
while (!isDestroying_.load(std::memory_order_acquire))
|
||||
{
|
||||
std::function<void()> fn;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <deque>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
class ThreadedObject
|
||||
{
|
||||
|
|
@ -40,7 +41,7 @@ public:
|
|||
virtual ~ThreadedObject();
|
||||
|
||||
protected:
|
||||
ThreadedObject(ThreadedObject* parent = nullptr);
|
||||
ThreadedObject(std::string name, ThreadedObject* parent = nullptr);
|
||||
|
||||
// Enqueues some code to run on a different thread.
|
||||
// @param timeoutMilliseconds Timeout to wait for lock. Note: if we can't get a lock within the timeout, the function doesn't run!
|
||||
|
|
@ -48,7 +49,8 @@ protected:
|
|||
|
||||
private:
|
||||
ThreadedObject* parent_;
|
||||
|
||||
std::string name_;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
dispatch_queue_t queue_;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#include "ThreadedObject.h"
|
||||
|
||||
ThreadedObject::ThreadedObject(ThreadedObject* parent)
|
||||
ThreadedObject::ThreadedObject(std::string name, ThreadedObject* parent)
|
||||
: parent_(parent)
|
||||
, name_(std::move(name))
|
||||
{
|
||||
dispatch_queue_t parentQueue;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
//=========================================================================
|
||||
|
||||
#include "ThreadedTimer.h"
|
||||
#include "../os/os_interface.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
|
|
@ -85,6 +86,8 @@ void ThreadedTimer::TimerServer::unregisterTimer(ThreadedTimer* timer)
|
|||
|
||||
void ThreadedTimer::TimerServer::eventLoop_()
|
||||
{
|
||||
SetThreadName("Timer");
|
||||
|
||||
std::unique_lock<std::mutex> lk(mutex_);
|
||||
std::chrono::time_point<std::chrono::steady_clock> nextFireTime;
|
||||
while (!isDestroying_.load(std::memory_order_acquire))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
#include <future>
|
||||
|
||||
Win32COMObject::Win32COMObject()
|
||||
Win32COMObject::Win32COMObject(std::string name)
|
||||
: ThreadedObject(name)
|
||||
{
|
||||
enqueue_([&]() {
|
||||
HRESULT res = CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public:
|
|||
virtual ~Win32COMObject();
|
||||
|
||||
protected:
|
||||
Win32COMObject();
|
||||
Win32COMObject(std::string name);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue