/*!
  * The callback for less relation filter
  */
 virtual filter on_less_relation(attribute_name const& name, string_type const& arg)
 {
     BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less attribute value relation is not supported", (name));
     BOOST_LOG_UNREACHABLE_RETURN(filter());
 }
Beispiel #2
0
//! 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);
}
 /*!
  * The callback for custom relation filter
  */
 virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg)
 {
     BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(arg) + "\" is not supported", (name));
     BOOST_LOG_UNREACHABLE_RETURN(filter());
 }