A debug-facility that wraps output-stream insertions with synchronization. Code like DebugSync(as_of_join_node) << ... << ... << ... ; will insert to the node's debug-stream and guard all insertions as one operation using the node's debug-mutex. However, it is recommended to use the DEBUG_SYNC macro, defined below it. Code like DEBUG_SYNC(as_of_join_node, ..., ..., ...); will do the same if N
| 160 | // |
| 161 | // DEBUG_SYNC(as_of_join_node, ... , DEBUG_MANIP(std::endl) , ...); |
| 162 | class DebugSync { |
| 163 | public: |
| 164 | explicit DebugSync(AsofJoinNode* node) |
| 165 | : debug_os_(GetDebugStream(node)), |
| 166 | debug_mutex_(GetDebugMutex(node)), |
| 167 | alt_debug_mutex_(), // an alternative debug-mutex, if the node has none |
| 168 | debug_lock_(debug_mutex_ ? *debug_mutex_ : alt_debug_mutex_) { |
| 169 | if (debug_os_) { |
| 170 | std::ios state(NULL); |
| 171 | state.copyfmt(*debug_os_); |
| 172 | (*debug_os_) << "AsofjoinNode(" << std::hex << &node << "): "; |
| 173 | debug_os_->copyfmt(state); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | DebugSync& operator<<(std::ostream& (*pf)(std::ostream&)) { |
| 178 | if (debug_os_) pf(*debug_os_); |
| 179 | return *this; |
| 180 | } |
| 181 | DebugSync& operator<<(std::ios& (*pf)(std::ios&)) { |
| 182 | if (debug_os_) pf(*debug_os_); |
| 183 | return *this; |
| 184 | } |
| 185 | DebugSync& operator<<(std::ios_base& (*pf)(std::ios_base&)) { |
| 186 | if (debug_os_) pf(*debug_os_); |
| 187 | return *this; |
| 188 | } |
| 189 | |
| 190 | // used by DEBUG_MANIP macro below |
| 191 | using Manip = std::function<DebugSync&(DebugSync&)>; |
| 192 | DebugSync& operator<<(Manip f) { return f(*this); } |
| 193 | |
| 194 | template <typename T> |
| 195 | DebugSync& operator<<(T&& value) { |
| 196 | if (debug_os_) (*debug_os_) << value; |
| 197 | return *this; |
| 198 | } |
| 199 | |
| 200 | // used by DEBUG_SYNC macro below |
| 201 | template <typename... Args> |
| 202 | DebugSync& insert(Args&&... args) { |
| 203 | return (*this << ... << args); |
| 204 | } |
| 205 | |
| 206 | private: |
| 207 | std::ostream* debug_os_; |
| 208 | std::mutex* debug_mutex_; |
| 209 | std::mutex alt_debug_mutex_; |
| 210 | std::unique_lock<std::mutex> debug_lock_; |
| 211 | }; |
| 212 | |
| 213 | # define DEBUG_SYNC(node, ...) DebugSync(node).insert(__VA_ARGS__) |
| 214 | # define DEBUG_MANIP(manip) \ |