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:
Jim Ingham 2015-06-23 21:02:45 +00:00
parent 19ffcb900f
commit 60c915e96a
2 changed files with 25 additions and 9 deletions

View File

@ -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);

View File

@ -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;