Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:36

0001 //
0002 // detail/impl/win_static_mutex.ipp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 
0020 #if defined(BOOST_ASIO_WINDOWS)
0021 
0022 #include <cstdio>
0023 #include <boost/asio/detail/throw_error.hpp>
0024 #include <boost/asio/detail/win_static_mutex.hpp>
0025 #include <boost/asio/error.hpp>
0026 
0027 #include <boost/asio/detail/push_options.hpp>
0028 
0029 namespace boost {
0030 namespace asio {
0031 namespace detail {
0032 
0033 void win_static_mutex::init()
0034 {
0035   int error = do_init();
0036   boost::system::error_code ec(error,
0037       boost::asio::error::get_system_category());
0038   boost::asio::detail::throw_error(ec, "static_mutex");
0039 }
0040 
0041 int win_static_mutex::do_init()
0042 {
0043   using namespace std; // For sprintf.
0044   wchar_t mutex_name[128];
0045 #if defined(BOOST_ASIO_HAS_SECURE_RTL)
0046   swprintf_s(
0047 #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
0048   _snwprintf(
0049 #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
0050       mutex_name, 128, L"asio-58CCDC44-6264-4842-90C2-F3C545CB8AA7-%u-%p",
0051       static_cast<unsigned int>(::GetCurrentProcessId()), this);
0052 
0053 #if defined(BOOST_ASIO_WINDOWS_APP)
0054   HANDLE mutex = ::CreateMutexExW(0, mutex_name, CREATE_MUTEX_INITIAL_OWNER, 0);
0055 #else // defined(BOOST_ASIO_WINDOWS_APP)
0056   HANDLE mutex = ::CreateMutexW(0, TRUE, mutex_name);
0057 #endif // defined(BOOST_ASIO_WINDOWS_APP)
0058   DWORD last_error = ::GetLastError();
0059   if (mutex == 0)
0060     return ::GetLastError();
0061 
0062   if (last_error == ERROR_ALREADY_EXISTS)
0063   {
0064 #if defined(BOOST_ASIO_WINDOWS_APP)
0065     ::WaitForSingleObjectEx(mutex, INFINITE, false);
0066 #else // defined(BOOST_ASIO_WINDOWS_APP)
0067     ::WaitForSingleObject(mutex, INFINITE);
0068 #endif // defined(BOOST_ASIO_WINDOWS_APP)
0069   }
0070 
0071   if (initialised_)
0072   {
0073     ::ReleaseMutex(mutex);
0074     ::CloseHandle(mutex);
0075     return 0;
0076   }
0077 
0078 #if defined(__MINGW32__)
0079   // Not sure if MinGW supports structured exception handling, so for now
0080   // we'll just call the Windows API and hope.
0081 # if defined(UNDER_CE)
0082   ::InitializeCriticalSection(&crit_section_);
0083 # else
0084   if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000))
0085   {
0086     last_error = ::GetLastError();
0087     ::ReleaseMutex(mutex);
0088     ::CloseHandle(mutex);
0089     return last_error;
0090   }
0091 # endif
0092 #else
0093   __try
0094   {
0095 # if defined(UNDER_CE)
0096     ::InitializeCriticalSection(&crit_section_);
0097 # elif defined(BOOST_ASIO_WINDOWS_APP)
0098     if (!::InitializeCriticalSectionEx(&crit_section_, 0, 0))
0099     {
0100       last_error = ::GetLastError();
0101       ::ReleaseMutex(mutex);
0102       ::CloseHandle(mutex);
0103       return last_error;
0104     }
0105 # else
0106     if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000))
0107     {
0108       last_error = ::GetLastError();
0109       ::ReleaseMutex(mutex);
0110       ::CloseHandle(mutex);
0111       return last_error;
0112     }
0113 # endif
0114   }
0115   __except(GetExceptionCode() == STATUS_NO_MEMORY
0116       ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
0117   {
0118     ::ReleaseMutex(mutex);
0119     ::CloseHandle(mutex);
0120     return ERROR_OUTOFMEMORY;
0121   }
0122 #endif
0123 
0124   initialised_ = true;
0125   ::ReleaseMutex(mutex);
0126   ::CloseHandle(mutex);
0127   return 0;
0128 }
0129 
0130 } // namespace detail
0131 } // namespace asio
0132 } // namespace boost
0133 
0134 #include <boost/asio/detail/pop_options.hpp>
0135 
0136 #endif // defined(BOOST_ASIO_WINDOWS)
0137 
0138 #endif // BOOST_ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP