1*99451b44SJordan Rupprecht #ifndef LLDB_TEST_API_COMMON_H
2*99451b44SJordan Rupprecht #define LLDB_TEST_API_COMMON_H
3*99451b44SJordan Rupprecht 
4*99451b44SJordan Rupprecht #include <condition_variable>
5*99451b44SJordan Rupprecht #include <chrono>
6*99451b44SJordan Rupprecht #include <exception>
7*99451b44SJordan Rupprecht #include <iostream>
8*99451b44SJordan Rupprecht #include <mutex>
9*99451b44SJordan Rupprecht #include <string>
10*99451b44SJordan Rupprecht #include <queue>
11*99451b44SJordan Rupprecht 
12*99451b44SJordan Rupprecht #include <unistd.h>
13*99451b44SJordan Rupprecht 
14*99451b44SJordan Rupprecht /// Simple exception class with a message
15*99451b44SJordan Rupprecht struct Exception : public std::exception
16*99451b44SJordan Rupprecht {
17*99451b44SJordan Rupprecht   std::string s;
ExceptionException18*99451b44SJordan Rupprecht   Exception(std::string ss) : s(ss) {}
~ExceptionException19*99451b44SJordan Rupprecht   virtual ~Exception() throw () { }
whatException20*99451b44SJordan Rupprecht   const char* what() const throw() { return s.c_str(); }
21*99451b44SJordan Rupprecht };
22*99451b44SJordan Rupprecht 
23*99451b44SJordan Rupprecht // Synchronized data structure for listener to send events through
24*99451b44SJordan Rupprecht template<typename T>
25*99451b44SJordan Rupprecht class multithreaded_queue {
26*99451b44SJordan Rupprecht   std::condition_variable m_condition;
27*99451b44SJordan Rupprecht   std::mutex m_mutex;
28*99451b44SJordan Rupprecht   std::queue<T> m_data;
29*99451b44SJordan Rupprecht   bool m_notified;
30*99451b44SJordan Rupprecht 
31*99451b44SJordan Rupprecht public:
32*99451b44SJordan Rupprecht 
push(T e)33*99451b44SJordan Rupprecht   void push(T e) {
34*99451b44SJordan Rupprecht     std::lock_guard<std::mutex> lock(m_mutex);
35*99451b44SJordan Rupprecht     m_data.push(e);
36*99451b44SJordan Rupprecht     m_notified = true;
37*99451b44SJordan Rupprecht     m_condition.notify_all();
38*99451b44SJordan Rupprecht   }
39*99451b44SJordan Rupprecht 
pop(int timeout_seconds,bool & success)40*99451b44SJordan Rupprecht   T pop(int timeout_seconds, bool &success) {
41*99451b44SJordan Rupprecht     int count = 0;
42*99451b44SJordan Rupprecht     while (count < timeout_seconds) {
43*99451b44SJordan Rupprecht       std::unique_lock<std::mutex> lock(m_mutex);
44*99451b44SJordan Rupprecht       if (!m_data.empty()) {
45*99451b44SJordan Rupprecht         m_notified = false;
46*99451b44SJordan Rupprecht         T ret = m_data.front();
47*99451b44SJordan Rupprecht         m_data.pop();
48*99451b44SJordan Rupprecht         success = true;
49*99451b44SJordan Rupprecht         return ret;
50*99451b44SJordan Rupprecht       } else if (!m_notified)
51*99451b44SJordan Rupprecht         m_condition.wait_for(lock, std::chrono::seconds(1));
52*99451b44SJordan Rupprecht       count ++;
53*99451b44SJordan Rupprecht     }
54*99451b44SJordan Rupprecht     success = false;
55*99451b44SJordan Rupprecht     return T();
56*99451b44SJordan Rupprecht   }
57*99451b44SJordan Rupprecht };
58*99451b44SJordan Rupprecht 
59*99451b44SJordan Rupprecht /// Allocates a char buffer with the current working directory
get_working_dir()60*99451b44SJordan Rupprecht inline char* get_working_dir() {
61*99451b44SJordan Rupprecht #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
62*99451b44SJordan Rupprecht     return getwd(0);
63*99451b44SJordan Rupprecht #else
64*99451b44SJordan Rupprecht     return get_current_dir_name();
65*99451b44SJordan Rupprecht #endif
66*99451b44SJordan Rupprecht }
67*99451b44SJordan Rupprecht 
68*99451b44SJordan Rupprecht #endif // LLDB_TEST_API_COMMON_H
69