Skip to content

Commit 9d37c41

Browse files
committedMay 6, 2015
[ThreadStateCoordinator] Remove Event classes
Summary: This is a cleanup patch for thread state coordinator. After making processing of all events synchronous, there is no need to have a a separate class for each event. I have moved back processing of all events back into the TSC class. No functional change. Test Plan: All tests continue to pass. Reviewers: chaoren, vharron Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D9254 llvm-svn: 236576
1 parent e340f85 commit 9d37c41

File tree

2 files changed

+399
-614
lines changed

2 files changed

+399
-614
lines changed
 

‎lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.cpp

+322-583
Original file line numberDiff line numberDiff line change
@@ -24,618 +24,281 @@ using namespace lldb_private::process_linux;
2424

2525
//===----------------------------------------------------------------------===//
2626

27-
class ThreadStateCoordinator::EventBase : public std::enable_shared_from_this<ThreadStateCoordinator::EventBase>
28-
{
29-
public:
30-
EventBase ()
31-
{
32-
}
33-
34-
virtual
35-
~EventBase ()
36-
{
37-
}
38-
39-
virtual std::string
40-
GetDescription () = 0;
41-
42-
// Return false if the coordinator should terminate running.
43-
virtual EventLoopResult
44-
ProcessEvent (ThreadStateCoordinator &coordinator) = 0;
45-
};
46-
47-
//===----------------------------------------------------------------------===//
48-
49-
class ThreadStateCoordinator::EventCallAfterThreadsStop : public ThreadStateCoordinator::EventBase
27+
void
28+
ThreadStateCoordinator::DoResume(
29+
lldb::tid_t tid,
30+
ResumeThreadFunction request_thread_resume_function,
31+
ErrorFunction error_function,
32+
bool error_when_already_running)
5033
{
51-
public:
52-
EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
53-
const ThreadIDSet &wait_for_stop_tids,
54-
const StopThreadFunction &request_thread_stop_function,
55-
const ThreadIDFunction &call_after_function,
56-
const ErrorFunction &error_function):
57-
EventBase (),
58-
m_triggering_tid (triggering_tid),
59-
m_wait_for_stop_tids (wait_for_stop_tids),
60-
m_original_wait_for_stop_tids (wait_for_stop_tids),
61-
m_request_thread_stop_function (request_thread_stop_function),
62-
m_call_after_function (call_after_function),
63-
m_error_function (error_function),
64-
m_request_stop_on_all_unstopped_threads (false),
65-
m_skip_stop_request_tids ()
66-
{
67-
}
68-
69-
EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
70-
const StopThreadFunction &request_thread_stop_function,
71-
const ThreadIDFunction &call_after_function,
72-
const ErrorFunction &error_function) :
73-
EventBase (),
74-
m_triggering_tid (triggering_tid),
75-
m_wait_for_stop_tids (),
76-
m_original_wait_for_stop_tids (),
77-
m_request_thread_stop_function (request_thread_stop_function),
78-
m_call_after_function (call_after_function),
79-
m_error_function (error_function),
80-
m_request_stop_on_all_unstopped_threads (true),
81-
m_skip_stop_request_tids ()
82-
{
83-
}
84-
85-
EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
86-
const StopThreadFunction &request_thread_stop_function,
87-
const ThreadIDFunction &call_after_function,
88-
const ThreadIDSet &skip_stop_request_tids,
89-
const ErrorFunction &error_function) :
90-
EventBase (),
91-
m_triggering_tid (triggering_tid),
92-
m_wait_for_stop_tids (),
93-
m_original_wait_for_stop_tids (),
94-
m_request_thread_stop_function (request_thread_stop_function),
95-
m_call_after_function (call_after_function),
96-
m_error_function (error_function),
97-
m_request_stop_on_all_unstopped_threads (true),
98-
m_skip_stop_request_tids (skip_stop_request_tids)
99-
{
100-
}
101-
102-
lldb::tid_t GetTriggeringTID () const
103-
{
104-
return m_triggering_tid;
105-
}
106-
107-
ThreadIDSet &
108-
GetRemainingWaitTIDs ()
109-
{
110-
return m_wait_for_stop_tids;
111-
}
112-
113-
const ThreadIDSet &
114-
GetRemainingWaitTIDs () const
115-
{
116-
return m_wait_for_stop_tids;
117-
}
118-
119-
120-
const ThreadIDSet &
121-
GetInitialWaitTIDs () const
34+
// Ensure we know about the thread.
35+
auto find_it = m_tid_map.find (tid);
36+
if (find_it == m_tid_map.end ())
12237
{
123-
return m_original_wait_for_stop_tids;
38+
// We don't know about this thread. This is an error condition.
39+
std::ostringstream error_message;
40+
error_message << "error: tid " << tid << " asked to resume but tid is unknown";
41+
error_function (error_message.str ());
42+
return;
12443
}
125-
126-
EventLoopResult
127-
ProcessEvent(ThreadStateCoordinator &coordinator) override
128-
{
129-
// Validate we know about the deferred trigger thread.
130-
if (!coordinator.IsKnownThread (m_triggering_tid))
131-
{
132-
// We don't know about this thread. This is an error condition.
133-
std::ostringstream error_message;
134-
error_message << "error: deferred notification tid " << m_triggering_tid << " is unknown";
135-
m_error_function (error_message.str ());
136-
137-
// We bail out here.
138-
return eventLoopResultContinue;
139-
}
140-
141-
if (m_request_stop_on_all_unstopped_threads)
142-
{
143-
RequestStopOnAllRunningThreads (coordinator);
144-
}
145-
else
146-
{
147-
if (!RequestStopOnAllSpecifiedThreads (coordinator))
148-
return eventLoopResultContinue;
149-
}
150-
151-
if (m_wait_for_stop_tids.empty ())
44+
auto& context = find_it->second;
45+
// Tell the thread to resume if we don't already think it is running.
46+
const bool is_stopped = context.m_state == ThreadState::Stopped;
47+
if (!is_stopped)
48+
{
49+
// It's not an error, just a log, if the error_when_already_running flag is not set.
50+
// This covers cases where, for instance, we're just trying to resume all threads
51+
// from the user side.
52+
if (!error_when_already_running)
15253
{
153-
// We're not waiting for any threads. Fire off the deferred signal delivery event.
154-
NotifyNow ();
54+
Log ("ThreadStateCoordinator::%s tid %" PRIu64 " optional resume skipped since it is already running",
55+
__FUNCTION__,
56+
tid);
15557
}
15658
else
15759
{
158-
// The real meat of this class: wait until all
159-
// the thread stops (or thread deaths) come in
160-
// before firing off that the triggering signal
161-
// arrived.
162-
coordinator.SetPendingNotification (shared_from_this ());
60+
// Skip the resume call - we have tracked it to be running. And we unconditionally
61+
// expected to resume this thread. Flag this as an error.
62+
std::ostringstream error_message;
63+
error_message << "error: tid " << tid << " asked to resume but we think it is already running";
64+
error_function (error_message.str ());
16365
}
16466

165-
return eventLoopResultContinue;
67+
// Error or not, we're done.
68+
return;
16669
}
16770

168-
// Return true if still pending thread stops waiting; false if no more stops.
169-
// If no more pending stops, signal.
170-
bool
171-
RemoveThreadStopRequirementAndMaybeSignal (lldb::tid_t tid)
71+
// Before we do the resume below, first check if we have a pending
72+
// stop notification this is currently or was previously waiting for
73+
// this thread to stop. This is potentially a buggy situation since
74+
// we're ostensibly waiting for threads to stop before we send out the
75+
// pending notification, and here we are resuming one before we send
76+
// out the pending stop notification.
77+
if (m_pending_notification_up)
17278
{
173-
// Remove this tid if it was in it.
174-
m_wait_for_stop_tids.erase (tid);
175-
176-
// Fire pending notification if no pending thread stops remain.
177-
if (m_wait_for_stop_tids.empty ())
79+
if (m_pending_notification_up->wait_for_stop_tids.count (tid) > 0)
17880
{
179-
// Fire the pending notification now.
180-
NotifyNow ();
181-
return false;
81+
Log ("ThreadStateCoordinator::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, tid, m_pending_notification_up->triggering_tid);
18282
}
183-
184-
// Still have pending thread stops.
185-
return true;
186-
}
187-
188-
void
189-
AddThreadStopRequirement (lldb::tid_t tid)
190-
{
191-
// Add this tid.
192-
auto insert_result = m_wait_for_stop_tids.insert (tid);
193-
194-
// If it was really added, send the stop request to it.
195-
if (insert_result.second)
196-
m_request_thread_stop_function (tid);
197-
}
198-
199-
std::string
200-
GetDescription () override
201-
{
202-
std::ostringstream description;
203-
description << "EventCallAfterThreadsStop (triggering_tid=" << m_triggering_tid << ", request_stop_on_all_unstopped_threads=" << m_request_stop_on_all_unstopped_threads << ", skip_stop_request_tids.size()=" << m_skip_stop_request_tids.size () << ")";
204-
return description.str ();
205-
}
206-
207-
private:
208-
209-
void
210-
NotifyNow ()
211-
{
212-
m_call_after_function (m_triggering_tid);
213-
}
214-
215-
bool
216-
RequestStopOnAllSpecifiedThreads (ThreadStateCoordinator &coordinator)
217-
{
218-
// Request a stop for all the thread stops that need to be stopped
219-
// and are not already known to be stopped. Keep a list of all the
220-
// threads from which we still need to hear a stop reply.
221-
222-
ThreadIDSet sent_tids;
223-
for (auto tid : m_wait_for_stop_tids)
83+
else if (m_pending_notification_up->original_wait_for_stop_tids.count (tid) > 0)
22484
{
225-
// Validate we know about all tids for which we must first receive a stop before
226-
// triggering the deferred stop notification.
227-
auto find_it = coordinator.m_tid_map.find (tid);
228-
if (find_it == coordinator.m_tid_map.end ())
85+
Log ("ThreadStateCoordinator::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that hasn't fired yet and this is one of the threads we had been waiting on (and already marked satisfied for this tid). Valid sequence of events?", __FUNCTION__, tid, m_pending_notification_up->triggering_tid);
86+
for (auto tid : m_pending_notification_up->wait_for_stop_tids)
22987
{
230-
// This is an error. We shouldn't be asking for waiting pids that aren't known.
231-
// NOTE: we may be stripping out the specification of wait tids and handle this
232-
// automatically, in which case this state can never occur.
233-
std::ostringstream error_message;
234-
error_message << "error: deferred notification for tid " << m_triggering_tid << " specified an unknown/untracked pending stop tid " << m_triggering_tid;
235-
m_error_function (error_message.str ());
236-
237-
// Bail out here.
238-
return false;
239-
}
240-
241-
// If the pending stop thread is currently running, we need to send it a stop request.
242-
auto& context = find_it->second;
243-
if (context.m_state == ThreadState::Running)
244-
{
245-
RequestThreadStop (tid, coordinator, context);
246-
sent_tids.insert (tid);
88+
Log ("ThreadStateCoordinator::%s tid %" PRIu64 " deferred stop notification still waiting on tid %" PRIu64,
89+
__FUNCTION__,
90+
m_pending_notification_up->triggering_tid,
91+
tid);
24792
}
24893
}
249-
250-
// We only need to wait for the sent_tids - so swap our wait set
251-
// to the sent tids. The rest are already stopped and we won't
252-
// be receiving stop notifications for them.
253-
m_wait_for_stop_tids.swap (sent_tids);
254-
255-
// Succeeded, keep running.
256-
return true;
25794
}
25895

259-
void
260-
RequestStopOnAllRunningThreads (ThreadStateCoordinator &coordinator)
96+
// Request a resume. We expect this to be synchronous and the system
97+
// to reflect it is running after this completes.
98+
const auto error = request_thread_resume_function (tid, false);
99+
if (error.Success ())
261100
{
262-
// Request a stop for all the thread stops that need to be stopped
263-
// and are not already known to be stopped. Keep a list of all the
264-
// threads from which we still need to hear a stop reply.
265-
266-
ThreadIDSet sent_tids;
267-
for (auto it = coordinator.m_tid_map.begin(); it != coordinator.m_tid_map.end(); ++it)
268-
{
269-
// We only care about threads not stopped.
270-
const bool running = it->second.m_state == ThreadState::Running;
271-
if (running)
272-
{
273-
const lldb::tid_t tid = it->first;
274-
275-
// Request this thread stop if the tid stop request is not explicitly ignored.
276-
const bool skip_stop_request = m_skip_stop_request_tids.count (tid) > 0;
277-
if (!skip_stop_request)
278-
RequestThreadStop (tid, coordinator, it->second);
279-
280-
// Even if we skipped sending the stop request for other reasons (like stepping),
281-
// we still need to wait for that stepping thread to notify completion/stop.
282-
sent_tids.insert (tid);
283-
}
284-
}
285-
286-
// Set the wait list to the set of tids for which we requested stops.
287-
m_wait_for_stop_tids.swap (sent_tids);
101+
// Now mark it is running.
102+
context.m_state = ThreadState::Running;
103+
context.m_request_resume_function = request_thread_resume_function;
288104
}
289-
290-
void
291-
RequestThreadStop (lldb::tid_t tid, ThreadStateCoordinator &coordinator, ThreadContext& context)
105+
else
292106
{
293-
const auto error = m_request_thread_stop_function (tid);
294-
if (error.Success ())
295-
{
296-
context.m_stop_requested = true;
297-
}
298-
else
299-
{
300-
coordinator.Log ("EventCallAfterThreadsStop::%s failed to request thread stop tid %" PRIu64 ": %s",
301-
__FUNCTION__, tid, error.AsCString ());
302-
}
107+
Log ("ThreadStateCoordinator::%s failed to resume thread tid %" PRIu64 ": %s",
108+
__FUNCTION__, tid, error.AsCString ());
303109
}
304110

305-
const lldb::tid_t m_triggering_tid;
306-
ThreadIDSet m_wait_for_stop_tids;
307-
const ThreadIDSet m_original_wait_for_stop_tids;
308-
StopThreadFunction m_request_thread_stop_function;
309-
ThreadIDFunction m_call_after_function;
310-
ErrorFunction m_error_function;
311-
const bool m_request_stop_on_all_unstopped_threads;
312-
ThreadIDSet m_skip_stop_request_tids;
313-
};
111+
return;
112+
}
314113

