summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Core/Broadcaster.cpp190
-rw-r--r--lldb/source/Core/Event.cpp33
-rw-r--r--lldb/source/Core/Listener.cpp113
-rw-r--r--lldb/source/Host/posix/HostThreadPosix.cpp18
-rw-r--r--lldb/source/Target/Process.cpp68
5 files changed, 232 insertions, 190 deletions
diff --git a/lldb/source/Core/Broadcaster.cpp b/lldb/source/Core/Broadcaster.cpp
index 3f125183d0b..ec91f8d8a7f 100644
--- a/lldb/source/Core/Broadcaster.cpp
+++ b/lldb/source/Core/Broadcaster.cpp
@@ -61,6 +61,33 @@ Broadcaster::CheckInWithManager ()
}
void
+Broadcaster::BroadcasterImpl::ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback)
+{
+ // Private iterator that should be used by everyone except BroadcasterImpl::RemoveListener().
+ // We have weak pointers to our listeners which means that at any point the listener can
+ // expire which means we will need to take it out of our list. To take care of this, we
+ // iterate and check that the weak pointer can be made into a valid shared pointer before
+ // we call the callback. If the weak pointer has expired, we remove it from our list.
+ collection::iterator pos = m_listeners.begin();
+ while (pos != m_listeners.end())
+ {
+ lldb::ListenerSP curr_listener_sp(pos->first.lock());
+ if (curr_listener_sp)
+ {
+ if (callback(curr_listener_sp, pos->second))
+ ++pos; // Keep iterating
+ else
+ return; // Done iterating
+ }
+ else
+ {
+ // The listener has been expired. Remove this entry.
+ pos = m_listeners.erase(pos);
+ }
+ }
+}
+
+void
Broadcaster::BroadcasterImpl::Clear()
{
Mutex::Locker listeners_locker(m_listeners_mutex);
@@ -68,10 +95,11 @@ Broadcaster::BroadcasterImpl::Clear()
// Make sure the listener forgets about this broadcaster. We do
// this in the broadcaster in case the broadcaster object initiates
// the removal.
-
- collection::iterator pos, end = m_listeners.end();
- for (pos = m_listeners.begin(); pos != end; ++pos)
- pos->first->BroadcasterWillDestruct (&m_broadcaster);
+
+ ListenerIterator([this](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+ curr_listener_sp->BroadcasterWillDestruct (&m_broadcaster);
+ return true; // Keep iterating
+ });
m_listeners.clear();
}
@@ -114,57 +142,45 @@ Broadcaster::BroadcasterImpl::GetEventNames (Stream &s, uint32_t event_mask, boo
}
void
-Broadcaster::AddInitialEventsToListener (lldb::ListenerSP listener_sp, uint32_t requested_events)
+Broadcaster::AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events)
{
}
uint32_t
-Broadcaster::BroadcasterImpl::AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
{
if (!listener_sp)
return 0;
Mutex::Locker locker(m_listeners_mutex);
- collection::iterator pos, end = m_listeners.end();
- collection::iterator existing_pos = end;
// See if we already have this listener, and if so, update its mask
- uint32_t taken_event_types = 0;
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- if (pos->first == listener_sp)
- existing_pos = pos;
- // For now don't descriminate on who gets what
- // FIXME: Implement "unique listener for this bit" mask
- // taken_event_types |= pos->second;
- }
- // Each event bit in a Broadcaster object can only be used
- // by one listener
- uint32_t available_event_types = ~taken_event_types & event_mask;
+ bool handled = false;
- if (available_event_types)
- {
- // If we didn't find our listener, add it
- if (existing_pos == end)
+ ListenerIterator([this, &listener_sp, &handled, event_mask](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+ if (curr_listener_sp == listener_sp)
{
- // Grant a new listener the available event bits
- m_listeners.push_back(std::make_pair(listener_sp, available_event_types));
- }
- else
- {
- // Grant the existing listener the available event bits
- existing_pos->second |= available_event_types;
+ handled = true;
+ curr_event_mask |= event_mask;
+ m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
+ return false; // Stop iterating
}
+ return true; // Keep iterating
+ });
+
+ if (!handled)
+ {
+ // Grant a new listener the available event bits
+ m_listeners.push_back(std::make_pair(lldb::ListenerWP(listener_sp), event_mask));
// Individual broadcasters decide whether they have outstanding data when a
// listener attaches, and insert it into the listener with this method.
-
- m_broadcaster.AddInitialEventsToListener (listener_sp, available_event_types);
+ m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
}
// Return the event bits that were granted to the listener
- return available_event_types;
+ return event_mask;
}
bool
@@ -178,36 +194,63 @@ Broadcaster::BroadcasterImpl::EventTypeHasListeners (uint32_t event_type)
if (m_listeners.empty())
return false;
- collection::iterator pos, end = m_listeners.end();
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- if (pos->second & event_type)
- return true;
- }
- return false;
+ bool result = false;
+ ListenerIterator([this, event_type, &result](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+
+ if (curr_event_mask & event_type)
+ {
+ result = true;
+ return false; // Stop iterating
+ }
+ else
+ {
+ return true; // Keep iterating
+ }
+ });
+ return result;
}
bool
-Broadcaster::BroadcasterImpl::RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::RemoveListener (lldb_private::Listener *listener, uint32_t event_mask)
{
- Mutex::Locker locker(m_listeners_mutex);
- collection::iterator pos, end = m_listeners.end();
- // See if we already have this listener, and if so, update its mask
- for (pos = m_listeners.begin(); pos != end; ++pos)
+ if (listener)
{
- if (pos->first == listener_sp)
+ Mutex::Locker locker(m_listeners_mutex);
+ collection::iterator pos = m_listeners.begin();
+ // See if we already have this listener, and if so, update its mask
+ while (pos != m_listeners.end())
{
- // Relinquish all event bits in "event_mask"
- pos->second &= ~event_mask;
- // If all bits have been relinquished then remove this listener
- if (pos->second == 0)
- m_listeners.erase (pos);
- return true;
+ lldb::ListenerSP curr_listener_sp(pos->first.lock());
+ if (curr_listener_sp)
+ {
+ if (curr_listener_sp.get() == listener)
+ {
+ // Relinquish all event bits in "event_mask"
+ pos->second &= ~event_mask;
+ // If all bits have been relinquished then remove this listener
+ if (pos->second == 0)
+ m_listeners.erase (pos);
+ return true;
+ }
+ ++pos;
+ }
+ else
+ {
+ // The listener has been destroyed since we couldn't turn the std::weak_ptr
+ // into a valid shared pointer, so we can remove it.
+ pos = m_listeners.erase (pos);
+ }
}
}
return false;
}
+bool
+Broadcaster::BroadcasterImpl::RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
+{
+ return RemoveListener (listener_sp.get(), event_mask);
+}
+
void
Broadcaster::BroadcasterImpl::BroadcastEvent (EventSP &event_sp)
{
@@ -232,7 +275,7 @@ Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool uni
const uint32_t event_type = event_sp->GetType();
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ Mutex::Locker locker(m_listeners_mutex);
ListenerSP hijacking_listener_sp;
@@ -263,20 +306,16 @@ Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool uni
}
else
{
- collection::iterator pos, end = m_listeners.end();
- // Iterate through all listener/mask pairs
- for (pos = m_listeners.begin(); pos != end; ++pos)
- {
- // If the listener's mask matches any bits that we just set, then
- // put the new event on its event queue.
- if (event_type & pos->second)
+ ListenerIterator([this, unique, event_type, &event_sp](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+
+ if (event_type & curr_event_mask)
{
- if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
- continue;
- pos->first->AddEvent (event_sp);
+ if (!unique || curr_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type) == nullptr)
+ curr_listener_sp->AddEvent (event_sp);
}
- }
+ return true; // Keep iterating
+ });
}
}
@@ -288,6 +327,13 @@ Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, EventData *ev
}
void
+Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, const lldb::EventDataSP &event_data_sp)
+{
+ EventSP event_sp (new Event (event_type, event_data_sp));
+ PrivateBroadcastEvent (event_sp, false);
+}
+
+void
Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
{
EventSP event_sp (new Event (event_type, event_data));
@@ -295,9 +341,9 @@ Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (uint32_t event_type, Event
}
bool
-Broadcaster::BroadcasterImpl::HijackBroadcaster (ListenerSP listener_sp, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ Mutex::Locker locker(m_listeners_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
if (log)
@@ -312,7 +358,7 @@ Broadcaster::BroadcasterImpl::HijackBroadcaster (ListenerSP listener_sp, uint32_
bool
Broadcaster::BroadcasterImpl::IsHijackedForEvent (uint32_t event_mask)
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ Mutex::Locker locker(m_listeners_mutex);
if (!m_hijacking_listeners.empty())
return (event_mask & m_hijacking_masks.back()) != 0;
@@ -335,7 +381,7 @@ Broadcaster::BroadcasterImpl::GetHijackingListenerName()
void
Broadcaster::BroadcasterImpl::RestoreBroadcaster ()
{
- Mutex::Locker event_types_locker(m_listeners_mutex);
+ Mutex::Locker locker(m_listeners_mutex);
if (!m_hijacking_listeners.empty())
{
@@ -391,7 +437,7 @@ BroadcasterManager::MakeBroadcasterManager()
}
uint32_t
-BroadcasterManager::RegisterListenerForEvents (ListenerSP listener_sp, BroadcastEventSpec event_spec)
+BroadcasterManager::RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
{
Mutex::Locker locker(m_manager_mutex);
@@ -415,7 +461,7 @@ BroadcasterManager::RegisterListenerForEvents (ListenerSP listener_sp, Broadcast
}
bool
-BroadcasterManager::UnregisterListenerForEvents (ListenerSP listener_sp, BroadcastEventSpec event_spec)
+BroadcasterManager::UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
{
Mutex::Locker locker(m_manager_mutex);
bool removed_some = false;
@@ -495,7 +541,7 @@ BroadcasterManager::RemoveListener(Listener *listener)
}
void
-BroadcasterManager::RemoveListener (ListenerSP listener_sp)
+BroadcasterManager::RemoveListener (const lldb::ListenerSP &listener_sp)
{
Mutex::Locker locker(m_manager_mutex);
ListenerMatches predicate (listener_sp);
diff --git a/lldb/source/Core/Event.cpp b/lldb/source/Core/Event.cpp
index a8063bfb34d..6b07e4d9198 100644
--- a/lldb/source/Core/Event.cpp
+++ b/lldb/source/Core/Event.cpp
@@ -26,15 +26,30 @@ using namespace lldb;
using namespace lldb_private;
Event::Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data) :
- m_broadcaster_wp (broadcaster->GetBroadcasterImpl()),
- m_type (event_type),
- m_data_ap (data)
+ m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
+ m_type(event_type),
+ m_data_sp(data)
+{
+}
+
+Event::Event (Broadcaster *broadcaster, uint32_t event_type, const EventDataSP &event_data_sp) :
+ m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
+ m_type(event_type),
+ m_data_sp(event_data_sp)
{
}
Event::Event(uint32_t event_type, EventData *data) :
- m_type (event_type),
- m_data_ap (data)
+ m_broadcaster_wp(),
+ m_type(event_type),
+ m_data_sp(data)
+{
+}
+
+Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) :
+ m_broadcaster_wp(),
+ m_type(event_type),
+ m_data_sp(event_data_sp)
{
}
@@ -69,10 +84,10 @@ Event::Dump (Stream *s) const
s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
static_cast<const void*>(this), m_type);
- if (m_data_ap)
+ if (m_data_sp)
{
s->PutChar('{');
- m_data_ap->Dump (s);
+ m_data_sp->Dump (s);
s->PutChar('}');
}
else
@@ -82,8 +97,8 @@ Event::Dump (Stream *s) const
void
Event::DoOnRemoval ()
{
- if (m_data_ap)
- m_data_ap->DoOnRemoval (this);
+ if (m_data_sp)
+ m_data_sp->DoOnRemoval (this);
}
EventData::EventData() = default;
diff --git a/lldb/source/Core/Listener.cpp b/lldb/source/Core/Listener.cpp
index e8cf39e0676..32ca1f0cebb 100644
--- a/lldb/source/Core/Listener.cpp
+++ b/lldb/source/Core/Listener.cpp
@@ -45,8 +45,7 @@ Listener::Listener(const char *name) :
m_broadcasters(),
m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
m_events (),
- m_events_mutex (Mutex::eMutexTypeRecursive),
- m_cond_wait()
+ m_events_mutex (Mutex::eMutexTypeNormal)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log != nullptr)
@@ -74,11 +73,10 @@ Listener::Clear()
{
Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
if (broadcaster_sp)
- broadcaster_sp->RemoveListener (this->shared_from_this(), pos->second.event_mask);
+ broadcaster_sp->RemoveListener (this, pos->second.event_mask);
}
m_broadcasters.clear();
- m_cond_wait.SetValue (false, eBroadcastNever);
- m_broadcasters.clear();
+
Mutex::Locker event_locker(m_events_mutex);
m_events.clear();
size_t num_managers = m_broadcaster_managers.size();
@@ -193,9 +191,6 @@ Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
else
++pos;
}
-
- if (m_events.empty())
- m_cond_wait.SetValue (false, eBroadcastNever);
}
}
@@ -221,12 +216,9 @@ Listener::AddEvent (EventSP &event_sp)
static_cast<void*>(this), m_name.c_str(),
static_cast<void*>(event_sp.get()));
- // Scope for "locker"
- {
- Mutex::Locker locker(m_events_mutex);
- m_events.push_back (event_sp);
- }
- m_cond_wait.SetValue (true, eBroadcastAlways);
+ Mutex::Locker locker(m_events_mutex);
+ m_events.push_back (event_sp);
+ m_events_condition.Broadcast();
}
class EventBroadcasterMatches
@@ -293,6 +285,7 @@ private:
bool
Listener::FindNextEventInternal
(
+ Mutex::Locker& lock,
Broadcaster *broadcaster, // nullptr for any broadcaster
const ConstString *broadcaster_names, // nullptr for any event
uint32_t num_broadcaster_names,
@@ -300,10 +293,10 @@ Listener::FindNextEventInternal
EventSP &event_sp,
bool remove)
{
+ // NOTE: callers of this function must lock m_events_mutex using a Mutex::Locker
+ // and pass the locker as the first argument. m_events_mutex is no longer recursive.
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- Mutex::Locker lock(m_events_mutex);
-
if (m_events.empty())
return false;
@@ -333,20 +326,12 @@ Listener::FindNextEventInternal
if (remove)
{
m_events.erase(pos);
-
- if (m_events.empty())
- m_cond_wait.SetValue (false, eBroadcastNever);
- }
-
- // Unlock the event queue here. We've removed this event and are about to return
- // it so it should be okay to get the next event off the queue here - and it might
- // be useful to do that in the "DoOnRemoval".
- lock.Unlock();
-
- // Don't call DoOnRemoval if you aren't removing the event...
- if (remove)
+ // Unlock the event queue here. We've removed this event and are about to return
+ // it so it should be okay to get the next event off the queue here - and it might
+ // be useful to do that in the "DoOnRemoval".
+ lock.Unlock();
event_sp->DoOnRemoval();
-
+ }
return true;
}
@@ -357,8 +342,9 @@ Listener::FindNextEventInternal
Event *
Listener::PeekAtNextEvent ()
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal(nullptr, nullptr, 0, 0, event_sp, false))
+ if (FindNextEventInternal(lock, nullptr, nullptr, 0, 0, event_sp, false))
return event_sp.get();
return nullptr;
}
@@ -366,8 +352,9 @@ Listener::PeekAtNextEvent ()
Event *
Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal(broadcaster, nullptr, 0, 0, event_sp, false))
+ if (FindNextEventInternal(lock, broadcaster, nullptr, 0, 0, event_sp, false))
return event_sp.get();
return nullptr;
}
@@ -375,8 +362,9 @@ Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
Event *
Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
{
+ Mutex::Locker lock(m_events_mutex);
EventSP event_sp;
- if (FindNextEventInternal(broadcaster, nullptr, 0, event_type_mask, event_sp, false))
+ if (FindNextEventInternal(lock, broadcaster, nullptr, 0, event_type_mask, event_sp, false))
return event_sp.get();
return nullptr;
}
@@ -388,7 +376,8 @@ Listener::GetNextEventInternal(Broadcaster *broadcaster, // nullptr
uint32_t event_type_mask,
EventSP &event_sp)
{
- return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
+ Mutex::Locker lock(m_events_mutex);
+ return FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
}
bool
@@ -418,52 +407,40 @@ Listener::WaitForEventsInternal(const TimeValue *timeout,
EventSP &event_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- bool timed_out = false;
-
if (log != nullptr)
log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
static_cast<void*>(this), static_cast<const void*>(timeout),
m_name.c_str());
+ Mutex::Locker lock(m_events_mutex);
+
while (true)
{
- // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
- // code might require that new events be serviced. For instance, the Breakpoint Command's
- if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
- return true;
-
- {
- // Reset condition value to false, so we can wait for new events to be
- // added that might meet our current filter
- // But first poll for any new event that might satisfy our condition, and if so consume it,
- // otherwise wait.
-
- Mutex::Locker event_locker(m_events_mutex);
- const bool remove = false;
- if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
- continue;
- else
- m_cond_wait.SetValue (false, eBroadcastNever);
- }
-
- if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
- continue;
-
- else if (timed_out)
+ if (FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true))
{
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log != nullptr)
- log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s",
- static_cast<void*>(this), m_name.c_str());
- break;
+ return true;
}
else
{
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log != nullptr)
- log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s",
- static_cast<void*>(this), m_name.c_str());
- break;
+ bool timed_out = false;
+ if (m_events_condition.Wait(m_events_mutex, timeout, &timed_out) != 0)
+ {
+ if (timed_out)
+ {
+ log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
+ if (log != nullptr)
+ log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s",
+ static_cast<void*>(this), m_name.c_str());
+ }
+ else
+ {
+ log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
+ if (log != nullptr)
+ log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s",
+ static_cast<void*>(this), m_name.c_str());
+ }
+ return false;
+ }
}
}
diff --git a/lldb/source/Host/posix/HostThreadPosix.cpp b/lldb/source/Host/posix/HostThreadPosix.cpp
index 9c489243193..3ac83ac07b1 100644
--- a/lldb/source/Host/posix/HostThreadPosix.cpp
+++ b/lldb/source/Host/posix/HostThreadPosix.cpp
@@ -53,13 +53,16 @@ Error
HostThreadPosix::Cancel()
{
Error error;
+ if (IsJoinable())
+ {
#ifndef __ANDROID__
- int err = ::pthread_cancel(m_thread);
- error.SetError(err, eErrorTypePOSIX);
+ assert(false && "someone is calling HostThread::Cancel()");
+ int err = ::pthread_cancel(m_thread);
+ error.SetError(err, eErrorTypePOSIX);
#else
- error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
+ error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
-
+ }
return error;
}
@@ -67,8 +70,11 @@ Error
HostThreadPosix::Detach()
{
Error error;
- int err = ::pthread_detach(m_thread);
- error.SetError(err, eErrorTypePOSIX);
+ if (IsJoinable())
+ {
+ int err = ::pthread_detach(m_thread);
+ error.SetError(err, eErrorTypePOSIX);
+ }
Reset();
return error;
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f156d086d28..a880782663a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -726,7 +726,6 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSig
m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"),
m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"),
m_private_state_listener_sp (Listener::MakeListener("lldb.process.internal_state_listener")),
- m_private_state_control_wait(),
m_mod_id (),
m_process_unique_id(0),
m_thread_index_id (0),
@@ -4109,44 +4108,46 @@ Process::ControlPrivateStateThread (uint32_t signal)
// Signal the private state thread. First we should copy this is case the
// thread starts exiting since the private state thread will NULL this out
// when it exits
- HostThread private_state_thread(m_private_state_thread);
- if (private_state_thread.IsJoinable())
{
- TimeValue timeout_time;
- bool timed_out;
-
- m_private_state_control_broadcaster.BroadcastEvent(signal, nullptr);
-
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
- if (log)
- log->Printf ("Sending control event of type: %d.", signal);
- m_private_state_control_wait.WaitForValueEqualTo (true, &timeout_time, &timed_out);
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
-
- if (signal == eBroadcastInternalStateControlStop)
+ HostThread private_state_thread(m_private_state_thread);
+ if (private_state_thread.IsJoinable())
{
- if (timed_out)
+ if (log)
+ log->Printf ("Sending control event of type: %d.", signal);
+ // Send the control event and wait for the receipt or for the private state
+ // thread to exit
+ std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
+ m_private_state_control_broadcaster.BroadcastEvent(signal, event_receipt_sp);
+
+ bool receipt_received = false;
+ while (!receipt_received)
{
- Error error = private_state_thread.Cancel();
- if (log)
- log->Printf ("Timed out responding to the control event, cancel got error: \"%s\".", error.AsCString());
+ bool timed_out = false;
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(2);
+ // Check for a receipt for 2 seconds and then check if the private state
+ // thread is still around.
+ receipt_received = event_receipt_sp->WaitForEventReceived (&timeout_time, &timed_out);
+ if (!receipt_received)
+ {
+ // Check if the private state thread is still around. If it isn't then we are done waiting
+ if (!m_private_state_thread.IsJoinable())
+ break; // Private state thread exited, we are done
+ }
}
- else
+
+ if (signal == eBroadcastInternalStateControlStop)
{
- if (log)
- log->Printf ("The control event killed the private state thread without having to cancel.");
+ thread_result_t result = NULL;
+ private_state_thread.Join(&result);
}
-
- thread_result_t result = NULL;
- private_state_thread.Join(&result);
- m_private_state_thread.Reset();
}
- }
- else
- {
- if (log)
- log->Printf ("Private state thread already dead, no need to signal it to stop.");
+ else
+ {
+ if (log)
+ log->Printf ("Private state thread already dead, no need to signal it to stop.");
+ }
}
}
@@ -4311,7 +4312,6 @@ thread_result_t
Process::RunPrivateStateThread (bool is_secondary_thread)
{
bool control_only = true;
- m_private_state_control_wait.SetValue (false, eBroadcastNever);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
@@ -4346,7 +4346,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
break;
}
- m_private_state_control_wait.SetValue (true, eBroadcastAlways);
continue;
}
else if (event_sp->GetType() == eBroadcastBitInterrupt)
@@ -4442,7 +4441,6 @@ Process::RunPrivateStateThread (bool is_secondary_thread)
// 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;
}
OpenPOWER on IntegriCloud