diff options
| author | Pavel Labath <labath@google.com> | 2015-05-05 15:05:50 +0000 |
|---|---|---|
| committer | Pavel Labath <labath@google.com> | 2015-05-05 15:05:50 +0000 |
| commit | 45f5cb31dcab4a956ababd123628e10fcc810d5b (patch) | |
| tree | 7afb0e321acd7a1b391d09fb056d2a838d740ed1 /lldb/source/Plugins/Process/Linux | |
| parent | 941b743fc9a65d73345560d1695e844a0db1d366 (diff) | |
| download | bcm5719-llvm-45f5cb31dcab4a956ababd123628e10fcc810d5b.tar.gz bcm5719-llvm-45f5cb31dcab4a956ababd123628e10fcc810d5b.zip | |
[NativeProcessLinux] Get rid of the thread state coordinator thread
Summary:
This change removes the thread state coordinator thread by making all the operations it was
performing synchronous. In order to prevent deadlock, NativeProcessLinux must now always call
m_monitor->DoOperation with the m_threads_mutex released. This is needed because HandleWait
callbacks lock the mutex (which means the monitor thread will block waiting on whoever holds the
lock). If the other thread now requests a monitor operation, it will wait for the monitor thread
do process it, creating a deadlock.
To preserve this invariant I have introduced two new Monitor commands: "begin operation block"
and "end operation block". They begin command blocks the monitor from processing waitpid
events until the corresponding end command, thereby assuring the monitor does not attempt to
acquire the mutex.
Test Plan: Run the test suite locally, verify no tests fail.
Reviewers: vharron, chaoren
Subscribers: lldb-commits
Differential Revision: http://reviews.llvm.org/D9227
llvm-svn: 236501
Diffstat (limited to 'lldb/source/Plugins/Process/Linux')
4 files changed, 126 insertions, 253 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index e529867e083..5def42efe78 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1069,7 +1069,6 @@ namespace { PTRACE(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error); } - } // end of anonymous namespace // Simple helper function to ensure flags are enabled on the given file @@ -1105,7 +1104,8 @@ EnsureFDFlags(int fd, int flags) // pipe, and the completion of the operation is signalled over the semaphore. // - thread exit event: this is signaled from the Monitor destructor by closing the write end // of the command pipe. -class NativeProcessLinux::Monitor { +class NativeProcessLinux::Monitor +{ private: // The initial monitor operation (launch or attach). It returns a inferior process id. std::unique_ptr<InitialOperation> m_initial_operation_up; @@ -1124,7 +1124,11 @@ private: sem_t m_operation_sem; Error m_operation_error; - static constexpr char operation_command = 'o'; + unsigned m_operation_nesting_level = 0; + + static constexpr char operation_command = 'o'; + static constexpr char begin_block_command = '{'; + static constexpr char end_block_command = '}'; void HandleSignals(); @@ -1143,7 +1147,22 @@ private: RunMonitor(void *arg); Error - WaitForOperation(); + WaitForAck(); + + void + BeginOperationBlock() + { + write(m_pipefd[WRITE], &begin_block_command, sizeof operation_command); + WaitForAck(); + } + + void + EndOperationBlock() + { + write(m_pipefd[WRITE], &end_block_command, sizeof operation_command); + WaitForAck(); + } + public: Monitor(const InitialOperation &initial_operation, NativeProcessLinux *native_process) @@ -1159,9 +1178,26 @@ public: Initialize(); void + Terminate(); + + void DoOperation(Operation *op); + + class ScopedOperationLock { + Monitor &m_monitor; + + public: + ScopedOperationLock(Monitor &monitor) + : m_monitor(monitor) + { m_monitor.BeginOperationBlock(); } + + ~ScopedOperationLock() + { m_monitor.EndOperationBlock(); } + }; }; constexpr char NativeProcessLinux::Monitor::operation_command; +constexpr char NativeProcessLinux::Monitor::begin_block_command; +constexpr char NativeProcessLinux::Monitor::end_block_command; Error NativeProcessLinux::Monitor::Initialize() @@ -1198,7 +1234,7 @@ NativeProcessLinux::Monitor::Initialize() return Error("Failed to create monitor thread for NativeProcessLinux."); // Wait for initial operation to complete. - return WaitForOperation(); + return WaitForAck(); } void @@ -1218,15 +1254,24 @@ NativeProcessLinux::Monitor::DoOperation(Operation *op) // notify the thread that an operation is ready to be processed write(m_pipefd[WRITE], &operation_command, sizeof operation_command); - WaitForOperation(); + WaitForAck(); } -NativeProcessLinux::Monitor::~Monitor() +void +NativeProcessLinux::Monitor::Terminate() { if (m_pipefd[WRITE] >= 0) + { close(m_pipefd[WRITE]); + m_pipefd[WRITE] = -1; + } if (m_thread.IsJoinable()) m_thread.Join(nullptr); +} + +NativeProcessLinux::Monitor::~Monitor() +{ + Terminate(); if (m_pipefd[READ] >= 0) close(m_pipefd[READ]); if (m_signal_fd >= 0) @@ -1356,6 +1401,7 @@ NativeProcessLinux::Monitor::HandleCommands() { if (log) log->Printf("NativeProcessLinux::Monitor::%s exit command received, exiting...", __FUNCTION__); + assert(m_operation_nesting_level == 0 && "Unbalanced begin/end block commands detected"); return true; // We are done. } @@ -1363,15 +1409,22 @@ NativeProcessLinux::Monitor::HandleCommands() { case operation_command: m_operation->Execute(m_native_process); - - // notify calling thread that operation is complete - sem_post(&m_operation_sem); + break; + case begin_block_command: + ++m_operation_nesting_level; + break; + case end_block_command: + assert(m_operation_nesting_level > 0); + --m_operation_nesting_level; break; default: if (log) log->Printf("NativeProcessLinux::Monitor::%s received unknown command '%c'", __FUNCTION__, command); } + + // notify calling thread that the command has been processed + sem_post(&m_operation_sem); } } @@ -1387,7 +1440,10 @@ NativeProcessLinux::Monitor::MainLoop() { fd_set fds; FD_ZERO(&fds); - FD_SET(m_signal_fd, &fds); + // Only process waitpid events if we are outside of an operation block. Any pending + // events will be processed after we leave the block. + if (m_operation_nesting_level == 0) + FD_SET(m_signal_fd, &fds); FD_SET(m_pipefd[READ], &fds); int max_fd = std::max(m_signal_fd, m_pipefd[READ]) + 1; @@ -1416,7 +1472,7 @@ NativeProcessLinux::Monitor::MainLoop() } Error -NativeProcessLinux::Monitor::WaitForOperation() +NativeProcessLinux::Monitor::WaitForAck() { Error error; while (sem_wait(&m_operation_sem) != 0) @@ -1617,8 +1673,7 @@ NativeProcessLinux::NativeProcessLinux () : m_supports_mem_region (eLazyBoolCalculate), m_mem_region_cache (), m_mem_region_cache_mutex (), - m_coordinator_up (new ThreadStateCoordinator (GetThreadLoggerFunction ())), - m_coordinator_thread () + m_coordinator_up (new ThreadStateCoordinator (GetThreadLoggerFunction ())) { } @@ -1652,10 +1707,6 @@ NativeProcessLinux::LaunchInferior ( StartMonitorThread ([&] (Error &e) { return Launch(args.get(), e); }, error); if (!error.Success ()) return; - - error = StartCoordinatorThread (); - if (!error.Success ()) - return; } void @@ -1705,16 +1756,12 @@ NativeProcessLinux::AttachToInferior (lldb::pid_t pid, Error &error) StartMonitorThread ([=] (Error &e) { return Attach(pid, e); }, error); if (!error.Success ()) return; - - error = StartCoordinatorThread (); - if (!error.Success ()) - return; } void NativeProcessLinux::Terminate () { - StopMonitor(); + m_monitor_up->Terminate(); } ::pid_t @@ -2997,6 +3044,7 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions) bool stepping = false; bool software_single_step = !SupportHardwareSingleStepping(); + Monitor::ScopedOperationLock monitor_lock(*m_monitor_up); Mutex::Locker locker (m_threads_mutex); if (software_single_step) @@ -3144,7 +3192,7 @@ NativeProcessLinux::Detach () error = Detach (GetID ()); // Stop monitoring the inferior. - StopMonitor (); + m_monitor_up->Terminate(); // No error. return error; @@ -3179,6 +3227,7 @@ NativeProcessLinux::Interrupt () if (log) log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__); + Monitor::ScopedOperationLock monitor_lock(*m_monitor_up); Mutex::Locker locker (m_threads_mutex); for (auto thread_sp : m_threads) @@ -3233,6 +3282,7 @@ NativeProcessLinux::Interrupt () // Tell the process delegate that the process is in a stopped state. SetState (StateType::eStateStopped, true); }); + return Error(); } @@ -3834,7 +3884,25 @@ NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info) #endif Error -NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) +NativeProcessLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) +{ + // The base SetWatchpoint will end up executing monitor operations. Let's lock the monitor + // for it. + Monitor::ScopedOperationLock monitor_lock(*m_monitor_up); + return NativeProcessProtocol::SetWatchpoint(addr, size, watch_flags, hardware); +} + +Error +NativeProcessLinux::RemoveWatchpoint (lldb::addr_t addr) +{ + // The base RemoveWatchpoint will end up executing monitor operations. Let's lock the monitor + // for it. + Monitor::ScopedOperationLock monitor_lock(*m_monitor_up); + return NativeProcessProtocol::RemoveWatchpoint(addr); +} + +Error +NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) { ReadOperation op(addr, buf, size, bytes_read); m_monitor_up->DoOperation(&op); @@ -3997,77 +4065,6 @@ NativeProcessLinux::StartMonitorThread(const InitialOperation &initial_operation } } -void -NativeProcessLinux::StopMonitor() -{ - StopCoordinatorThread (); - m_monitor_up.reset(); -} - -Error -NativeProcessLinux::StartCoordinatorThread () -{ - Error error; - static const char *g_thread_name = "lldb.process.linux.ts_coordinator"; - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - - // Skip if thread is already running - if (m_coordinator_thread.IsJoinable()) - { - error.SetErrorString ("ThreadStateCoordinator's run loop is already running"); - if (log) - log->Printf ("NativeProcessLinux::%s %s", __FUNCTION__, error.AsCString ()); - return error; - } - - // Enable verbose logging if lldb thread logging is enabled. - m_coordinator_up->LogEnableEventProcessing (log != nullptr); - - if (log) - log->Printf ("NativeProcessLinux::%s launching ThreadStateCoordinator thread for pid %" PRIu64, __FUNCTION__, GetID ()); - m_coordinator_thread = ThreadLauncher::LaunchThread(g_thread_name, CoordinatorThread, this, &error); - return error; -} - -void * -NativeProcessLinux::CoordinatorThread (void *arg) -{ - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - - NativeProcessLinux *const process = static_cast<NativeProcessLinux*> (arg); - assert (process && "null process passed to CoordinatorThread"); - if (!process) - { - if (log) - log->Printf ("NativeProcessLinux::%s null process, exiting ThreadStateCoordinator processing loop", __FUNCTION__); - return nullptr; - } - - // Run the thread state coordinator loop until it is done. This call uses - // efficient waiting for an event to be ready. - while (process->m_coordinator_up->ProcessNextEvent () == ThreadStateCoordinator::eventLoopResultContinue) - { - } - - if (log) - log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " exiting ThreadStateCoordinator processing loop due to coordinator indicating completion", __FUNCTION__, process->GetID ()); - - return nullptr; -} - -void -NativeProcessLinux::StopCoordinatorThread() -{ - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - if (log) - log->Printf ("NativeProcessLinux::%s requesting ThreadStateCoordinator stop for pid %" PRIu64, __FUNCTION__, GetID ()); - - // Tell the coordinator we're done. This will cause the coordinator - // run loop thread to exit when the processing queue hits this message. - m_coordinator_up->StopCoordinator (); - m_coordinator_thread.Join (nullptr); -} - bool NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id) { diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 5c1f712d9b4..a35f0a731b7 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -110,6 +110,12 @@ namespace process_linux { Error SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override; + Error + SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override; + + Error + RemoveWatchpoint (lldb::addr_t addr) override; + void DoStopIDBumped (uint32_t newBumpId) override; @@ -185,7 +191,6 @@ namespace process_linux { Mutex m_mem_region_cache_mutex; std::unique_ptr<ThreadStateCoordinator> m_coordinator_up; - HostThread m_coordinator_thread; // List of thread ids stepping with a breakpoint with the address of // the relevan breakpoint @@ -303,19 +308,6 @@ namespace process_linux { GetCrashReasonForSIGBUS(const siginfo_t *info); #endif - Error - StartCoordinatorThread (); - - static void* - CoordinatorThread (void *arg); - - void - StopCoordinatorThread (); - - /// Stops monitoring the child process thread. - void - StopMonitor(); - bool HasThreadNoLock (lldb::tid_t thread_id); diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp index da1c33f64fd..438c1423bf6 100644 --- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp +++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp @@ -46,29 +46,6 @@ public: //===----------------------------------------------------------------------===// -class ThreadStateCoordinator::EventStopCoordinator : public ThreadStateCoordinator::EventBase -{ -public: - EventStopCoordinator (): - EventBase () - { - } - - EventLoopResult - ProcessEvent(ThreadStateCoordinator &coordinator) override - { - return eventLoopResultStop; - } - - std::string - GetDescription () override - { - return "EventStopCoordinator"; - } -}; - -//===----------------------------------------------------------------------===// - class ThreadStateCoordinator::EventCallAfterThreadsStop : public ThreadStateCoordinator::EventBase { public: @@ -588,42 +565,12 @@ private: ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) : m_log_function (log_function), - m_event_queue (), - m_queue_condition (), - m_queue_mutex (), m_tid_map (), m_log_event_processing (false) { } void -ThreadStateCoordinator::EnqueueEvent (EventBaseSP event_sp) -{ - std::lock_guard<std::mutex> lock (m_queue_mutex); - - m_event_queue.push (event_sp); - if (m_log_event_processing) - Log ("ThreadStateCoordinator::%s enqueued event: %s", __FUNCTION__, event_sp->GetDescription ().c_str ()); - - m_queue_condition.notify_one (); -} - -ThreadStateCoordinator::EventBaseSP -ThreadStateCoordinator::DequeueEventWithWait () -{ - // Wait for an event to be present. - std::unique_lock<std::mutex> lock (m_queue_mutex); - m_queue_condition.wait (lock, - [this] { return !m_event_queue.empty (); }); - - // Grab the event and pop it off the queue. - EventBaseSP event_sp = m_event_queue.front (); - m_event_queue.pop (); - - return event_sp; -} - -void ThreadStateCoordinator::SetPendingNotification (const EventBaseSP &event_sp) { assert (event_sp && "null event_sp"); @@ -653,11 +600,11 @@ ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid, const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - wait_for_stop_tids, - request_thread_stop_function, - call_after_function, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + wait_for_stop_tids, + request_thread_stop_function, + call_after_function, + error_function))); } void @@ -666,10 +613,10 @@ ThreadStateCoordinator::CallAfterRunningThreadsStop (const lldb::tid_t triggerin const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - request_thread_stop_function, - call_after_function, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + request_thread_stop_function, + call_after_function, + error_function))); } void @@ -679,11 +626,11 @@ ThreadStateCoordinator::CallAfterRunningThreadsStopWithSkipTIDs (lldb::tid_t tri const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - request_thread_stop_function, - call_after_function, - skip_stop_request_tids, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + request_thread_stop_function, + call_after_function, + skip_stop_request_tids, + error_function))); } @@ -826,7 +773,7 @@ ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid, bool initiated_by_llgs, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadStopped (tid, initiated_by_llgs, error_function))); + ProcessEvent(EventBaseSP(new EventThreadStopped (tid, initiated_by_llgs, error_function))); } void @@ -834,7 +781,7 @@ ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid, const ResumeThreadFunction &request_thread_resume_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, true))); + ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, true))); } void @@ -842,7 +789,7 @@ ThreadStateCoordinator::RequestThreadResumeAsNeeded (lldb::tid_t tid, const ResumeThreadFunction &request_thread_resume_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, false))); + ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, false))); } void @@ -850,56 +797,26 @@ ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid, bool is_stopped, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadCreate (tid, is_stopped, error_function))); + ProcessEvent(EventBaseSP(new EventThreadCreate (tid, is_stopped, error_function))); } void ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadDeath (tid, error_function))); + ProcessEvent(EventBaseSP(new EventThreadDeath (tid, error_function))); } void ThreadStateCoordinator::ResetForExec () { - std::lock_guard<std::mutex> lock (m_queue_mutex); - - // Remove everything from the queue. This is the only - // state mutation that takes place outside the processing - // loop. - QueueType empty_queue; - m_event_queue.swap (empty_queue); - - // Do the real clear behavior on the the queue to eliminate - // the chance that processing of a dequeued earlier event is - // overlapping with the clearing of state here. Push it - // directly because we need to have this happen with the lock, - // and so far I only have this one place that needs a no-lock - // variant. - m_event_queue.push (EventBaseSP (new EventReset ())); + ProcessEvent(EventBaseSP(new EventReset())); } void -ThreadStateCoordinator::StopCoordinator () +ThreadStateCoordinator::ProcessEvent (const EventBaseSP &event_sp) { - EnqueueEvent (EventBaseSP (new EventStopCoordinator ())); -} - -ThreadStateCoordinator::EventLoopResult -ThreadStateCoordinator::ProcessNextEvent () -{ - // Dequeue the next event, synchronous. - if (m_log_event_processing) - Log ("ThreadStateCoordinator::%s about to dequeue next event in blocking mode", __FUNCTION__); - - EventBaseSP event_sp = DequeueEventWithWait(); - assert (event_sp && "event should never be null"); - if (!event_sp) - { - Log ("ThreadStateCoordinator::%s error: event_sp was null, signaling exit of event loop.", __FUNCTION__); - return eventLoopResultStop; - } + std::lock_guard<std::mutex> lock(m_event_mutex); if (m_log_event_processing) { @@ -907,15 +824,12 @@ ThreadStateCoordinator::ProcessNextEvent () } // Process the event. - const EventLoopResult result = event_sp->ProcessEvent (*this); + event_sp->ProcessEvent (*this); if (m_log_event_processing) { - Log ("ThreadStateCoordinator::%s event processing returned value %s", __FUNCTION__, - result == eventLoopResultContinue ? "eventLoopResultContinue" : "eventLoopResultStop"); + Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__); } - - return result; } void diff --git a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h index 17184f6f80a..e5883bdb84f 100644 --- a/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h +++ b/lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h @@ -10,10 +10,8 @@ #ifndef lldb_ThreadStateCoordinator_h #define lldb_ThreadStateCoordinator_h -#include <condition_variable> #include <functional> #include <mutex> -#include <queue> #include <unordered_map> #include <unordered_set> @@ -126,24 +124,9 @@ namespace process_linux { // Indicate the calling process did an exec and that the thread state // should be 100% cleared. - // - // Note this will clear out any pending notifications, but will not stop - // a notification currently in progress via ProcessNextEvent(). void ResetForExec (); - // Indicate when the coordinator should shut down. - void - StopCoordinator (); - - // Process the next event, returning false when the coordinator is all done. - // This call is synchronous and blocks when there are no events pending. - // Expected usage is to run this in a separate thread until the function - // returns false. Always call this from the same thread. The processing - // logic assumes the execution of this is implicitly serialized. - EventLoopResult - ProcessNextEvent (); - // Enable/disable verbose logging of event processing. void LogEnableEventProcessing (bool enabled); @@ -159,13 +142,10 @@ namespace process_linux { class EventThreadDeath; class EventRequestResume; - class EventStopCoordinator; class EventReset; typedef std::shared_ptr<EventBase> EventBaseSP; - typedef std::queue<EventBaseSP> QueueType; - enum class ThreadState { Running, @@ -181,12 +161,10 @@ namespace process_linux { typedef std::unordered_map<lldb::tid_t, ThreadContext> TIDContextMap; - // Private member functions. - void - EnqueueEvent (EventBaseSP event_sp); + std::mutex m_event_mutex; // Serializes execution of ProcessEvent. - EventBaseSP - DequeueEventWithWait (); + void + ProcessEvent (const EventBaseSP &event_sp); void SetPendingNotification (const EventBaseSP &event_sp); @@ -215,14 +193,6 @@ namespace process_linux { // Member variables. LogFunction m_log_function; - QueueType m_event_queue; - // For now we do simple read/write lock strategy with efficient wait-for-data. - // We can replace with an entirely non-blocking queue later but we still want the - // reader to sleep when nothing is available - this will be a bursty but infrequent - // event mechanism. - std::condition_variable m_queue_condition; - std::mutex m_queue_mutex; - EventBaseSP m_pending_notification_sp; // Maps known TIDs to ThreadContext. |