315114
//===----------------------------------------------------------------------===//
316115

317-
class ThreadStateCoordinator::EventReset : public ThreadStateCoordinator::EventBase
116+
ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) :
117+
m_log_function (log_function),
118+
m_tid_map (),
119+
m_log_event_processing (false)
318120
{
319-
public:
320-
EventReset ():
321-
EventBase ()
322-
{
323-
}
121+
}
324122

325-
EventLoopResult
326-
ProcessEvent(ThreadStateCoordinator &coordinator) override
327-
{
328-
coordinator.ResetNow ();
329-
return eventLoopResultContinue;
330-
}
123+
void
124+
ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid,
125+
const ThreadIDSet &wait_for_stop_tids,
126+
const StopThreadFunction &request_thread_stop_function,
127+
const ThreadIDFunction &call_after_function,
128+
const ErrorFunction &error_function)
129+
{
130+
std::lock_guard<std::mutex> lock(m_event_mutex);
331131

332-
std::string
333-
GetDescription () override
132+
if (m_log_event_processing)
334133
{
335-
return "EventReset";
134+
Log ("ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 ", wait_for_stop_tids.size(): %zd)",
135+
__FUNCTION__, triggering_tid, wait_for_stop_tids.size());
336136
}
337-
};
338137

339-
//===----------------------------------------------------------------------===//
138+
DoCallAfterThreadsStop(PendingNotificationUP(new PendingNotification(
139+
triggering_tid, wait_for_stop_tids, request_thread_stop_function,
140+
call_after_function, error_function)));
340141

341-
class ThreadStateCoordinator::EventThreadStopped : public ThreadStateCoordinator::EventBase
342-
{
343-
public:
344-
EventThreadStopped (lldb::tid_t tid,
345-
bool initiated_by_llgs,
346-
const ErrorFunction &error_function):
347-
EventBase (),
348-
m_tid (tid),
349-
m_initiated_by_llgs (initiated_by_llgs),
350-
m_error_function (error_function)
142+
if (m_log_event_processing)
351143
{
144+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
352145
}
146+
}
353147

354-
EventLoopResult
355-
ProcessEvent(ThreadStateCoordinator &coordinator) override
356-
{
357-
coordinator.ThreadDidStop (m_tid, m_initiated_by_llgs, m_error_function);
358-
return eventLoopResultContinue;
359-
}
148+
void
149+
ThreadStateCoordinator::CallAfterRunningThreadsStop (const lldb::tid_t triggering_tid,
150+
const StopThreadFunction &request_thread_stop_function,
151+
const ThreadIDFunction &call_after_function,
152+
const ErrorFunction &error_function)
153+
{
154+
std::lock_guard<std::mutex> lock(m_event_mutex);
360155

361-
std::string
362-
GetDescription () override
156+
if (m_log_event_processing)
363157
{
364-
std::ostringstream description;
365-
description << "EventThreadStopped (tid=" << m_tid << ")";
366-
return description.str ();
158+
Log ("ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 ")",
159+
__FUNCTION__, triggering_tid);
367160
}
368161

369-
private:
370-
371-
const lldb::tid_t m_tid;
372-
const bool m_initiated_by_llgs;
373-
ErrorFunction m_error_function;
374-
};
375-
376-
//===----------------------------------------------------------------------===//
162+
DoCallAfterThreadsStop(PendingNotificationUP(new PendingNotification(
163+
triggering_tid,
164+
request_thread_stop_function,
165+
call_after_function,
166+
error_function)));
377167

378-
class ThreadStateCoordinator::EventThreadCreate : public ThreadStateCoordinator::EventBase
379-
{
380-
public:
381-
EventThreadCreate (lldb::tid_t tid,
382-
bool is_stopped,
383-
const ErrorFunction &error_function):
384-
EventBase (),
385-
m_tid (tid),
386-
m_is_stopped (is_stopped),
387-
m_error_function (error_function)
168+
if (m_log_event_processing)
388169
{
170+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
389171
}
172+
}
390173

391-
EventLoopResult
392-
ProcessEvent(ThreadStateCoordinator &coordinator) override
393-
{
394-
coordinator.ThreadWasCreated (m_tid, m_is_stopped, m_error_function);
395-
return eventLoopResultContinue;
396-
}
174+
void
175+
ThreadStateCoordinator::CallAfterRunningThreadsStopWithSkipTIDs (lldb::tid_t triggering_tid,
176+
const ThreadIDSet &skip_stop_request_tids,
177+
const StopThreadFunction &request_thread_stop_function,
178+
const ThreadIDFunction &call_after_function,
179+
const ErrorFunction &error_function)
180+
{
181+
std::lock_guard<std::mutex> lock(m_event_mutex);
397182

398-
std::string
399-
GetDescription () override
183+
if (m_log_event_processing)
400184
{
401-
std::ostringstream description;
402-
description << "EventThreadCreate (tid=" << m_tid << ", " << (m_is_stopped ? "stopped" : "running") << ")";
403-
return description.str ();
185+
Log ("ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 ", skip_stop_request_tids.size(): %zd)",
186+
__FUNCTION__, triggering_tid, skip_stop_request_tids.size());
404187
}
405188

406-
private:
407-
408-
const lldb::tid_t m_tid;
409-
const bool m_is_stopped;
410-
ErrorFunction m_error_function;
411-
};
412-
413-
//===----------------------------------------------------------------------===//
414-
415-
class ThreadStateCoordinator::EventThreadDeath : public ThreadStateCoordinator::EventBase
416-
{
417-
public:
418-
EventThreadDeath (lldb::tid_t tid,
419-
const ErrorFunction &error_function):
420-
EventBase (),
421-
m_tid (tid),
422-
m_error_function (error_function)
423-
{
424-
}
189+
DoCallAfterThreadsStop(PendingNotificationUP(new PendingNotification(
190+
triggering_tid,
191+
request_thread_stop_function,
192+
call_after_function,
193+
skip_stop_request_tids,
194+
error_function)));
425195

426-
EventLoopResult
427-
ProcessEvent(ThreadStateCoordinator &coordinator) override
196+
if (m_log_event_processing)
428197
{
429-
coordinator.ThreadDidDie (m_tid, m_error_function);
430-
return eventLoopResultContinue;
198+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
431199
}
200+
}
432201

433-
std::string
434-
GetDescription () override
202+
void
203+
ThreadStateCoordinator::SignalIfRequirementsSatisfied()
204+
{
205+
if (m_pending_notification_up && m_pending_notification_up->wait_for_stop_tids.empty ())
435206
{
436-
std::ostringstream description;
437-
description << "EventThreadDeath (tid=" << m_tid << ")";
438-
return description.str ();
207+
m_pending_notification_up->call_after_function(m_pending_notification_up->triggering_tid);
208+
m_pending_notification_up.reset();
439209
}
210+
}
440211

441-
private:
442-
443-
const lldb::tid_t m_tid;
444-
ErrorFunction m_error_function;
445-
};
446-
447-
//===----------------------------------------------------------------------===//
448-
449-
class ThreadStateCoordinator::EventRequestResume : public ThreadStateCoordinator::EventBase
212+
bool
213+
ThreadStateCoordinator::RequestStopOnAllSpecifiedThreads()
450214
{
451-
public:
452-
EventRequestResume (lldb::tid_t tid,
453-
const ResumeThreadFunction &request_thread_resume_function,
454-
const ErrorFunction &error_function,
455-
bool error_when_already_running):
456-
EventBase (),
457-
m_tid (tid),
458-
m_request_thread_resume_function (request_thread_resume_function),
459-
m_error_function (error_function),
460-
m_error_when_already_running (error_when_already_running)
461-
{
462-
}
215+
// Request a stop for all the thread stops that need to be stopped
216+
// and are not already known to be stopped. Keep a list of all the
217+
// threads from which we still need to hear a stop reply.
463218

464-
EventLoopResult
465-
ProcessEvent(ThreadStateCoordinator &coordinator) override
219+
ThreadIDSet sent_tids;
220+
for (auto tid : m_pending_notification_up->wait_for_stop_tids)
466221
{
467-
// Ensure we know about the thread.
468-
auto find_it = coordinator.m_tid_map.find (m_tid);
469-
if (find_it == coordinator.m_tid_map.end ())
222+
// Validate we know about all tids for which we must first receive a stop before
223+
// triggering the deferred stop notification.
224+
auto find_it = m_tid_map.find (tid);
225+
if (find_it == m_tid_map.end ())
470226
{
471-
// We don't know about this thread. This is an error condition.
227+
// This is an error. We shouldn't be asking for waiting pids that aren't known.
228+
// NOTE: we may be stripping out the specification of wait tids and handle this
229+
// automatically, in which case this state can never occur.
472230
std::ostringstream error_message;
473-
error_message << "error: tid " << m_tid << " asked to resume but tid is unknown";
474-
m_error_function (error_message.str ());
475-
return eventLoopResultContinue;
476-
}
477-
auto& context = find_it->second;
478-
// Tell the thread to resume if we don't already think it is running.
479-
const bool is_stopped = context.m_state == ThreadState::Stopped;
480-
if (!is_stopped)
481-
{
482-
// It's not an error, just a log, if the m_already_running_no_error flag is set.
483-
// This covers cases where, for instance, we're just trying to resume all threads
484-
// from the user side.
485-
if (!m_error_when_already_running)
486-
{
487-
coordinator.Log ("EventRequestResume::%s tid %" PRIu64 " optional resume skipped since it is already running",
488-
__FUNCTION__,
489-
m_tid);
490-
}
491-
else
492-
{
493-
// Skip the resume call - we have tracked it to be running. And we unconditionally
494-
// expected to resume this thread. Flag this as an error.
495-
std::ostringstream error_message;
496-
error_message << "error: tid " << m_tid << " asked to resume but we think it is already running";
497-
m_error_function (error_message.str ());
498-
}
499-
500-
// Error or not, we're done.
501-
return eventLoopResultContinue;
502-
}
231+
error_message << "error: deferred notification for tid " << m_pending_notification_up->triggering_tid << " specified an unknown/untracked pending stop tid " << m_pending_notification_up->triggering_tid;
232+
m_pending_notification_up->error_function (error_message.str ());
503233

504-
// Before we do the resume below, first check if we have a pending
505-
// stop notification this is currently or was previously waiting for
506-
// this thread to stop. This is potentially a buggy situation since
507-
// we're ostensibly waiting for threads to stop before we send out the
508-
// pending notification, and here we are resuming one before we send
509-
// out the pending stop notification.
510-
const EventCallAfterThreadsStop *const pending_stop_notification = coordinator.GetPendingThreadStopNotification ();
511-
if (pending_stop_notification)
512-
{
513-
if (pending_stop_notification->GetRemainingWaitTIDs ().count (m_tid) > 0)
514-
{
515-
coordinator.Log ("EventRequestResume::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, m_tid, pending_stop_notification->GetTriggeringTID ());
516-
}
517-
else if (pending_stop_notification->GetInitialWaitTIDs ().count (m_tid) > 0)
518-
{
519-
coordinator.Log ("EventRequestResume::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that hasn't fired yet and this is one of the threads we had been waiting on (and already marked satisfied for this tid). Valid sequence of events?", __FUNCTION__, m_tid, pending_stop_notification->GetTriggeringTID ());
520-
for (auto tid : pending_stop_notification->GetRemainingWaitTIDs ())
521-
{
522-
coordinator.Log ("EventRequestResume::%s tid %" PRIu64 " deferred stop notification still waiting on tid %" PRIu64,
523-
__FUNCTION__,
524-
pending_stop_notification->GetTriggeringTID (),
525-
tid);
526-
}
527-
}
234+
// Bail out here.
235+
return false;
528236
}
529237

530-
// Request a resume. We expect this to be synchronous and the system
531-
// to reflect it is running after this completes.
532-
const auto error = m_request_thread_resume_function (m_tid, false);
533-
if (error.Success ())
534-
{
535-
// Now mark it is running.
536-
context.m_state = ThreadState::Running;
537-
context.m_request_resume_function = m_request_thread_resume_function;
538-
}
539-
else
238+
// If the pending stop thread is currently running, we need to send it a stop request.
239+
auto& context = find_it->second;
240+
if (context.m_state == ThreadState::Running)
540241
{
541-
coordinator.Log ("EventRequestResume::%s failed to resume thread tid %" PRIu64 ": %s",
542-
__FUNCTION__, m_tid, error.AsCString ());
242+
RequestThreadStop (tid, context);
243+
sent_tids.insert (tid);
543244
}
544-
545-
return eventLoopResultContinue;
546245
}
246+
// We only need to wait for the sent_tids - so swap our wait set
247+
// to the sent tids. The rest are already stopped and we won't
248+
// be receiving stop notifications for them.
249+
m_pending_notification_up->wait_for_stop_tids.swap (sent_tids);
547250

548-
std::string
549-
GetDescription () override
550-
{
551-
std::ostringstream description;
552-
description << "EventRequestResume (tid=" << m_tid << ")";
553-
return description.str ();
554-
}
555-
556-
private:
557-
558-
const lldb::tid_t m_tid;
559-
ResumeThreadFunction m_request_thread_resume_function;
560-
ErrorFunction m_error_function;
561-
const bool m_error_when_already_running;
562-
};
563-
564-
//===----------------------------------------------------------------------===//
565-
566-
ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) :
567-
m_log_function (log_function),
568-
m_tid_map (),
569-
m_log_event_processing (false)
570-
{
251+
// Succeeded, keep running.
252+
return true;
571253
}
572254

573255
void
574-
ThreadStateCoordinator::SetPendingNotification (const EventBaseSP &event_sp)
256+
ThreadStateCoordinator::RequestStopOnAllRunningThreads()
575257
{
576-
assert (event_sp && "null event_sp");
577-
if (!event_sp)
578-
return;
258+
// Request a stop for all the thread stops that need to be stopped
259+
// and are not already known to be stopped. Keep a list of all the
260+
// threads from which we still need to hear a stop reply.
579261

580-
const EventCallAfterThreadsStop *new_call_after_event = static_cast<EventCallAfterThreadsStop*> (event_sp.get ());
581-
582-
EventCallAfterThreadsStop *const prev_call_after_event = GetPendingThreadStopNotification ();
583-
if (prev_call_after_event)
262+
ThreadIDSet sent_tids;
263+
for (auto it = m_tid_map.begin(); it != m_tid_map.end(); ++it)
584264
{
585-
// Yikes - we've already got a pending signal notification in progress.
586-
// Log this info. We lose the pending notification here.
587-
Log ("ThreadStateCoordinator::%s dropping existing pending signal notification for tid %" PRIu64 ", to be replaced with signal for tid %" PRIu64,
588-
__FUNCTION__,
589-
prev_call_after_event->GetTriggeringTID (),
590-
new_call_after_event->GetTriggeringTID ());
591-
}
265+
// We only care about threads not stopped.
266+
const bool running = it->second.m_state == ThreadState::Running;
267+
if (running)
268+
{
269+
const lldb::tid_t tid = it->first;
592270

593-
m_pending_notification_sp = event_sp;
594-
}
271+
// Request this thread stop if the tid stop request is not explicitly ignored.
272+
const bool skip_stop_request = m_pending_notification_up->skip_stop_request_tids.count (tid) > 0;
273+
if (!skip_stop_request)
274+
RequestThreadStop (tid, it->second);
595275

596-
void
597-
ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid,
598-
const ThreadIDSet &wait_for_stop_tids,
599-
const StopThreadFunction &request_thread_stop_function,
600-
const ThreadIDFunction &call_after_function,
601-
const ErrorFunction &error_function)
602-
{
603-
ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid,
604-
wait_for_stop_tids,
605-
request_thread_stop_function,
606-
call_after_function,
607-
error_function)));
608-
}
276+
// Even if we skipped sending the stop request for other reasons (like stepping),
277+
// we still need to wait for that stepping thread to notify completion/stop.
278+
sent_tids.insert (tid);
279+
}
280+
}
609281

