filter default_filter_factory< CharT >::parse_argument(attribute_name const& name, string_type const& arg) { typedef log::aux::encoding_specific< typename log::aux::encoding< char_type >::type > encoding_specific; const qi::real_parser< double, qi::strict_real_policies< double > > real_; filter f; const on_fp_argument< RelationT > on_fp(name, f); const on_integral_argument< RelationT > on_int(name, f); const on_string_argument< RelationT > on_str(name, f); const bool res = qi::parse ( arg.c_str(), arg.c_str() + arg.size(), ( real_[boost::log::as_action(on_fp)] | qi::long_[boost::log::as_action(on_int)] | qi::as< string_type >()[ +encoding_specific::print ][boost::log::as_action(on_str)] ) >> qi::eoi ); if (!res) BOOST_LOG_THROW_DESCR(parse_error, "Failed to parse relation operand"); return boost::move(f); }
BOOST_LOG_EXPORT void basic_event_log_backend< CharT >::construct( boost::log::aux::universal_path const& message_file_name, string_type const& target, string_type const& log_name, string_type const& source_name, event_log::registration_mode reg_mode) { if (reg_mode != event_log::never) { aux::registry_params< char_type > reg_params; string_type file_name; log::aux::code_convert(message_file_name.string(), file_name); reg_params.event_message_file = file_name; reg_params.types_supported = DWORD( EVENTLOG_SUCCESS | EVENTLOG_INFORMATION_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_ERROR_TYPE); aux::init_event_log_registry(log_name, source_name, reg_mode == event_log::forced, reg_params); } std::auto_ptr< implementation > p(new implementation()); const char_type* target_unc = NULL; if (!target.empty()) target_unc = target.c_str(); HANDLE hSource = register_event_source(target_unc, source_name.c_str()); if (!hSource) BOOST_LOG_THROW_DESCR(system_error, "Could not register event source"); p->m_SourceHandle = hSource; m_pImpl = p.release(); }
//! The method creates the backend implementation BOOST_LOG_API void syslog_backend::construct(syslog::facility fac, syslog::impl_types use_impl, ip_versions ip_version, std::string const& ident) { #ifdef BOOST_LOG_USE_NATIVE_SYSLOG if (use_impl == syslog::native) { typedef implementation::native native_impl; m_pImpl = new native_impl(fac, ident); return; } #endif // BOOST_LOG_USE_NATIVE_SYSLOG #if !defined(BOOST_LOG_NO_ASIO) typedef implementation::udp_socket_based udp_socket_based_impl; switch (ip_version) { case v4: m_pImpl = new udp_socket_based_impl(fac, asio::ip::udp::v4()); break; case v6: m_pImpl = new udp_socket_based_impl(fac, asio::ip::udp::v6()); break; default: BOOST_LOG_THROW_DESCR(setup_error, "Incorrect IP version specified"); } #endif }
static void allocate(StorageT& stg) { if (pthread_key_create(reinterpret_cast< pthread_key_type* >(&stg.as_dword), 0) != 0) { BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } }
//! Initializing constructor scoped_thread_id(frontend_mutex_type& mut, condition_variable_any& cond, thread::id& tid, boost::atomic< bool >& sr) : m_Mutex(mut), m_Cond(cond), m_ThreadID(tid), m_StopRequested(sr) { lock_guard< frontend_mutex_type > lock(m_Mutex); if (m_ThreadID != thread::id()) BOOST_LOG_THROW_DESCR(unexpected_call, "Asynchronous sink frontend already runs a record feeding thread"); m_ThreadID = this_thread::get_id(); }
thread_specific_base::thread_specific_base() { m_Key = TlsAlloc(); if (BOOST_UNLIKELY(m_Key == TLS_OUT_OF_INDEXES)) { BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } }
//! Initializing constructor scoped_thread_id(unique_lock< frontend_mutex_type >& l, condition_variable_any& cond, thread::id& tid, bool volatile& sr) : m_Mutex(*l.mutex()), m_Cond(cond), m_ThreadID(tid), m_StopRequested(sr) { unique_lock< frontend_mutex_type > lock(move(l)); if (m_ThreadID != thread::id()) BOOST_LOG_THROW_DESCR(unexpected_call, "Asynchronous sink frontend already runs a record feeding thread"); m_ThreadID = this_thread::get_id(); }
thread_specific_base::thread_specific_base() { m_Key.as_dword = TlsAlloc(); if (m_Key.as_dword == TLS_OUT_OF_INDEXES) { BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } set_content(0); }
bool interprocess_condition_variable::wait(interprocess_mutex::optional_unlock& lock, boost::detail::winapi::HANDLE_ abort_handle) { int32_t waiters = m_shared_state->m_waiters; if (waiters < 0) { // We need to select a new semaphore to block on m_current_semaphore = get_unused_semaphore(); ++m_shared_state->m_generation; m_shared_state->m_semaphore_id = m_current_semaphore->m_id; waiters = 0; } else { // Avoid integer overflow if (BOOST_UNLIKELY(waiters >= ((std::numeric_limits< int32_t >::max)() - 1))) BOOST_LOG_THROW_DESCR(limitation_error, "Too many waiters on an interprocess condition variable"); // Make sure we use the right semaphore to block on const uint32_t id = m_shared_state->m_semaphore_id; if (m_current_semaphore->m_id != id) m_current_semaphore = get_semaphore(id); } m_shared_state->m_waiters = waiters + 1; const uint32_t generation = m_shared_state->m_generation; boost::detail::winapi::HANDLE_ handles[2u] = { m_current_semaphore->m_semaphore.get_handle(), abort_handle }; interprocess_mutex* const mutex = lock.disengage(); mutex->unlock(); boost::detail::winapi::DWORD_ retval = boost::detail::winapi::WaitForMultipleObjects(2u, handles, false, boost::detail::winapi::INFINITE_); if (BOOST_UNLIKELY(retval == boost::detail::winapi::WAIT_FAILED_)) { const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); // Although highly unrealistic, it is possible that it took so long for the current thread to enter WaitForMultipleObjects that // another thread has managed to destroy the semaphore. This can happen if the semaphore remains in a non-zero state // for too long, which means that another process died while being blocked on the semaphore, and the semaphore was signalled, // and the non-zero state timeout has passed. In this case the most logical behavior for the wait function is to return as // if because of a wakeup. if (err == ERROR_INVALID_HANDLE) retval = boost::detail::winapi::WAIT_OBJECT_0_; else BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, "Failed to block on an interprocess semaphore object", (err)); } // Have to unconditionally lock the mutex here mutex->lock(); lock.engage(*mutex); if (generation == m_shared_state->m_generation && m_shared_state->m_waiters > 0) --m_shared_state->m_waiters; return retval == boost::detail::winapi::WAIT_OBJECT_0_; }
static void allocate(void*& stg) { pthread_key_type key = NULL; const int res = pthread_key_create(&key, NULL); if (BOOST_UNLIKELY(res != 0)) { BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } stg = static_cast< void* >(key); }
static void allocate(void*& stg) { pthread_key_caster caster = {}; const int res = pthread_key_create(&caster.as_key, NULL); if (BOOST_UNLIKELY(res != 0)) { BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } stg = caster.as_storage; }
static void allocate(StorageT& stg) { pthread_key_type* pkey = new pthread_key_type; if (pthread_key_create(pkey, 0) != 0) { delete pkey; BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } stg.as_pointer = pkey; }
static void allocate(void*& stg) { pthread_key_type* pkey = new pthread_key_type(); const int res = pthread_key_create(pkey, NULL); if (BOOST_UNLIKELY(res != 0)) { delete pkey; BOOST_LOG_THROW_DESCR(system_error, "TLS capacity depleted"); } stg = pkey; }
//! The method returns the filter factory for the specified attribute name formatter_factory_type& get_factory(attribute_name const& name) const { typename factories_map::const_iterator it = m_Map.find(name); if (it != m_Map.end()) { return *it->second; } else { #if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES) return m_DefaultFactory; #else BOOST_LOG_THROW_DESCR(setup_error, "No formatter factory registered for attribute " + name.string()); #endif } }
std::basic_string< CharT > get_current_module_name() { static HMODULE hSelfModule = 0; BOOST_LOG_ONCE_BLOCK() { init_self_module_handle(hSelfModule); } // Get the module file name CharT buf[MAX_PATH]; DWORD size = get_module_file_name(hSelfModule, buf, sizeof(buf) / sizeof(*buf)); if (size == 0) BOOST_LOG_THROW_DESCR(system_error, "Could not get module file name"); return std::basic_string< CharT >(buf, buf + size); }
typename default_filter_factory< CharT >::filter_type default_filter_factory< CharT >::parse_argument(string_type const& name, string_type const& arg) { filter_type filter; const bool full = bsc::parse(arg.c_str(), arg.c_str() + arg.size(), ( bsc::strict_real_p[boost::bind(&this_type::BOOST_NESTED_TEMPLATE on_fp_argument< RelationT >, boost::cref(name), _1, boost::ref(filter))] | bsc::int_p[boost::bind(&this_type::BOOST_NESTED_TEMPLATE on_integral_argument< RelationT >, boost::cref(name), _1, boost::ref(filter))] | (+bsc::print_p)[boost::bind(&this_type::BOOST_NESTED_TEMPLATE on_string_argument< RelationT >, boost::cref(name), _1, _2, boost::ref(filter))] ) ).full; if (!full || filter.empty()) BOOST_LOG_THROW_DESCR(parse_error, "Failed to parse relation operand"); return filter; }
filter default_filter_factory< CharT >::on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg) { typedef log::aux::char_constants< char_type > constants; filter f; if (rel == constants::begins_with_keyword()) on_string_argument< begins_with_fun >(name, f)(arg); else if (rel == constants::ends_with_keyword()) on_string_argument< ends_with_fun >(name, f)(arg); else if (rel == constants::contains_keyword()) on_string_argument< contains_fun >(name, f)(arg); else if (rel == constants::matches_keyword()) on_regex_argument< matches_fun >(name, f)(arg); else { BOOST_LOG_THROW_DESCR(parse_error, "The custom attribute relation \"" + log::aux::to_narrow(rel) + "\" is not supported"); } return boost::move(f); }
typename default_filter_factory< CharT >::filter_type default_filter_factory< CharT >::on_custom_relation(string_type const& name, string_type const& rel, string_type const& arg) { typedef log::aux::char_constants< char_type > constants; if (rel == constants::begins_with_keyword()) return filter_type(log::filters::attr< string_type >(name).begins_with(arg)); else if (rel == constants::ends_with_keyword()) return filter_type(log::filters::attr< string_type >(name).ends_with(arg)); else if (rel == constants::contains_keyword()) return filter_type(log::filters::attr< string_type >(name).contains(arg)); else if (rel == constants::matches_keyword()) { typedef xpressive::basic_regex< typename string_type::const_iterator > regex_t; regex_t rex = regex_t::compile(arg, regex_t::ECMAScript | regex_t::optimize); return filter_type(log::filters::attr< string_type >(name, std::nothrow).matches(rex)); } else { BOOST_LOG_THROW_DESCR(parse_error, "The custom attribute relation is not supported"); } }
inline void interprocess_mutex::mark_waiting_and_try_lock(uint32_t& old_state) { uint32_t new_state; do { uint32_t was_locked = (old_state & lock_flag_value); if (was_locked) { // Avoid integer overflows if (BOOST_UNLIKELY((old_state & waiter_count_mask) == waiter_count_mask)) BOOST_LOG_THROW_DESCR(limitation_error, "Too many waiters on an interprocess mutex"); new_state = old_state + 1u; } else { new_state = old_state | lock_flag_value; } } while (!m_shared_state->m_lock_state.compare_exchange_weak(old_state, new_state, boost::memory_order_acq_rel, boost::memory_order_relaxed)); }
void init_event_log_registry( std::basic_string< CharT > const& log_name, std::basic_string< CharT > const& source_name, bool force, registry_params< CharT > const& params) { typedef std::basic_string< CharT > string_type; typedef registry_traits< CharT > registry; // Registry key name that contains log description string_type reg_key = registry::make_event_log_key(log_name, source_name); // First check the registry keys and values in read-only mode. // This allows to avoid UAC asking for elevated permissions to modify HKLM registry when no modification is actually needed. if (verify_event_log_registry(reg_key, force, params)) return; // Create or open the key HKEY hkey = 0; DWORD disposition = 0; LSTATUS res = registry::create_key( HKEY_LOCAL_MACHINE, reg_key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disposition); if (res != ERROR_SUCCESS) BOOST_LOG_THROW_DESCR(system_error, "Could not create registry key for the event log"); auto_hkey_close hkey_guard(hkey); if (disposition != REG_OPENED_EXISTING_KEY || force) { // Fill registry values if (!!params.event_message_file) { // Set the module file name that contains event resources string_type const& module_name = params.event_message_file.get(); res = registry::set_value( hkey, registry::get_event_message_file_param_name(), 0, REG_EXPAND_SZ, reinterpret_cast< LPBYTE >(const_cast< CharT* >(module_name.c_str())), static_cast< DWORD >((module_name.size() + 1) * sizeof(CharT))); if (res != ERROR_SUCCESS) { BOOST_LOG_THROW_DESCR(system_error, "Could not create registry value " + log::aux::to_narrow(string_type(registry::get_event_message_file_param_name()))); } } if (!!params.category_message_file) { // Set the module file name that contains event category resources string_type const& module_name = params.category_message_file.get(); res = registry::set_value( hkey, registry::get_category_message_file_param_name(), 0, REG_SZ, reinterpret_cast< LPBYTE >(const_cast< CharT* >(module_name.c_str())), static_cast< DWORD >((module_name.size() + 1) * sizeof(CharT))); if (res != ERROR_SUCCESS) { BOOST_LOG_THROW_DESCR(system_error, "Could not create registry value " + log::aux::to_narrow(string_type(registry::get_category_message_file_param_name()))); } } if (!!params.category_count) { // Set number of categories DWORD category_count = params.category_count.get(); res = registry::set_value( hkey, registry::get_category_count_param_name(), 0, REG_DWORD, reinterpret_cast< LPBYTE >(&category_count), static_cast< DWORD >(sizeof(category_count))); if (res != ERROR_SUCCESS) { BOOST_LOG_THROW_DESCR(system_error, "Could not create registry value " + log::aux::to_narrow(string_type(registry::get_category_count_param_name()))); } } if (!!params.types_supported) { // Set the supported event types DWORD event_types = params.types_supported.get(); res = registry::set_value( hkey, registry::get_types_supported_param_name(), 0, REG_DWORD, reinterpret_cast< LPBYTE >(&event_types), static_cast< DWORD >(sizeof(event_types))); if (res != ERROR_SUCCESS) { BOOST_LOG_THROW_DESCR(system_error, "Could not create registry value " + log::aux::to_narrow(string_type(registry::get_types_supported_param_name()))); } } } }
//! Finds or creates a semaphore with zero counter interprocess_condition_variable::semaphore_info* interprocess_condition_variable::get_unused_semaphore() { // Be optimistic, check the current semaphore first if (m_current_semaphore && m_current_semaphore->m_semaphore.is_zero_count()) { mark_unused(*m_current_semaphore); return m_current_semaphore; } const tick_count_clock::time_point now = tick_count_clock::now(); semaphore_info_list::iterator it = m_semaphore_info_list.begin(), end = m_semaphore_info_list.end(); while (it != end) { if (is_overflow_less(m_next_semaphore_id, it->m_id) || m_next_semaphore_id == it->m_id) m_next_semaphore_id = it->m_id + 1u; if (it->m_semaphore.is_zero_count()) { semaphore_info& info = *it; mark_unused(info); return &info; } else if (it->check_non_zero_timeout(now)) { // The semaphore is non-zero for too long. A blocked process must have crashed. Close it. m_semaphore_info_set.erase(m_semaphore_info_set.iterator_to(*it)); m_semaphore_info_list.erase_and_dispose(it++, boost::checked_deleter< semaphore_info >()); } else { ++it; } } // No semaphore found, create a new one for (uint32_t semaphore_id = m_next_semaphore_id, semaphore_id_end = semaphore_id - 1u; semaphore_id != semaphore_id_end; ++semaphore_id) { interprocess_semaphore sem; try { generate_semaphore_name(semaphore_id); sem.create_or_open(m_semaphore_name.c_str(), m_perms); if (!sem.is_zero_count()) continue; } catch (...) { // Ignore errors, try the next one continue; } semaphore_info* p = NULL; semaphore_info_set::insert_commit_data insert_state; std::pair< semaphore_info_set::iterator, bool > res = m_semaphore_info_set.insert_check(semaphore_id, semaphore_info::order_by_id(), insert_state); if (res.second) { p = new semaphore_info(semaphore_id); p->m_semaphore.swap(sem); res.first = m_semaphore_info_set.insert_commit(*p, insert_state); m_semaphore_info_list.push_back(*p); } else { // Some of our currently open semaphores must have been released by another thread p = &*res.first; mark_unused(*p); } m_next_semaphore_id = semaphore_id + 1u; return p; } BOOST_LOG_THROW_DESCR(limitation_error, "Too many semaphores are actively used for an interprocess condition variable"); BOOST_LOG_UNREACHABLE_RETURN(NULL); }