Beispiel #1
0
    BOOST_LOG_ONCE_BLOCK()
    {
        if (!InitializeSecurityDescriptor(&g_unrestricted_security_descriptor, SECURITY_DESCRIPTOR_REVISION))
        {
            DWORD err = GetLastError();
            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to initialize security descriptor", (err));
        }

        if (!SetSecurityDescriptorDacl(&g_unrestricted_security_descriptor, TRUE, NULL, FALSE))
        {
            DWORD err = GetLastError();
            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to set null DACL to a security descriptor", (err));
        }

        g_unrestricted_security_attributes.nLength = sizeof(g_unrestricted_security_attributes);
        g_unrestricted_security_attributes.lpSecurityDescriptor = &g_unrestricted_security_descriptor;
        g_unrestricted_security_attributes.bInheritHandle = FALSE;
    }
Beispiel #2
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_;
}
Beispiel #3
0
void interprocess_semaphore::open(const wchar_t* name)
{
    boost::detail::winapi::HANDLE_ h = boost::detail::winapi::OpenSemaphoreW(boost::detail::winapi::SYNCHRONIZE_ | boost::detail::winapi::SEMAPHORE_MODIFY_STATE_ | boost::detail::winapi::SEMAPHORE_QUERY_STATE_, false, name);
    if (BOOST_UNLIKELY(h == NULL))
    {
        const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
        BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, "Failed to open an interprocess semaphore object", (err));
    }

    m_sem.init(h);
}
Beispiel #4
0
bool interprocess_semaphore::is_semaphore_zero_count_emulated(boost::detail::winapi::HANDLE_ h)
{
    const boost::detail::winapi::DWORD_ retval = boost::detail::winapi::WaitForSingleObject(h, 0u);
    if (retval == boost::detail::winapi::wait_timeout)
    {
        return true;
    }
    else if (BOOST_UNLIKELY(retval != boost::detail::winapi::wait_object_0))
    {
        const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
        BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, "Failed to test an interprocess semaphore object for zero count", (err));
    }

    // Restore the decremented counter
    BOOST_VERIFY(!!boost::detail::winapi::ReleaseSemaphore(h, 1, NULL));

    return false;
}
Beispiel #5
0
bool interprocess_semaphore::is_semaphore_zero_count_nt_query_semaphore(boost::detail::winapi::HANDLE_ h)
{
    semaphore_basic_information info = {};
    NTSTATUS_ err = nt_query_semaphore
    (
        h,
        0u, // SemaphoreBasicInformation
        &info,
        sizeof(info),
        NULL
    );
    if (BOOST_UNLIKELY(err != 0u))
    {
        char buf[sizeof(unsigned int) * 2u + 4u];
        boost::log::aux::snprintf(buf, sizeof(buf), "0x%08x", static_cast< unsigned int >(err));
        BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, std::string("Failed to test an interprocess semaphore object for zero count, NT status: ") + buf, (ERROR_INVALID_HANDLE));
    }

    return info.current_count == 0u;
}
Beispiel #6
0
void interprocess_semaphore::create_or_open(const wchar_t* name, permissions const& perms)
{
#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
    boost::detail::winapi::HANDLE_ h = boost::detail::winapi::CreateSemaphoreExW
    (
        reinterpret_cast< boost::detail::winapi::SECURITY_ATTRIBUTES_* >(perms.get_native()),
        0, // initial count
        (std::numeric_limits< boost::detail::winapi::LONG_ >::max)(), // max count
        name,
        0u, // flags
        boost::detail::winapi::SYNCHRONIZE_ | boost::detail::winapi::SEMAPHORE_MODIFY_STATE_ | boost::detail::winapi::SEMAPHORE_QUERY_STATE_
    );
#else
    boost::detail::winapi::HANDLE_ h = boost::detail::winapi::CreateSemaphoreW
    (
        reinterpret_cast< boost::detail::winapi::SECURITY_ATTRIBUTES_* >(perms.get_native()),
        0, // initial count
        (std::numeric_limits< boost::detail::winapi::LONG_ >::max)(), // max count
        name
    );
#endif
    if (h == NULL)
    {
        boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
        if (BOOST_LIKELY(err == ERROR_ALREADY_EXISTS))
        {
            open(name);
            return;
        }
        else
        {
            BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, "Failed to create an interprocess semaphore object", (err));
        }
    }

    m_sem.init(h);
}
 /*!
  * The callback for greater relation filter
  */
 virtual filter on_greater_relation(attribute_name const& name, string_type const& arg)
 {
     BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater attribute value relation is not supported", (name));
     BOOST_LOG_UNREACHABLE();
 }
 /*!
  * 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();
 }
 /*!
  * 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());
 }