610-
void
611-
ThreadStateCoordinator::CallAfterRunningThreadsStop (const lldb::tid_t triggering_tid,
612-
const StopThreadFunction &request_thread_stop_function,
613-
const ThreadIDFunction &call_after_function,
614-
const ErrorFunction &error_function)
615-
{
616-
ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid,
617-
request_thread_stop_function,
618-
call_after_function,
619-
error_function)));
282+
// Set the wait list to the set of tids for which we requested stops.
283+
m_pending_notification_up->wait_for_stop_tids.swap (sent_tids);
620284
}
621285

622286
void
623-
ThreadStateCoordinator::CallAfterRunningThreadsStopWithSkipTIDs (lldb::tid_t triggering_tid,
624-
const ThreadIDSet &skip_stop_request_tids,
625-
const StopThreadFunction &request_thread_stop_function,
626-
const ThreadIDFunction &call_after_function,
627-
const ErrorFunction &error_function)
287+
ThreadStateCoordinator::RequestThreadStop (lldb::tid_t tid, ThreadContext& context)
628288
{
629-
ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid,
630-
request_thread_stop_function,
631-
call_after_function,
632-
skip_stop_request_tids,
633-
error_function)));
289+
const auto error = m_pending_notification_up->request_thread_stop_function (tid);
290+
if (error.Success ())
291+
context.m_stop_requested = true;
292+
else
293+
{
294+
Log ("ThreadStateCoordinator::%s failed to request thread stop tid %" PRIu64 ": %s",
295+
__FUNCTION__, tid, error.AsCString ());
296+
}
634297
}
635298

636299

637300
void
638-
ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, ErrorFunction &error_function)
301+
ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, const ErrorFunction &error_function)
639302
{
640303
// Ensure we know about the thread.
641304
auto find_it = m_tid_map.find (tid);
@@ -655,15 +318,10 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs,
655318
context.m_stop_requested = false;
656319

657320
// If we have a pending notification, remove this from the set.
658-
EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
659-
if (call_after_event)
321+
if (m_pending_notification_up)
660322
{
661-
const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid);
662-
if (!pending_stops_remain)
663-
{
664-
// Clear the pending notification now.
665-
m_pending_notification_sp.reset ();
666-
}
323+
m_pending_notification_up->wait_for_stop_tids.erase(tid);
324+
SignalIfRequirementsSatisfied();
667325
}
668326

669327
if (initiated_by_llgs && context.m_request_resume_function && !stop_was_requested)
@@ -685,7 +343,49 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs,
685343
}
686344

687345
void
688-
ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, ErrorFunction &error_function)
346+
ThreadStateCoordinator::DoCallAfterThreadsStop(PendingNotificationUP &&notification_up)
347+
{
348+
// Validate we know about the deferred trigger thread.
349+
if (!IsKnownThread (notification_up->triggering_tid))
350+
{
351+
// We don't know about this thread. This is an error condition.
352+
std::ostringstream error_message;
353+
error_message << "error: deferred notification tid " << notification_up->triggering_tid << " is unknown";
354+
notification_up->error_function (error_message.str ());
355+
356+
// We bail out here.
357+
return;
358+
}
359+
360+
if (m_pending_notification_up)
361+
{
362+
// Yikes - we've already got a pending signal notification in progress.
363+
// Log this info. We lose the pending notification here.
364+
Log ("ThreadStateCoordinator::%s dropping existing pending signal notification for tid %" PRIu64 ", to be replaced with signal for tid %" PRIu64,
365+
__FUNCTION__,
366+
m_pending_notification_up->triggering_tid,
367+
notification_up->triggering_tid);
368+
}
369+
m_pending_notification_up = std::move(notification_up);
370+
371+
if (m_pending_notification_up->request_stop_on_all_unstopped_threads)
372+
RequestStopOnAllRunningThreads();
373+
else
374+
{
375+
if (!RequestStopOnAllSpecifiedThreads())
376+
return;
377+
}
378+
379+
if (m_pending_notification_up->wait_for_stop_tids.empty ())
380+
{
381+
// We're not waiting for any threads. Fire off the deferred signal delivery event.
382+
m_pending_notification_up->call_after_function(m_pending_notification_up->triggering_tid);
383+
m_pending_notification_up.reset();
384+
}
385+
}
386+
387+
void
388+
ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, const ErrorFunction &error_function)
689389
{
690390
// Ensure we don't already know about the thread.
691391
auto find_it = m_tid_map.find (tid);
@@ -703,17 +403,17 @@ ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, Erro
703403
ctx.m_state = (is_stopped) ? ThreadState::Stopped : ThreadState::Running;
704404
m_tid_map[tid] = std::move(ctx);
705405

706-
EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
707-
if (call_after_event && !is_stopped)
406+
if (m_pending_notification_up && !is_stopped)
708407
{
709-
// Tell the pending notification that we need to wait
710-
// for this new thread to stop.
711-
call_after_event->AddThreadStopRequirement (tid);
408+
// We will need to wait for this new thread to stop as well before firing the
409+
// notification.
410+
m_pending_notification_up->wait_for_stop_tids.insert(tid);
411+
m_pending_notification_up->request_thread_stop_function(tid);
712412
}
713413
}
714414

