diff options
author | Kenneth Heafield <github@kheafield.com> | 2014-01-28 04:51:35 +0400 |
---|---|---|
committer | Kenneth Heafield <github@kheafield.com> | 2014-01-28 04:51:35 +0400 |
commit | 14e02978fcbbe9ec6ed3faa232fcb3f30664f40e (patch) | |
tree | 0b0d19a9c1ba1020ae6b3f1230b8b5b9e6a945f9 /util/pcqueue.hh | |
parent | b68a906fdd97c344ce7d6fa90a2db5a79c5853e6 (diff) |
KenLM 5cc905bc2d214efa7de2db56a9a672b749a95591
Avoid unspecified behavior of mmap when a file is resized reported by Christian Hardmeier
Fixes for Mavericks and a workaround for Boost's broken semaphore
Clean clang compile (of kenlm)
Merged some of 744376b3fbebc41c4a270bf549826d5eb9219ae0 but also undid some of it because it was just masking a fundaemntal problem with pread rather than working around windows limitations
Diffstat (limited to 'util/pcqueue.hh')
-rw-r--r-- | util/pcqueue.hh | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/util/pcqueue.hh b/util/pcqueue.hh index 3df8749b1..07e4146f5 100644 --- a/util/pcqueue.hh +++ b/util/pcqueue.hh @@ -1,6 +1,8 @@ #ifndef UTIL_PCQUEUE__ #define UTIL_PCQUEUE__ +#include "util/exception.hh" + #include <boost/interprocess/sync/interprocess_semaphore.hpp> #include <boost/scoped_array.hpp> #include <boost/thread/mutex.hpp> @@ -8,20 +10,68 @@ #include <errno.h> +#ifdef __APPLE__ +#include <mach/semaphore.h> +#include <mach/task.h> +#include <mach/mach_traps.h> +#include <mach/mach.h> +#endif // __APPLE__ + namespace util { -inline void WaitSemaphore (boost::interprocess::interprocess_semaphore &on) { +/* OS X Maverick and Boost interprocess were doing "Function not implemented." + * So this is my own wrapper around the mach kernel APIs. + */ +#ifdef __APPLE__ + +#define MACH_CALL(call) UTIL_THROW_IF(KERN_SUCCESS != (call), Exception, "Mach call failure") + +class Semaphore { + public: + explicit Semaphore(int value) : task_(mach_task_self()) { + MACH_CALL(semaphore_create(task_, &back_, SYNC_POLICY_FIFO, value)); + } + + ~Semaphore() { + MACH_CALL(semaphore_destroy(task_, back_)); + } + + void wait() { + MACH_CALL(semaphore_wait(back_)); + } + + void post() { + MACH_CALL(semaphore_signal(back_)); + } + + private: + semaphore_t back_; + task_t task_; +}; + +inline void WaitSemaphore(Semaphore &semaphore) { + semaphore.wait(); +} + +#else +typedef boost::interprocess::interprocess_semaphore Semaphore; + +inline void WaitSemaphore (Semaphore &on) { while (1) { try { on.wait(); break; } catch (boost::interprocess::interprocess_exception &e) { - if (e.get_native_error() != EINTR) throw; + if (e.get_native_error() != EINTR) { + throw; + } } } } +#endif // __APPLE__ + /* Producer consumer queue safe for multiple producers and multiple consumers. * T must be default constructable and have operator=. * The value is copied twice for Consume(T &out) or three times for Consume(), @@ -82,9 +132,9 @@ template <class T> class PCQueue : boost::noncopyable { private: // Number of empty spaces in storage_. - boost::interprocess::interprocess_semaphore empty_; + Semaphore empty_; // Number of occupied spaces in storage_. - boost::interprocess::interprocess_semaphore used_; + Semaphore used_; boost::scoped_array<T> storage_; |