Removed the requirement of std::mutex from shaderc.
Once support in mingw is improved, we can switch back to std::mutex.
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index 45f579a..eb2b40b 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -92,18 +92,21 @@
set(TEST_NAME ${PARSED_ARGS_TEST_PREFIX}_${TARGET}_test)
add_executable(${TEST_NAME} src/${TARGET}_test.cc)
shaderc_default_compile_options(${TEST_NAME})
+ if (MINGW)
+ target_compile_options(${TARGET} PRIVATE -DSHADERC_DISABLE_THREADED_TESTS)
+ endif()
if (PARSED_ARGS_LINK_LIBS)
- target_link_libraries(${TEST_NAME} PRIVATE
- ${PARSED_ARGS_LINK_LIBS})
+ target_link_libraries(${TEST_NAME} PRIVATE
+ ${PARSED_ARGS_LINK_LIBS})
endif()
if (PARSED_ARGS_INCLUDE_DIRS)
- target_include_directories(${TEST_NAME} PRIVATE
- ${PARSED_ARGS_INCLUDE_DIRS})
+ target_include_directories(${TEST_NAME} PRIVATE
+ ${PARSED_ARGS_INCLUDE_DIRS})
endif()
shaderc_use_gmock(${TEST_NAME})
add_test(
- NAME ${PARSED_ARGS_TEST_PREFIX}_${TARGET}
- COMMAND ${TEST_NAME})
+ NAME ${PARSED_ARGS_TEST_PREFIX}_${TARGET}
+ COMMAND ${TEST_NAME})
endforeach()
endif(${SHADERC_ENABLE_TESTS})
endfunction(shaderc_add_tests)
diff --git a/libshaderc_util/CMakeLists.txt b/libshaderc_util/CMakeLists.txt
index c6a4cc2..c94dd1b 100644
--- a/libshaderc_util/CMakeLists.txt
+++ b/libshaderc_util/CMakeLists.txt
@@ -5,6 +5,7 @@
include/libshaderc_util/file_finder.h
include/libshaderc_util/format.h
include/libshaderc_util/io.h
+ include/libshaderc_util/mutex.h
include/libshaderc_util/message.h
include/libshaderc_util/resources.h
include/libshaderc_util/string_piece.h
@@ -36,7 +37,8 @@
format
file_finder
io
- message)
+ message
+ mutex)
if(${SHADERC_ENABLE_TESTS})
target_include_directories(shaderc_util_counting_includer_test
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
index d0dc909..cb7c320 100644
--- a/libshaderc_util/include/libshaderc_util/compiler.h
+++ b/libshaderc_util/include/libshaderc_util/compiler.h
@@ -16,7 +16,6 @@
#define LIBSHADERC_UTIL_INC_COMPILER_H
#include <functional>
-#include <mutex>
#include <ostream>
#include <string>
#include <unordered_map>
@@ -26,6 +25,7 @@
#include "counting_includer.h"
#include "file_finder.h"
+#include "mutex.h"
#include "string_piece.h"
namespace shaderc_util {
@@ -90,7 +90,7 @@
friend class InitializationToken;
EShMessages last_messages_;
- std::mutex state_lock_;
+ mutex state_lock_;
};
// Maps macro names to their definitions. Stores string_pieces, so the
diff --git a/libshaderc_util/include/libshaderc_util/mutex.h b/libshaderc_util/include/libshaderc_util/mutex.h
new file mode 100644
index 0000000..34a5290
--- /dev/null
+++ b/libshaderc_util/include/libshaderc_util/mutex.h
@@ -0,0 +1,104 @@
+// Copyright 2015 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef LIBSHADERC_UTIL_INC_MUTEX_H
+#define LIBSHADERC_UTIL_INC_MUTEX_H
+
+// shaderc_util::mutex will be defined and specialized
+// depending on the platform that is being compiled.
+// It is more or less conformant to the C++11 specification of std::mutex.
+// However it does not implement try_lock.
+
+#ifdef _WIN32
+// windows.h #defines min and max if we don't define this.
+// this means things like std::min and std::max break
+#define NOMINMAX
+#include <windows.h>
+namespace shaderc_util {
+
+// As the name suggests, this mutex class is for running on windows.
+// It conforms to the c++11 mutex implementation, and should be a
+// drop in replacement.
+class windows_mutex {
+ public:
+ using native_handle_type = HANDLE;
+
+ windows_mutex() { mutex_ = CreateMutex(nullptr, false, nullptr); }
+
+ ~windows_mutex() {
+ if (mutex_ != INVALID_HANDLE_VALUE) {
+ CloseHandle(mutex_);
+ }
+ }
+
+ windows_mutex(const windows_mutex&) = delete;
+ windows_mutex& operator=(const windows_mutex&) = delete;
+
+ // Locks this mutex, waiting until the mutex is unlocked if it is not already.
+ // It is not valid to lock a mutex that has already been locked.
+ void lock() { WaitForSingleObject(mutex_, INFINITE); }
+
+ // Unlocks this mutex. It is invalid to unlock a mutex that this thread
+ // has not already locked.
+ void unlock() { ReleaseMutex(mutex_); }
+
+ // Returns the native handle for this mutex. In this case a HANDLE object.
+ native_handle_type native_handle() { return mutex_; }
+
+ private:
+ HANDLE mutex_;
+};
+
+using mutex = windows_mutex;
+}
+
+#else
+#include <pthread.h>
+#include <memory>
+namespace shaderc_util {
+
+// As the name suggests, this mutex class is for running with pthreads.
+// It conforms to the c++11 mutex implementation, and should be a
+// drop in replacement.
+class posix_mutex {
+ public:
+ using native_handle_type = pthread_mutex_t*;
+
+ posix_mutex() { pthread_mutex_init(&mutex_, nullptr); }
+
+ ~posix_mutex() { pthread_mutex_destroy(&mutex_); }
+
+ posix_mutex(const posix_mutex&) = delete;
+ posix_mutex& operator=(const posix_mutex&) = delete;
+
+ // Locks this mutex, waiting until the mutex is unlocked if it is not already.
+ // It is not valid to lock a mutex that has already been locked.
+ void lock() { pthread_mutex_lock(&mutex_); }
+
+ // Unlocks this mutex. It is invalid to unlock a mutex that this thread
+ // has not already locked.
+ void unlock() { pthread_mutex_unlock(&mutex_); }
+
+ // Returns the native handle for this mutex. In this case a pthread_mutex_t*.
+ native_handle_type native_handle() { return &mutex_; }
+
+ private:
+ pthread_mutex_t mutex_;
+};
+
+using mutex = posix_mutex;
+}
+#endif
+
+#endif // LIBSHADERC_UTIL_INC_MUTEX_H
diff --git a/libshaderc_util/src/counting_includer_test.cc b/libshaderc_util/src/counting_includer_test.cc
index b618605..1f452e4 100644
--- a/libshaderc_util/src/counting_includer_test.cc
+++ b/libshaderc_util/src/counting_includer_test.cc
@@ -54,6 +54,7 @@
EXPECT_EQ(100, includer.num_include_directives());
}
+#ifndef SHADERC_DISABLE_THREADED_TESTS
TEST(CountingIncluderTest, ThreadedIncludes) {
ConcreteCountingIncluder includer;
std::thread t1([&includer]() { includer.include("name1"); });
@@ -64,5 +65,6 @@
t3.join();
EXPECT_EQ(3, includer.num_include_directives());
}
+#endif // SHADERC_DISABLE_THREADED_TESTS
} // anonymous namespace
diff --git a/libshaderc_util/src/mutex_test.cc b/libshaderc_util/src/mutex_test.cc
new file mode 100644
index 0000000..1892089
--- /dev/null
+++ b/libshaderc_util/src/mutex_test.cc
@@ -0,0 +1,51 @@
+// Copyright 2015 The Shaderc Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "libshaderc_util/mutex.h"
+
+#include <gmock/gmock.h>
+#include <thread>
+
+namespace {
+
+TEST(MutexTest, CanCreateMutex) {
+ shaderc_util::mutex mutex;
+ mutex.lock();
+ mutex.unlock();
+}
+
+#ifndef SHADERC_DISABLE_THREADED_TESTS
+
+void increment_by_1000(shaderc_util::mutex& mut, int& i) {
+ for(size_t j = 0; j < 1000; ++j) {
+ mut.lock();
+ i = i + 1;
+ mut.unlock();
+ }
+}
+
+TEST(MutexTest, MutexLocks) {
+ shaderc_util::mutex mutex;
+ int i = 0;
+ std::thread t1([&mutex, &i]() { increment_by_1000(mutex, i); });
+ std::thread t2([&mutex, &i]() { increment_by_1000(mutex, i); });
+ std::thread t3([&mutex, &i]() { increment_by_1000(mutex, i); });
+ t1.join();
+ t2.join();
+ t3.join();
+ EXPECT_EQ(3000, i);
+}
+#endif // SHADERC_DISABLE_THREADED_TESTS
+
+} // anonymous namespace