715415
void
716-
ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, ErrorFunction &error_function)
416+
ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, const ErrorFunction &error_function)
717417
{
718418
// Ensure we know about the thread.
719419
auto find_it = m_tid_map.find (tid);
@@ -732,31 +432,13 @@ ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, ErrorFunction &error_func
732432
m_tid_map.erase (find_it);
733433

734434
// If we have a pending notification, remove this from the set.
735-
EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
736-
if (call_after_event)
435+
if (m_pending_notification_up)
737436
{
738-
const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid);
739-
if (!pending_stops_remain)
740-
{
741-
// Clear the pending notification now.
742-
m_pending_notification_sp.reset ();
743-
}
437+
m_pending_notification_up->wait_for_stop_tids.erase(tid);
438+
SignalIfRequirementsSatisfied();
744439
}
745440
}
746441

747-
void
748-
ThreadStateCoordinator::ResetNow ()
749-
{
750-
// Clear the pending notification if there was one.
751-
m_pending_notification_sp.reset ();
752-
753-
// Clear the stop map - we no longer know anything about any thread state.
754-
// The caller is expected to reset thread states for all threads, and we
755-
// will assume anything we haven't heard about is running and requires a
756-
// stop.
757-
m_tid_map.clear ();
758-
}
759-
760442
void
761443
ThreadStateCoordinator::Log (const char *format, ...)
762444
{
@@ -773,77 +455,134 @@ ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid,
773455
bool initiated_by_llgs,
774456
const ErrorFunction &error_function)
775457
{
776-
ProcessEvent(EventBaseSP(new EventThreadStopped (tid, initiated_by_llgs, error_function)));
458+
std::lock_guard<std::mutex> lock(m_event_mutex);
459+
460+
if (m_log_event_processing)
461+
{
462+
Log ("ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 ", %sinitiated by llgs)",
463+
__FUNCTION__, tid, initiated_by_llgs?"":"not ");
464+
}
465+
466+
ThreadDidStop (tid, initiated_by_llgs, error_function);
467+
468+
if (m_log_event_processing)
469+
{
470+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
471+
}
777472
}
778473

779474
void
780475
ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid,
781476
const ResumeThreadFunction &request_thread_resume_function,
782477
const ErrorFunction &error_function)
783478
{
784-
ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, true)));
479+
std::lock_guard<std::mutex> lock(m_event_mutex);
480+
481+
if (m_log_event_processing)
482+
{
483+
Log ("ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 ")",
484+
__FUNCTION__, tid);
485+
}
486+
487+
DoResume(tid, request_thread_resume_function, error_function, true);
488+
489+
if (m_log_event_processing)
490+
{
491+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
492+
}
785493
}
786494

787495
void
788496
ThreadStateCoordinator::RequestThreadResumeAsNeeded (lldb::tid_t tid,
789497
const ResumeThreadFunction &request_thread_resume_function,
790498
const ErrorFunction &error_function)
791499
{
792-
ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, false)));
500+
std::lock_guard<std::mutex> lock(m_event_mutex);
501+
502+
if (m_log_event_processing)
503+
{
504+
Log ("ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 ")",
505+
__FUNCTION__, tid);
506+
}
507+
508+
DoResume (tid, request_thread_resume_function, error_function, false);
509+
510+
if (m_log_event_processing)
511+
{
512+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
513+
}
793514
}
794515

795516
void
796517
ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid,
797518
bool is_stopped,
798519
const ErrorFunction &error_function)
799520
{
800-
ProcessEvent(EventBaseSP(new EventThreadCreate (tid, is_stopped, error_function)));
521+
std::lock_guard<std::mutex> lock(m_event_mutex);
522+
523+
if (m_log_event_processing)
524+
{
525+
Log ("ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 ", is %sstopped)",
526+
__FUNCTION__, tid, is_stopped?"":"not ");
527+
}
528+
529+
ThreadWasCreated (tid, is_stopped, error_function);
530+
531+
if (m_log_event_processing)
532+
{
533+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
534+
}
801535
}
802536

803537
void
804538
ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid,
805539
const ErrorFunction &error_function)
806540
{
807-
ProcessEvent(EventBaseSP(new EventThreadDeath (tid, error_function)));
808-
}
541+
std::lock_guard<std::mutex> lock(m_event_mutex);
809542

810-
void
811-
ThreadStateCoordinator::ResetForExec ()
812-
{
813-
ProcessEvent(EventBaseSP(new EventReset()));
543+
if (m_log_event_processing)
544+
{
545+
Log ("ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 ")", __FUNCTION__, tid);
546+
}
547+
548+
ThreadDidDie(tid, error_function);
549+
550+
if (m_log_event_processing)
551+
{
552+
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
553+
}
814554
}
815555

816556
void
817-
ThreadStateCoordinator::ProcessEvent (const EventBaseSP &event_sp)
557+
ThreadStateCoordinator::ResetForExec ()
818558
{
819559
std::lock_guard<std::mutex> lock(m_event_mutex);
820560

821561
if (m_log_event_processing)
822562
{
823-
Log ("ThreadStateCoordinator::%s about to process event: %s", __FUNCTION__, event_sp->GetDescription ().c_str ());
563+
Log ("ThreadStateCoordinator::%s about to process event", __FUNCTION__);
824564
}
825565

826-
// Process the event.
827-
event_sp->ProcessEvent (*this);
566+
// Clear the pending notification if there was one.
567+
m_pending_notification_up.reset ();
568+
569+
// Clear the stop map - we no longer know anything about any thread state.
570+
// The caller is expected to reset thread states for all threads, and we
571+
// will assume anything we haven't heard about is running and requires a
572+
// stop.
573+
m_tid_map.clear ();
828574

829575
if (m_log_event_processing)
830576
{
831577
Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__);
832578
}
833579
}
834-
835580
void
836581
ThreadStateCoordinator::LogEnableEventProcessing (bool enabled)
837582
{
838583
m_log_event_processing = enabled;
839584
}
840585

