#ifndef RAY_UTILS_H #define RAY_UTILS_H #include #include template class Synchronized; template class Synchronized; // Prevent use of const T; it doesn't make sense template struct SynchronizedSource { typedef Synchronized type; }; template struct SynchronizedSource { typedef const Synchronized type; }; template struct SynchronizedSource { typedef volatile Synchronized type; }; template struct SynchronizedSource { typedef const Synchronized type; }; template class SynchronizedPtr : public std::unique_lock::type> { protected: typedef std::unique_lock::type> base_type; // Make these private; they don't make much sense externally... using base_type::mutex; public: typedef T value_type; SynchronizedPtr(typename base_type::mutex_type& value) : base_type(value) { } value_type& operator*() const { return *mutex()->unsafe_get(); } value_type* operator->() const { return mutex() ? mutex()->unsafe_get() : NULL; } }; template class Synchronized { T value_; public: typedef T element_type; template Synchronized(U&&... args) : value_(std::forward(args)...) { } Synchronized(const Synchronized& other) : value_((std::lock_guard(other), other.value_)) { } Synchronized(Synchronized&& other) : value_((std::lock_guard(other), std::move(other.value_))) { } Synchronized& operator =(const Synchronized& other) { if (this != &other) { std::lock_guard guard_this(*this); std::lock_guard guard_other(other); value_ = other.value_; } return *this; } Synchronized& operator =(Synchronized&& other) { if (this != &other) { std::lock_guard guard_this(*this); std::lock_guard guard_other(other); value_ = std::move(other.value_); } return *this; } virtual void lock() const = 0; virtual void unlock() const = 0; virtual bool try_lock() const = 0; element_type* unsafe_get() { return &value_; } const element_type* unsafe_get() const { return &value_; } }; template class Synchronized { mutable Mutex mutex_; public: typedef Mutex mutex_type; void lock() const { return mutex_.lock(); } void unlock() const { return mutex_.unlock(); } bool try_lock() const { return mutex_.try_lock(); } }; template class Synchronized : public Synchronized, public Synchronized { typedef Synchronized base1_type; typedef Synchronized base2_type; public: template Synchronized(U&&... args) : base1_type(std::forward(args)...), base2_type() { } SynchronizedPtr unchecked_get() { return *this; } SynchronizedPtr unchecked_get() const { return *this; } void lock() const override { return base2_type::lock(); } void unlock() const override { return base2_type::unlock(); } bool try_lock() const override { return base2_type::try_lock(); } }; std::string::iterator split_ip_address(std::string& ip_address); const char* get_cmd_option(char** begin, char** end, const std::string& option); void create_log_dir_or_die(const char* log_file_name); #endif