forked from OSchip/llvm-project
Fix the handling of the run lock in cases where you needed to run
a hand-called function from the private state thread. The problem was that on the way out of the private state thread, we try to drop the run lock. That is appropriate for the main private state thread, but not the secondary private state thread. Only the thread that spawned them can know whether this is an appropriate thing to do or not. <rdar://problem/21375352> llvm-svn: 240461
This commit is contained in:
parent
19ffcb900f
commit
60c915e96a
|
@ -3250,7 +3250,7 @@ protected:
|
|||
SetPrivateState (lldb::StateType state);
|
||||
|
||||
bool
|
||||
StartPrivateStateThread (bool force = false);
|
||||
StartPrivateStateThread (bool is_secondary_thread = false);
|
||||
|
||||
void
|
||||
StopPrivateStateThread ();
|
||||
|
@ -3261,11 +3261,22 @@ protected:
|
|||
void
|
||||
ResumePrivateStateThread ();
|
||||
|
||||
struct PrivateStateThreadArgs
|
||||
{
|
||||
Process *process;
|
||||
bool is_secondary_thread;
|
||||
};
|
||||
|
||||
static lldb::thread_result_t
|
||||
PrivateStateThread (void *arg);
|
||||
|
||||
// The starts up the private state thread that will watch for events from the debugee.
|
||||
// Pass true for is_secondary_thread in the case where you have to temporarily spin up a
|
||||
// secondary state thread to handle events from a hand-called function on the primary
|
||||
// private state thread.
|
||||
|
||||
lldb::thread_result_t
|
||||
RunPrivateStateThread ();
|
||||
RunPrivateStateThread (bool is_secondary_thread);
|
||||
|
||||
void
|
||||
HandlePrivateEvent (lldb::EventSP &event_sp);
|
||||
|
|
|
@ -4271,7 +4271,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
|
|||
|
||||
|
||||
bool
|
||||
Process::StartPrivateStateThread (bool force)
|
||||
Process::StartPrivateStateThread (bool is_secondary_thread)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
|
||||
|
||||
|
@ -4279,7 +4279,7 @@ Process::StartPrivateStateThread (bool force)
|
|||
if (log)
|
||||
log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread");
|
||||
|
||||
if (!force && already_running)
|
||||
if (!is_secondary_thread && already_running)
|
||||
return true;
|
||||
|
||||
// Create a thread that watches our internal state and controls which
|
||||
|
@ -4303,7 +4303,8 @@ Process::StartPrivateStateThread (bool force)
|
|||
}
|
||||
|
||||
// Create the private state thread, and start it running.
|
||||
m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, this, NULL);
|
||||
PrivateStateThreadArgs args = {this, is_secondary_thread};
|
||||
m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL);
|
||||
if (m_private_state_thread.IsJoinable())
|
||||
{
|
||||
ResumePrivateStateThread();
|
||||
|
@ -4533,13 +4534,13 @@ Process::HandlePrivateEvent (EventSP &event_sp)
|
|||
thread_result_t
|
||||
Process::PrivateStateThread (void *arg)
|
||||
{
|
||||
Process *proc = static_cast<Process*> (arg);
|
||||
thread_result_t result = proc->RunPrivateStateThread();
|
||||
PrivateStateThreadArgs *real_args = static_cast<PrivateStateThreadArgs *> (arg);
|
||||
thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread);
|
||||
return result;
|
||||
}
|
||||
|
||||
thread_result_t
|
||||
Process::RunPrivateStateThread ()
|
||||
Process::RunPrivateStateThread (bool is_secondary_thread)
|
||||
{
|
||||
bool control_only = true;
|
||||
m_private_state_control_wait.SetValue (false, eBroadcastNever);
|
||||
|
@ -4631,7 +4632,11 @@ Process::RunPrivateStateThread ()
|
|||
log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",
|
||||
__FUNCTION__, static_cast<void*>(this), GetID());
|
||||
|
||||
m_public_run_lock.SetStopped();
|
||||
// If we are a secondary thread, then the primary thread we are working for will have already
|
||||
// acquired the public_run_lock, and isn't done with what it was doing yet, so don't
|
||||
// try to change it on the way out.
|
||||
if (!is_secondary_thread)
|
||||
m_public_run_lock.SetStopped();
|
||||
m_private_state_control_wait.SetValue (true, eBroadcastAlways);
|
||||
m_private_state_thread.Reset();
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue