SBQueue.cpp revision 269024
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 22using namespace lldb; 23using namespace lldb_private; 24 25namespace 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 272SBQueue::SBQueue () : 273 m_opaque_sp (new QueueImpl()) 274{ 275} 276 277SBQueue::SBQueue (const QueueSP& queue_sp) : 278 m_opaque_sp (new QueueImpl (queue_sp)) 279{ 280} 281 282SBQueue::SBQueue (const SBQueue &rhs) 283{ 284 if (&rhs == this) 285 return; 286 287 m_opaque_sp = rhs.m_opaque_sp; 288} 289 290const lldb::SBQueue & 291SBQueue::operator = (const lldb::SBQueue &rhs) 292{ 293 m_opaque_sp = rhs.m_opaque_sp; 294 return *this; 295} 296 297SBQueue::~SBQueue() 298{ 299} 300 301bool 302SBQueue::IsValid() const 303{ 304 return m_opaque_sp->IsValid(); 305} 306 307 308void 309SBQueue::Clear () 310{ 311 m_opaque_sp->Clear(); 312} 313 314 315void 316SBQueue::SetQueue (const QueueSP& queue_sp) 317{ 318 m_opaque_sp->SetQueue (queue_sp); 319} 320 321lldb::queue_id_t 322SBQueue::GetQueueID () const 323{ 324 return m_opaque_sp->GetQueueID (); 325} 326 327uint32_t 328SBQueue::GetIndexID () const 329{ 330 return m_opaque_sp->GetIndexID (); 331} 332 333const char * 334SBQueue::GetName () const 335{ 336 return m_opaque_sp->GetName (); 337} 338 339uint32_t 340SBQueue::GetNumThreads () 341{ 342 return m_opaque_sp->GetNumThreads (); 343} 344 345SBThread 346SBQueue::GetThreadAtIndex (uint32_t idx) 347{ 348 return m_opaque_sp->GetThreadAtIndex (idx); 349} 350 351 352uint32_t 353SBQueue::GetNumPendingItems () 354{ 355 return m_opaque_sp->GetNumPendingItems (); 356} 357 358SBQueueItem 359SBQueue::GetPendingItemAtIndex (uint32_t idx) 360{ 361 return m_opaque_sp->GetPendingItemAtIndex (idx); 362} 363 364SBProcess 365SBQueue::GetProcess () 366{ 367 return m_opaque_sp->GetProcess(); 368} 369