841-
ThreadStateCoordinator::EventCallAfterThreadsStop *
842-
ThreadStateCoordinator::GetPendingThreadStopNotification ()
843-
{
844-
return static_cast<EventCallAfterThreadsStop*> (m_pending_notification_sp.get ());
845-
}
846-
847586
bool
848587
ThreadStateCoordinator::IsKnownThread (lldb::tid_t tid) const
849588
{

‎lldb/source/Plugins/Process/Linux/ThreadStateCoordinator.h

+77-31
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ namespace process_linux {
2929
// Typedefs.
3030
typedef std::unordered_set<lldb::tid_t> ThreadIDSet;
3131

32-
enum EventLoopResult
33-
{
34-
eventLoopResultContinue,
35-
eventLoopResultStop
36-
};
37-
3832
// Callback/block definitions.
3933
typedef std::function<void (lldb::tid_t tid)> ThreadIDFunction;
4034
typedef std::function<void (const char *format, va_list args)> LogFunction;
@@ -133,19 +127,6 @@ namespace process_linux {
133127

134128
private:
135129

136-
// Typedefs.
137-
class EventBase;
138-
139-
class EventCallAfterThreadsStop;
140-
class EventThreadStopped;
141-
class EventThreadCreate;
142-
class EventThreadDeath;
143-
class EventRequestResume;
144-
145-
class EventReset;
146-
147-
typedef std::shared_ptr<EventBase> EventBaseSP;
148-
149130
enum class ThreadState
150131
{
151132
Running,
@@ -160,40 +141,105 @@ namespace process_linux {
160141
};
161142
typedef std::unordered_map<lldb::tid_t, ThreadContext> TIDContextMap;
162143

144+
struct PendingNotification
145+
{
146+
PendingNotification (lldb::tid_t triggering_tid,
147+
const ThreadIDSet &wait_for_stop_tids,
148+
const StopThreadFunction &request_thread_stop_function,
149+
const ThreadIDFunction &call_after_function,
150+
const ErrorFunction &error_function):
151+
triggering_tid (triggering_tid),
152+
wait_for_stop_tids (wait_for_stop_tids),
153+
original_wait_for_stop_tids (wait_for_stop_tids),
154+
request_thread_stop_function (request_thread_stop_function),
155+
call_after_function (call_after_function),
156+
error_function (error_function),
157+
request_stop_on_all_unstopped_threads (false),
158+
skip_stop_request_tids ()
159+
{
160+
}
161+
162+
PendingNotification (lldb::tid_t triggering_tid,
163+
const StopThreadFunction &request_thread_stop_function,
164+
const ThreadIDFunction &call_after_function,
165+
const ErrorFunction &error_function) :
166+
triggering_tid (triggering_tid),
167+
wait_for_stop_tids (),
168+
original_wait_for_stop_tids (),
169+
request_thread_stop_function (request_thread_stop_function),
170+
call_after_function (call_after_function),
171+
error_function (error_function),
172+
request_stop_on_all_unstopped_threads (true),
173+
skip_stop_request_tids ()
174+
{
175+
}
176+
177+
PendingNotification (lldb::tid_t triggering_tid,
178+
const StopThreadFunction &request_thread_stop_function,
179+
const ThreadIDFunction &call_after_function,
180+
const ThreadIDSet &skip_stop_request_tids,
181+
const ErrorFunction &error_function) :
182+
triggering_tid (triggering_tid),
183+
wait_for_stop_tids (),
184+
original_wait_for_stop_tids (),
185+
request_thread_stop_function (request_thread_stop_function),
186+
call_after_function (call_after_function),
187+
error_function (error_function),
188+
request_stop_on_all_unstopped_threads (true),
189+
skip_stop_request_tids (skip_stop_request_tids)
190+
{
191+
}
192+
193+
const lldb::tid_t triggering_tid;
194+
ThreadIDSet wait_for_stop_tids;
195+
const ThreadIDSet original_wait_for_stop_tids;
196+
StopThreadFunction request_thread_stop_function;
197+
ThreadIDFunction call_after_function;
198+
ErrorFunction error_function;
199+
const bool request_stop_on_all_unstopped_threads;
200+
ThreadIDSet skip_stop_request_tids;
201+
};
202+
typedef std::unique_ptr<PendingNotification> PendingNotificationUP;
203+
204+
// Fire pending notification if no pending thread stops remain.
205+
void SignalIfRequirementsSatisfied();
206+
207+
bool
208+
RequestStopOnAllSpecifiedThreads();
163209

164-
std::mutex m_event_mutex; // Serializes execution of ProcessEvent.
210+
void
211+
RequestStopOnAllRunningThreads();
165212

166213
void
167-
ProcessEvent (const EventBaseSP &event_sp);
214+
RequestThreadStop (lldb::tid_t tid, ThreadContext& context);
215+
216+
std::mutex m_event_mutex; // Serializes execution of TSC operations.
168217

169218
void
170-
SetPendingNotification (const EventBaseSP &event_sp);
219+
ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, const ErrorFunction &error_function);
171220

172221
void
173-
ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, ErrorFunction &error_function);
222+
DoResume(lldb::tid_t tid, ResumeThreadFunction request_thread_resume_function,
223+
ErrorFunction error_function, bool error_when_already_running);
174224

175225
void
176-
ThreadWasCreated (lldb::tid_t tid, bool is_stopped, ErrorFunction &error_function);
226+
DoCallAfterThreadsStop(PendingNotificationUP &&notification_up);
177227

178228
void
179-
ThreadDidDie (lldb::tid_t tid, ErrorFunction &error_function);
229+
ThreadWasCreated (lldb::tid_t tid, bool is_stopped, const ErrorFunction &error_function);
180230

181231
void
182-
ResetNow ();
232+
ThreadDidDie (lldb::tid_t tid, const ErrorFunction &error_function);
183233

184234
bool
185235
IsKnownThread(lldb::tid_t tid) const;
186236

187237
void
188238
Log (const char *format, ...);
189239

190-
EventCallAfterThreadsStop *
191-
GetPendingThreadStopNotification ();
192-
193240
// Member variables.
194241
LogFunction m_log_function;
195-
196-
EventBaseSP m_pending_notification_sp;
242+
PendingNotificationUP m_pending_notification_up;
197243

198244
// Maps known TIDs to ThreadContext.
199245
TIDContextMap m_tid_map;

0 commit comments

Comments
 (0)
Please sign in to comment.