Skip to content

Commit

Permalink
Replaced Boost.Thread synchronization primitives with std equivalents.
Browse files Browse the repository at this point in the history
This replaces most mutexes and condition variables with std equivalents.

Refs #232.
  • Loading branch information
Lastique committed Aug 16, 2024
1 parent 9a906e2 commit b3ca66d
Show file tree
Hide file tree
Showing 30 changed files with 213 additions and 329 deletions.
8 changes: 8 additions & 0 deletions doc/changelog.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

[section:changelog Changelog]

[heading 2.30, Boost 1.87]

* Replaced __boost_thread__ synchronization primitives with equivalents from the C++ standard library. This may improve multithreaded performance, but also has user-facing consequences:
* __boost_thread__ thread interruption is no longer supported. Boost.Log no longer has special treatment for the `thread_interrupted` exception that is used by Boost.Thread to implement thread interruption. This exception will be handled like any other exception.
In particular, user-specified exception handlers may now be invoked with the `thread_interrupted` pending exception.
* For timed waiting operations, timeouts are now using std::chrono time units. This means that the `ordering_window` named parameter that is supported by the [class_sinks_bounded_ordering_queue] and [class_sinks_unbounded_ordering_queue] now expects an `std::chrono::duration` value instead of `boost::posix_time::time_duration` from __boost_date_time__.
* In case of errors indicated by thread synchronization primitives, `std::system_error` exception is thrown instead of __boost_thread__ exception types.

[heading 2.29, Boost 1.86]

* Added a workaround for `windres.exe` issue, when it is used in CMake to compile event log resource files on MinGW-w64. ([pull_request 231])
Expand Down
16 changes: 7 additions & 9 deletions example/async_log/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@
// #define BOOST_LOG_DYN_LINK 1

#include <stdexcept>
#include <thread>
#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include <boost/core/ref.hpp>
#include <boost/bind/bind.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>

#include <boost/log/common.hpp>
Expand Down Expand Up @@ -57,7 +54,7 @@ void thread_fun(boost::barrier& bar)
bar.wait();

// Here we go. First, identify the thread.
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", boost::this_thread::get_id());
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", std::this_thread::get_id());

// Now, do some logging
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
Expand Down Expand Up @@ -95,7 +92,7 @@ int main(int argc, char* argv[])
expr::format("%1%: [%2%] [%3%] - %4%")
% expr::attr< unsigned int >("RecordID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::attr< boost::thread::id >("ThreadID")
% expr::attr< std::thread::id >("ThreadID")
% expr::smessage
);

Expand All @@ -108,12 +105,13 @@ int main(int argc, char* argv[])

// Create logging threads
boost::barrier bar(THREAD_COUNT);
boost::thread_group threads;
std::thread threads[THREAD_COUNT];
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads.create_thread(boost::bind(&thread_fun, boost::ref(bar)));
threads[i] = std::thread([&bar]() { thread_fun(bar); });

// Wait until all action ends
threads.join_all();
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads[i].join();

// Flush all buffered records
sink->stop();
Expand Down
16 changes: 7 additions & 9 deletions example/bounded_async_log/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@
// #define BOOST_LOG_DYN_LINK 1

#include <stdexcept>
#include <thread>
#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include <boost/core/ref.hpp>
#include <boost/bind/bind.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>

#include <boost/log/common.hpp>
Expand Down Expand Up @@ -57,7 +54,7 @@ void thread_fun(boost::barrier& bar)
bar.wait();

// Here we go. First, identify the thread.
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", boost::this_thread::get_id());
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", std::this_thread::get_id());

// Now, do some logging
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
Expand Down Expand Up @@ -97,7 +94,7 @@ int main(int argc, char* argv[])
expr::format("%1%: [%2%] [%3%] - %4%")
% expr::attr< unsigned int >("RecordID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::attr< boost::thread::id >("ThreadID")
% expr::attr< std::thread::id >("ThreadID")
% expr::smessage
);

Expand All @@ -110,12 +107,13 @@ int main(int argc, char* argv[])

