Skip to content

Commit

Permalink
Merge pull request #50 from nmcclatchey/winver_check
Browse files Browse the repository at this point in the history
Descriptive error on insufficient Windows version.
  • Loading branch information
alxvasilev authored Feb 7, 2019
2 parents cb28f8b + a2c801d commit 2d0b10a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
19 changes: 13 additions & 6 deletions mingw.condition_variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
#include "mingw.mutex.h"
#include "mingw.shared_mutex.h"

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher.
#endif

namespace mingw_stdthread
{
#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)
Expand Down Expand Up @@ -280,7 +284,8 @@ class condition_variable

bool wait_impl (unique_lock<xp::mutex> & lock, DWORD time)
{
static_assert(std::is_same<typename xp::mutex::native_handle_type, PCRITICAL_SECTION>::value,
using mutex_handle_type = typename xp::mutex::native_handle_type;
static_assert(std::is_same<mutex_handle_type, PCRITICAL_SECTION>::value,
"Native Win32 condition variable requires std::mutex to \
use native Win32 critical section objects.");
xp::mutex * pmutex = lock.release();
Expand All @@ -298,7 +303,13 @@ use native Win32 critical section objects.");
before_wait(pmutex);
BOOL success = SleepConditionVariableSRW( native_handle(),
pmutex->native_handle(),
time, 0);
time,
// CONDITION_VARIABLE_LOCKMODE_SHARED has a value not specified by
// Microsoft's Dev Center, but is known to be (convertible to) a ULONG. To
// ensure that the value passed to this function is not equal to Microsoft's
// constant, we can either use a static_assert, or simply generate an
// appropriate value.
!CONDITION_VARIABLE_LOCKMODE_SHARED);
after_wait(pmutex);
return success;
}
Expand Down Expand Up @@ -414,10 +425,6 @@ class condition_variable_any
// Some shared_mutex functionality is available even in Vista, but it's not
// until Windows 7 that a full implementation is natively possible. The class
// itself is defined, with missing features, at the Vista feature level.
static_assert(CONDITION_VARIABLE_LOCKMODE_SHARED != 0, "The flag \
CONDITION_VARIABLE_LOCKMODE_SHARED is not defined as expected. The value for \
exclusive mode is unknown (not specified by Microsoft Dev Center), but assumed \
to be 0. There is a conflict with CONDITION_VARIABLE_LOCKMODE_SHARED.");
bool wait_impl (unique_lock<native_shared_mutex> & lock, DWORD time)
{
native_shared_mutex * pmutex = lock.release();
Expand Down
8 changes: 8 additions & 0 deletions mingw.mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
// Need for the implementation of invoke
#include "mingw.thread.h"

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher.
#endif

namespace mingw_stdthread
{
// The _NonRecursive class has mechanisms that do not play nice with direct
Expand Down Expand Up @@ -161,6 +165,7 @@ class mutex
mutex & operator= (const mutex&) = delete;
void lock (void)
{
// Note: Undefined behavior if called recursively.
#if STDMUTEX_RECURSION_CHECKS
DWORD self = mOwnerThread.checkOwnerBeforeLock();
#endif
Expand Down Expand Up @@ -216,6 +221,9 @@ class mutex
mutex & operator= (const mutex&) = delete;
~mutex() noexcept
{
// Undefined behavior if the mutex is held (locked) by any thread.
// Undefined behavior if a thread terminates while holding ownership of the
// mutex.
DeleteCriticalSection(&mHandle);
}
void lock (void)
Expand Down
4 changes: 4 additions & 0 deletions mingw.shared_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
// Might be able to use native Slim Reader-Writer (SRW) locks.
#ifdef _WIN32
#include <windows.h>

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher.
#endif
#endif

namespace mingw_stdthread
Expand Down
16 changes: 16 additions & 0 deletions mingw.thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
#include <cstdio>
#endif

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher.
#endif

// Instead of INVALID_HANDLE_VALUE, _beginthreadex returns 0.
namespace mingw_stdthread
{
Expand Down Expand Up @@ -220,7 +224,14 @@ class thread
static unsigned int _hardware_concurrency_helper() noexcept
{
SYSTEM_INFO sysinfo;
// This is one of the few functions used by the library which has a nearly-
// equivalent function defined in earlier versions of Windows. Include the
// workaround, just as a reminder that it does exist.
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
::GetNativeSystemInfo(&sysinfo);
#else
::GetSystemInfo(&sysinfo);
#endif
return sysinfo.dwNumberOfProcessors;
}
public:
Expand Down Expand Up @@ -259,6 +270,11 @@ class thread
}

bool joinable() const {return mHandle != kInvalidHandle;}

// Note: Due to lack of synchronization, this function has a race condition
// if called concurrently, which leads to undefined behavior. The same applies
// to all other member functions of this class, but this one is mentioned
// explicitly.
void join()
{
using namespace std;
Expand Down

0 comments on commit 2d0b10a

Please sign in to comment.