]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/API/SBQueue.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / API / SBQueue.cpp
1 //===-- SBQueue.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/lldb-python.h"
11
12 #include "lldb/API/SBQueue.h"
13
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBThread.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/Queue.h"
19 #include "lldb/Target/QueueItem.h"
20 #include "lldb/Target/Thread.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 namespace lldb_private
26 {
27
28     class QueueImpl
29     {
30     public:
31         QueueImpl () :
32             m_queue_wp(),
33             m_threads(),
34             m_thread_list_fetched(false),
35             m_pending_items(),
36             m_pending_items_fetched(false)
37         {
38         }
39
40         QueueImpl (const lldb::QueueSP &queue_sp) :
41             m_queue_wp(),
42             m_threads(),
43             m_thread_list_fetched(false),
44             m_pending_items(),
45             m_pending_items_fetched(false)
46         {
47             m_queue_wp = queue_sp;
48         }
49
50         QueueImpl (const QueueImpl &rhs)
51         {
52             if (&rhs == this)
53                 return;
54             m_queue_wp = rhs.m_queue_wp;
55             m_threads = rhs.m_threads;
56             m_thread_list_fetched = rhs.m_thread_list_fetched;
57             m_pending_items = rhs.m_pending_items;
58             m_pending_items_fetched = rhs.m_pending_items_fetched;
59         }
60
61         ~QueueImpl ()
62         {
63         }
64
65         bool
66         IsValid ()
67         {
68             return m_queue_wp.lock() != NULL;
69         }
70
71         void
72         Clear ()
73         {
74             m_queue_wp.reset();
75             m_thread_list_fetched = false;
76             m_threads.clear();
77             m_pending_items_fetched = false;
78             m_pending_items.clear();
79         }
80
81         void
82         SetQueue (const lldb::QueueSP &queue_sp)
83         {
84             Clear();
85             m_queue_wp = queue_sp;
86         }
87
88         lldb::queue_id_t
89         GetQueueID () const
90         {
91             lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
92             lldb::QueueSP queue_sp = m_queue_wp.lock();
93             if (queue_sp)
94             {
95                 result = queue_sp->GetID();
96             }
97             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
98             if (log)
99                 log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, this, result);
100             return result;
101         }
102
103         uint32_t
104         GetIndexID () const
105         {
106             uint32_t result = LLDB_INVALID_INDEX32;
107             lldb::QueueSP queue_sp = m_queue_wp.lock();
108             if (queue_sp)
109             {
110                 result = queue_sp->GetIndexID();
111             }
112             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
113             if (log)
114                 log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d", this, result);
115             return result;
116         }
117         
118         const char *
119         GetName () const
120         {
121             const char *name = NULL;
122             lldb::QueueSP queue_sp = m_queue_wp.lock ();
123             if (queue_sp.get())
124             {
125                 name = queue_sp->GetName();
126             }
127         
128             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
129             if (log)
130                 log->Printf ("SBQueueImpl(%p)::GetName () => %s", this, name ? name : "NULL");
131         
132             return name;
133         }
134         
135         void
136         FetchThreads ()
137         {
138             if (m_thread_list_fetched == false)
139             {
140                 lldb::QueueSP queue_sp = m_queue_wp.lock();
141                 if (queue_sp)
142                 {
143                     Process::StopLocker stop_locker;
144                     if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
145                     {
146                         const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
147                         m_thread_list_fetched = true;
148                         const uint32_t num_threads = thread_list.size();
149                         for (uint32_t idx = 0; idx < num_threads; ++idx)
150                         {
151                             ThreadSP thread_sp = thread_list[idx];
152                             if (thread_sp && thread_sp->IsValid())
153                             {
154                                 m_threads.push_back (thread_sp);
155                             }
156                         }
157                     }
158                 }
159             }
160         }
161         
162         void
163         FetchItems ()
164         {
165             if (m_pending_items_fetched == false)
166             {
167                 QueueSP queue_sp = m_queue_wp.lock();
168                 if (queue_sp)
169                 {
170                     Process::StopLocker stop_locker;
171                     if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
172                     {
173                         const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems());
174                         m_pending_items_fetched = true;
175                         const uint32_t num_pending_items = queue_items.size();
176                         for (uint32_t idx = 0; idx < num_pending_items; ++idx)
177                         {
178                             QueueItemSP item = queue_items[idx];
179                             if (item && item->IsValid())
180                             {
181                                 m_pending_items.push_back (item);
182                             }
183                         }
184                     }
185                 }
186             }
187         }
188         
189         uint32_t
190         GetNumThreads ()
191         {
192             uint32_t result = 0;
193         
194             FetchThreads();
195             if (m_thread_list_fetched)
196             {
197                 result = m_threads.size();
198             }
199             return result;
200         }
201         
202         lldb::SBThread
203         GetThreadAtIndex (uint32_t idx)
204         {
205             FetchThreads();
206         
207             SBThread sb_thread;
208             QueueSP queue_sp = m_queue_wp.lock();
209             if (queue_sp && idx < m_threads.size())
210             {
211                 ProcessSP process_sp = queue_sp->GetProcess();
212                 if (process_sp)
213                 {
214                     ThreadSP thread_sp = m_threads[idx].lock();
215                     if (thread_sp)
216                     {
217                         sb_thread.SetThread (thread_sp);
218                     }
219                 }
220             }
221             return sb_thread;
222         }
223         
224         
225         uint32_t
226         GetNumPendingItems ()
227         {
228             uint32_t result = 0;
229             FetchItems();
230         
231             if (m_pending_items_fetched)
232             {
233                 result = m_pending_items.size();
234             }
235             return result;
236         }
237         
238         lldb::SBQueueItem
239         GetPendingItemAtIndex (uint32_t idx)
240         {
241             SBQueueItem result;
242             FetchItems();
243             if (m_pending_items_fetched && idx < m_pending_items.size())
244             {
245                 result.SetQueueItem (m_pending_items[idx]);
246             }
247             return result;
248         }
249         
250         lldb::SBProcess
251         GetProcess ()
252         {
253             SBProcess result;
254             QueueSP queue_sp = m_queue_wp.lock();
255             if (queue_sp)
256             {
257                 result.SetSP (queue_sp->GetProcess());
258             }
259             return result;
260         }
261
262     private:
263         lldb::QueueWP                   m_queue_wp;
264         std::vector<lldb::ThreadWP>     m_threads;              // threads currently executing this queue's items
265         bool                            m_thread_list_fetched;  // have we tried to fetch the threads list already?
266         std::vector<lldb::QueueItemSP>  m_pending_items;       // items currently enqueued
267         bool                            m_pending_items_fetched;  // have we tried to fetch the item list already?
268     };
269
270 }
271
272 SBQueue::SBQueue () :
273     m_opaque_sp (new QueueImpl())
274 {
275 }
276
277 SBQueue::SBQueue (const QueueSP& queue_sp) :
278     m_opaque_sp (new QueueImpl (queue_sp))
279 {
280 }
281
282 SBQueue::SBQueue (const SBQueue &rhs)
283 {
284     if (&rhs == this)
285         return;
286
287     m_opaque_sp = rhs.m_opaque_sp;
288 }
289
290 const lldb::SBQueue &
291 SBQueue::operator = (const lldb::SBQueue &rhs)
292 {
293     m_opaque_sp = rhs.m_opaque_sp;
294     return *this;
295 }
296
297 SBQueue::~SBQueue()
298 {
299 }
300
301 bool
302 SBQueue::IsValid() const
303 {
304     return m_opaque_sp->IsValid();
305 }
306
307
308 void
309 SBQueue::Clear ()
310 {
311     m_opaque_sp->Clear();
312 }
313
314
315 void
316 SBQueue::SetQueue (const QueueSP& queue_sp)
317 {
318     m_opaque_sp->SetQueue (queue_sp);
319 }
320
321 lldb::queue_id_t
322 SBQueue::GetQueueID () const
323 {
324     return m_opaque_sp->GetQueueID ();
325 }
326
327 uint32_t
328 SBQueue::GetIndexID () const
329 {
330     return m_opaque_sp->GetIndexID ();
331 }
332
333 const char *
334 SBQueue::GetName () const
335 {
336     return m_opaque_sp->GetName ();
337 }
338
339 uint32_t
340 SBQueue::GetNumThreads ()
341 {
342     return m_opaque_sp->GetNumThreads ();
343 }
344
345 SBThread
346 SBQueue::GetThreadAtIndex (uint32_t idx)
347 {
348     return m_opaque_sp->GetThreadAtIndex (idx);
349 }
350
351
352 uint32_t
353 SBQueue::GetNumPendingItems ()
354 {
355     return m_opaque_sp->GetNumPendingItems ();
356 }
357
358 SBQueueItem
359 SBQueue::GetPendingItemAtIndex (uint32_t idx)
360 {
361     return m_opaque_sp->GetPendingItemAtIndex (idx);
362 }
363
364 SBProcess
365 SBQueue::GetProcess ()
366 {
367     return m_opaque_sp->GetProcess();
368 }