// Create logging threads
boost::barrier bar(THREAD_COUNT);
boost::thread_group threads;
std::thread threads[THREAD_COUNT];
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads.create_thread(boost::bind(&thread_fun, boost::ref(bar)));
threads[i] = std::thread([&bar]() { thread_fun(bar); });

// Wait until all action ends
threads.join_all();
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads[i].join();

// Flush all buffered records
sink->stop();
Expand Down
13 changes: 7 additions & 6 deletions example/multiple_files/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
// #define BOOST_LOG_DYN_LINK 1

#include <stdexcept>
#include <thread>
#include <string>
#include <iostream>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include <boost/log/common.hpp>
Expand Down Expand Up @@ -53,7 +53,7 @@ BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)
// This function is executed in a separate thread
void thread_foo()
{
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", boost::this_thread::get_id());
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", std::this_thread::get_id());
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
{
BOOST_LOG(my_logger::get()) << "Log record " << i;
Expand All @@ -70,7 +70,7 @@ int main(int argc, char* argv[])

// Set up how the file names will be generated
sink->locked_backend()->set_file_name_composer(sinks::file::as_file_name_composer(
expr::stream << "logs/" << expr::attr< boost::thread::id >("ThreadID") << ".log"));
expr::stream << "logs/" << expr::attr< std::thread::id >("ThreadID") << ".log"));

// Set the log record formatter
sink->set_formatter
Expand All @@ -89,11 +89,12 @@ int main(int argc, char* argv[])
logging::core::get()->add_global_attribute("RecordID", attrs::counter< unsigned int >());

// Create threads and make some logs
boost::thread_group threads;
std::thread threads[THREAD_COUNT];
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads.create_thread(&thread_foo);
threads[i] = std::thread(&thread_foo);

threads.join_all();
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads[i].join();

return 0;
}
Expand Down
11 changes: 5 additions & 6 deletions example/multiple_threads/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
// #define BOOST_LOG_DYN_LINK 1

#include <stdexcept>
#include <thread>
#include <string>
#include <iostream>
#include <fstream>
#include <boost/core/ref.hpp>
#include <boost/bind/bind.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>

#include <boost/log/common.hpp>
Expand Down Expand Up @@ -98,12 +96,13 @@ int main(int argc, char* argv[])

// Create logging threads
boost::barrier bar(THREAD_COUNT);
boost::thread_group threads;
std::thread threads[THREAD_COUNT];
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads.create_thread(boost::bind(&thread_fun, boost::ref(bar)));
threads[i] = std::thread([&bar]() { thread_fun(bar); });

// Wait until all action ends
threads.join_all();
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads[i].join();

return 0;
}
Expand Down
18 changes: 8 additions & 10 deletions include/boost/log/detail/adaptive_mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@

#ifndef BOOST_LOG_NO_THREADS

#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/assert/source_location.hpp>

#if defined(BOOST_THREAD_POSIX) // This one can be defined by users, so it should go first
#define BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD
#elif defined(BOOST_WINDOWS)
Expand Down Expand Up @@ -144,7 +140,10 @@ BOOST_LOG_CLOSE_NAMESPACE // namespace log
#elif defined(BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD)

#include <pthread.h>
#include <cerrno>
#include <system_error>
#include <boost/assert.hpp>
#include <boost/assert/source_location.hpp>
#include <boost/log/detail/header.hpp>

#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
Expand Down Expand Up @@ -177,7 +176,7 @@ class adaptive_mutex
const int err = pthread_mutex_init(&m_State, NULL);
#endif
if (BOOST_UNLIKELY(err != 0))
throw_exception< thread_resource_error >(err, "Failed to initialize an adaptive mutex", "adaptive_mutex::adaptive_mutex()", __FILE__, __LINE__);
throw_system_error(err, "Failed to initialize an adaptive mutex", "adaptive_mutex::adaptive_mutex()", __FILE__, __LINE__);
}

