BreakpointList.cpp revision 7e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20
1//===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Breakpoint/BreakpointList.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Target/Target.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21BreakpointList::BreakpointList (bool is_internal) :
22    m_mutex (Mutex::eMutexTypeRecursive),
23    m_breakpoints(),
24    m_next_break_id (0),
25    m_is_internal (is_internal)
26{
27}
28
29BreakpointList::~BreakpointList()
30{
31}
32
33
34break_id_t
35BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
36{
37    Mutex::Locker locker(m_mutex);
38    // Internal breakpoint IDs are negative, normal ones are positive
39    bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
40
41    m_breakpoints.push_back(bp_sp);
42    if (notify)
43    {
44        if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
45            bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
46                                               new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
47    }
48    return bp_sp->GetID();
49}
50
51bool
52BreakpointList::Remove (break_id_t break_id, bool notify)
53{
54    Mutex::Locker locker(m_mutex);
55    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
56    if (pos != m_breakpoints.end())
57    {
58        BreakpointSP bp_sp (*pos);
59        m_breakpoints.erase(pos);
60        if (notify)
61        {
62            if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
63                bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
64                                                   new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
65        }
66        return true;
67    }
68    return false;
69}
70
71void
72BreakpointList::SetEnabledAll (bool enabled)
73{
74    Mutex::Locker locker(m_mutex);
75    bp_collection::iterator pos, end = m_breakpoints.end();
76    for (pos = m_breakpoints.begin(); pos != end; ++pos)
77        (*pos)->SetEnabled (enabled);
78}
79
80
81void
82BreakpointList::RemoveAll (bool notify)
83{
84    Mutex::Locker locker(m_mutex);
85    ClearAllBreakpointSites ();
86
87    if (notify)
88    {
89        bp_collection::iterator pos, end = m_breakpoints.end();
90        for (pos = m_breakpoints.begin(); pos != end; ++pos)
91            if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
92                (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
93                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, *pos));
94    }
95    m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
96}
97
98class BreakpointIDMatches
99{
100public:
101    BreakpointIDMatches (break_id_t break_id) :
102        m_break_id(break_id)
103    {
104    }
105
106    bool operator() (const BreakpointSP &bp) const
107    {
108        return m_break_id == bp->GetID();
109    }
110
111private:
112   const break_id_t m_break_id;
113};
114
115BreakpointList::bp_collection::iterator
116BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
117{
118    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
119                        BreakpointIDMatches(break_id));             // Predicate
120}
121
122BreakpointList::bp_collection::const_iterator
123BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
124{
125    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
126                        BreakpointIDMatches(break_id));             // Predicate
127}
128
129BreakpointSP
130BreakpointList::FindBreakpointByID (break_id_t break_id)
131{
132    Mutex::Locker locker(m_mutex);
133    BreakpointSP stop_sp;
134    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
135    if (pos != m_breakpoints.end())
136        stop_sp = *pos;
137
138    return stop_sp;
139}
140
141const BreakpointSP
142BreakpointList::FindBreakpointByID (break_id_t break_id) const
143{
144    Mutex::Locker locker(m_mutex);
145    BreakpointSP stop_sp;
146    bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
147    if (pos != m_breakpoints.end())
148        stop_sp = *pos;
149
150    return stop_sp;
151}
152
153void
154BreakpointList::Dump (Stream *s) const
155{
156    Mutex::Locker locker(m_mutex);
157    s->Printf("%p: ", this);
158    s->Indent();
159    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
160    s->IndentMore();
161    bp_collection::const_iterator pos;
162    bp_collection::const_iterator end = m_breakpoints.end();
163    for (pos = m_breakpoints.begin(); pos != end; ++pos)
164        (*pos)->Dump(s);
165    s->IndentLess();
166}
167
168
169BreakpointSP
170BreakpointList::GetBreakpointAtIndex (uint32_t i)
171{
172    Mutex::Locker locker(m_mutex);
173    BreakpointSP stop_sp;
174    bp_collection::iterator end = m_breakpoints.end();
175    bp_collection::iterator pos;
176    uint32_t curr_i = 0;
177    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
178    {
179        if (curr_i == i)
180            stop_sp = *pos;
181    }
182    return stop_sp;
183}
184
185const BreakpointSP
186BreakpointList::GetBreakpointAtIndex (uint32_t i) const
187{
188    Mutex::Locker locker(m_mutex);
189    BreakpointSP stop_sp;
190    bp_collection::const_iterator end = m_breakpoints.end();
191    bp_collection::const_iterator pos;
192    uint32_t curr_i = 0;
193    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
194    {
195        if (curr_i == i)
196            stop_sp = *pos;
197    }
198    return stop_sp;
199}
200
201void
202BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added)
203{
204    Mutex::Locker locker(m_mutex);
205    bp_collection::iterator end = m_breakpoints.end();
206    bp_collection::iterator pos;
207    for (pos = m_breakpoints.begin(); pos != end; ++pos)
208        (*pos)->ModulesChanged (module_list, added);
209
210}
211
212void
213BreakpointList::ClearAllBreakpointSites ()
214{
215    Mutex::Locker locker(m_mutex);
216    bp_collection::iterator end = m_breakpoints.end();
217    bp_collection::iterator pos;
218    for (pos = m_breakpoints.begin(); pos != end; ++pos)
219        (*pos)->ClearAllBreakpointSites ();
220
221}
222
223void
224BreakpointList::GetListMutex (Mutex::Locker &locker)
225{
226    return locker.Reset (m_mutex.GetMutex());
227}
228