~adaptive_mutex()
Expand All @@ -191,15 +190,15 @@ class adaptive_mutex
if (err == 0)
return true;
if (BOOST_UNLIKELY(err != EBUSY))
throw_exception< lock_error >(err, "Failed to lock an adaptive mutex", "adaptive_mutex::try_lock()", __FILE__, __LINE__);
throw_system_error(err, "Failed to lock an adaptive mutex", "adaptive_mutex::try_lock()", __FILE__, __LINE__);
return false;
}

void lock()
{
const int err = pthread_mutex_lock(&m_State);
if (BOOST_UNLIKELY(err != 0))
throw_exception< lock_error >(err, "Failed to lock an adaptive mutex", "adaptive_mutex::lock()", __FILE__, __LINE__);
throw_system_error(err, "Failed to lock an adaptive mutex", "adaptive_mutex::lock()", __FILE__, __LINE__);
}

void unlock()
Expand All @@ -212,10 +211,9 @@ class adaptive_mutex
BOOST_DELETED_FUNCTION(adaptive_mutex& operator= (adaptive_mutex const&))

private:
template< typename ExceptionT >
static BOOST_NOINLINE BOOST_LOG_NORETURN void throw_exception(int err, const char* descr, const char* func, const char* file, int line)
static BOOST_NOINLINE BOOST_LOG_NORETURN void throw_system_error(int err, const char* descr, const char* func, const char* file, int line)
{
boost::throw_exception(ExceptionT(err, descr), boost::source_location(file, line, func));
boost::throw_exception(std::system_error(std::error_code(err, std::system_category()), descr), boost::source_location(file, line, func));
}
};

Expand Down
6 changes: 3 additions & 3 deletions include/boost/log/detail/enqueued_record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
#ifndef BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
#define BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_

#include <chrono>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/timestamp.hpp>
#include <boost/log/core/record_view.hpp>
#include <boost/log/detail/header.hpp>

Expand Down Expand Up @@ -60,7 +60,7 @@ class enqueued_record
}
};

boost::log::aux::timestamp m_timestamp;
std::chrono::steady_clock::time_point m_timestamp;
record_view m_record;

enqueued_record(enqueued_record const& that) BOOST_NOEXCEPT : m_timestamp(that.m_timestamp), m_record(that.m_record)
Expand All @@ -72,7 +72,7 @@ class enqueued_record
{
}
explicit enqueued_record(record_view const& rec) :
m_timestamp(boost::log::aux::get_timestamp()),
m_timestamp(std::chrono::steady_clock::now()),
m_record(rec)
{
}
Expand Down
10 changes: 5 additions & 5 deletions include/boost/log/detail/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
#include <boost/atomic/atomic.hpp>
#define BOOST_LOG_EVENT_USE_WINAPI
#else
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#define BOOST_LOG_EVENT_USE_BOOST_CONDITION_VARIABLE
#include <mutex>
#include <condition_variable>
#define BOOST_LOG_EVENT_USE_STD_CONDITION_VARIABLE
#endif

#include <boost/log/detail/header.hpp>
Expand Down Expand Up @@ -130,8 +130,8 @@ typedef winapi_based_event event;
class generic_event
{
private:
boost::mutex m_mutex;
boost::condition_variable m_cond;
std::mutex m_mutex;
std::condition_variable m_cond;
bool m_state;

public:
Expand Down
4 changes: 2 additions & 2 deletions include/boost/log/detail/locking_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
#define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_

#include <cstddef>
#include <mutex> // try_to_lock_t
#include <boost/move/core.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/thread/lock_options.hpp>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/header.hpp>
Expand Down Expand Up @@ -66,7 +66,7 @@ class locking_ptr
m_pLock->lock();
}
//! Constructor
locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, try_to_lock_t const&) : m_pElement(p), m_pLock(&l)
locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, std::try_to_lock_t) : m_pElement(p), m_pLock(&l)
{
if (!m_pLock->try_lock())
{
Expand Down
Loading

0 comments on commit b3ca66d

Please sign in to comment.