1 //===-- Listener.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/Core/Listener.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Broadcaster.h" 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/StreamString.h" 19 #include "lldb/Core/Event.h" 20 #include "lldb/Host/TimeValue.h" 21 #include "lldb/lldb-private-log.h" 22 #include <algorithm> 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 Listener::Listener(const char *name) : 28 m_name (name), 29 m_broadcasters(), 30 m_broadcasters_mutex (Mutex::eMutexTypeRecursive), 31 m_events (), 32 m_events_mutex (Mutex::eMutexTypeRecursive), 33 m_cond_wait() 34 { 35 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 36 if (log) 37 log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str()); 38 } 39 40 Listener::~Listener() 41 { 42 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 43 Mutex::Locker locker (m_broadcasters_mutex); 44 45 size_t num_managers = m_broadcaster_managers.size(); 46 47 for (size_t i = 0; i < num_managers; i++) 48 m_broadcaster_managers[i]->RemoveListener(*this); 49 50 if (log) 51 log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str()); 52 Clear(); 53 } 54 55 void 56 Listener::Clear() 57 { 58 Mutex::Locker locker(m_broadcasters_mutex); 59 broadcaster_collection::iterator pos, end = m_broadcasters.end(); 60 for (pos = m_broadcasters.begin(); pos != end; ++pos) 61 pos->first->RemoveListener (this, pos->second.event_mask); 62 m_broadcasters.clear(); 63 m_cond_wait.SetValue (false, eBroadcastNever); 64 m_broadcasters.clear(); 65 Mutex::Locker event_locker(m_events_mutex); 66 m_events.clear(); 67 } 68 69 uint32_t 70 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask) 71 { 72 if (broadcaster) 73 { 74 // Scope for "locker" 75 // Tell the broadcaster to add this object as a listener 76 { 77 Mutex::Locker locker(m_broadcasters_mutex); 78 m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask))); 79 } 80 81 uint32_t acquired_mask = broadcaster->AddListener (this, event_mask); 82 83 if (event_mask != acquired_mask) 84 { 85 86 } 87 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 88 if (log) 89 log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s", 90 this, 91 broadcaster, 92 event_mask, 93 acquired_mask, 94 m_name.c_str()); 95 96 return acquired_mask; 97 98 } 99 return 0; 100 } 101 102 uint32_t 103 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data) 104 { 105 if (broadcaster) 106 { 107 // Scope for "locker" 108 // Tell the broadcaster to add this object as a listener 109 { 110 Mutex::Locker locker(m_broadcasters_mutex); 111 m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data))); 112 } 113 114 uint32_t acquired_mask = broadcaster->AddListener (this, event_mask); 115 116 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 117 if (log) 118 log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s", 119 this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str()); 120 121 return acquired_mask; 122 } 123 return 0; 124 } 125 126 bool 127 Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask) 128 { 129 if (broadcaster) 130 { 131 // Scope for "locker" 132 { 133 Mutex::Locker locker(m_broadcasters_mutex); 134 m_broadcasters.erase (broadcaster); 135 } 136 // Remove the broadcaster from our set of broadcasters 137 return broadcaster->RemoveListener (this, event_mask); 138 } 139 140 return false; 141 } 142 143 // Called when a Broadcaster is in its destuctor. We need to remove all 144 // knowledge of this broadcaster and any events that it may have queued up 145 void 146 Listener::BroadcasterWillDestruct (Broadcaster *broadcaster) 147 { 148 // Scope for "broadcasters_locker" 149 { 150 Mutex::Locker broadcasters_locker(m_broadcasters_mutex); 151 m_broadcasters.erase (broadcaster); 152 } 153 154 // Scope for "event_locker" 155 { 156 Mutex::Locker event_locker(m_events_mutex); 157 // Remove all events for this broadcaster object. 158 event_collection::iterator pos = m_events.begin(); 159 while (pos != m_events.end()) 160 { 161 if ((*pos)->GetBroadcaster() == broadcaster) 162 pos = m_events.erase(pos); 163 else 164 ++pos; 165 } 166 167 if (m_events.empty()) 168 m_cond_wait.SetValue (false, eBroadcastNever); 169 170 } 171 } 172 173 void 174 Listener::BroadcasterManagerWillDestruct (BroadcasterManager *manager) 175 { 176 // Just need to remove this broadcast manager from the list of managers: 177 broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end(); 178 iter = find(m_broadcaster_managers.begin(), end_iter, manager); 179 if (iter != end_iter) 180 m_broadcaster_managers.erase (iter); 181 } 182 183 void 184 Listener::AddEvent (EventSP &event_sp) 185 { 186 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 187 if (log) 188 log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get()); 189 190 // Scope for "locker" 191 { 192 Mutex::Locker locker(m_events_mutex); 193 m_events.push_back (event_sp); 194 } 195 m_cond_wait.SetValue (true, eBroadcastAlways); 196 } 197 198 class EventBroadcasterMatches 199 { 200 public: 201 EventBroadcasterMatches (Broadcaster *broadcaster) : 202 m_broadcaster (broadcaster) { 203 } 204 205 bool operator() (const EventSP &event_sp) const 206 { 207 if (event_sp->BroadcasterIs(m_broadcaster)) 208 return true; 209 else 210 return false; 211 } 212 213 private: 214 Broadcaster *m_broadcaster; 215 216 }; 217 218 class EventMatcher 219 { 220 public: 221 EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) : 222 m_broadcaster (broadcaster), 223 m_broadcaster_names (broadcaster_names), 224 m_num_broadcaster_names (num_broadcaster_names), 225 m_event_type_mask (event_type_mask) 226 { 227 } 228 229 bool operator() (const EventSP &event_sp) const 230 { 231 if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster)) 232 return false; 233 234 if (m_broadcaster_names) 235 { 236 bool found_source = false; 237 const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName(); 238 for (uint32_t i=0; i<m_num_broadcaster_names; ++i) 239 { 240 if (m_broadcaster_names[i] == event_broadcaster_name) 241 { 242 found_source = true; 243 break; 244 } 245 } 246 if (!found_source) 247 return false; 248 } 249 250 if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType()) 251 return true; 252 return false; 253 } 254 255 private: 256 Broadcaster *m_broadcaster; 257 const ConstString *m_broadcaster_names; 258 const uint32_t m_num_broadcaster_names; 259 const uint32_t m_event_type_mask; 260 }; 261 262 263 bool 264 Listener::FindNextEventInternal 265 ( 266 Broadcaster *broadcaster, // NULL for any broadcaster 267 const ConstString *broadcaster_names, // NULL for any event 268 uint32_t num_broadcaster_names, 269 uint32_t event_type_mask, 270 EventSP &event_sp, 271 bool remove) 272 { 273 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 274 275 Mutex::Locker lock(m_events_mutex); 276 277 if (m_events.empty()) 278 return false; 279 280 281 Listener::event_collection::iterator pos = m_events.end(); 282 283 if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0) 284 { 285 pos = m_events.begin(); 286 } 287 else 288 { 289 pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask)); 290 } 291 292 if (pos != m_events.end()) 293 { 294 event_sp = *pos; 295 296 if (log) 297 log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p", 298 this, 299 GetName(), 300 broadcaster, 301 broadcaster_names, 302 num_broadcaster_names, 303 event_type_mask, 304 remove, 305 event_sp.get()); 306 307 if (remove) 308 { 309 m_events.erase(pos); 310 311 if (m_events.empty()) 312 m_cond_wait.SetValue (false, eBroadcastNever); 313 } 314 315 // Unlock the event queue here. We've removed this event and are about to return 316 // it so it should be okay to get the next event off the queue here - and it might 317 // be useful to do that in the "DoOnRemoval". 318 lock.Unlock(); 319 320 // Don't call DoOnRemoval if you aren't removing the event... 321 if (remove) 322 event_sp->DoOnRemoval(); 323 324 return true; 325 } 326 327 event_sp.reset(); 328 return false; 329 } 330 331 Event * 332 Listener::PeekAtNextEvent () 333 { 334 EventSP event_sp; 335 if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false)) 336 return event_sp.get(); 337 return NULL; 338 } 339 340 Event * 341 Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster) 342 { 343 EventSP event_sp; 344 if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false)) 345 return event_sp.get(); 346 return NULL; 347 } 348 349 Event * 350 Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask) 351 { 352 EventSP event_sp; 353 if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false)) 354 return event_sp.get(); 355 return NULL; 356 } 357 358 359 bool 360 Listener::GetNextEventInternal 361 ( 362 Broadcaster *broadcaster, // NULL for any broadcaster 363 const ConstString *broadcaster_names, // NULL for any event 364 uint32_t num_broadcaster_names, 365 uint32_t event_type_mask, 366 EventSP &event_sp 367 ) 368 { 369 return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true); 370 } 371 372 bool 373 Listener::GetNextEvent (EventSP &event_sp) 374 { 375 return GetNextEventInternal (NULL, NULL, 0, 0, event_sp); 376 } 377 378 379 bool 380 Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp) 381 { 382 return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp); 383 } 384 385 bool 386 Listener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp) 387 { 388 return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp); 389 } 390 391 392 bool 393 Listener::WaitForEventsInternal 394 ( 395 const TimeValue *timeout, 396 Broadcaster *broadcaster, // NULL for any broadcaster 397 const ConstString *broadcaster_names, // NULL for any event 398 uint32_t num_broadcaster_names, 399 uint32_t event_type_mask, 400 EventSP &event_sp 401 ) 402 { 403 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS)); 404 bool timed_out = false; 405 406 if (log) 407 { 408 log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s", 409 this, timeout, m_name.c_str()); 410 } 411 412 while (1) 413 { 414 // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval 415 // code might require that new events be serviced. For instance, the Breakpoint Command's 416 if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp)) 417 return true; 418 419 { 420 // Reset condition value to false, so we can wait for new events to be 421 // added that might meet our current filter 422 // But first poll for any new event that might satisfy our condition, and if so consume it, 423 // otherwise wait. 424 425 Mutex::Locker event_locker(m_events_mutex); 426 const bool remove = false; 427 if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove)) 428 continue; 429 else 430 m_cond_wait.SetValue (false, eBroadcastNever); 431 } 432 433 if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out)) 434 continue; 435 436 else if (timed_out) 437 { 438 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS); 439 if (log) 440 log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str()); 441 break; 442 } 443 else 444 { 445 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS); 446 if (log) 447 log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str()); 448 break; 449 } 450 } 451 452 return false; 453 } 454 455 bool 456 Listener::WaitForEventForBroadcasterWithType 457 ( 458 const TimeValue *timeout, 459 Broadcaster *broadcaster, 460 uint32_t event_type_mask, 461 EventSP &event_sp 462 ) 463 { 464 return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp); 465 } 466 467 bool 468 Listener::WaitForEventForBroadcaster 469 ( 470 const TimeValue *timeout, 471 Broadcaster *broadcaster, 472 EventSP &event_sp 473 ) 474 { 475 return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp); 476 } 477 478 bool 479 Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp) 480 { 481 return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp); 482 } 483 484 //Listener::broadcaster_collection::iterator 485 //Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact) 486 //{ 487 // broadcaster_collection::iterator pos; 488 // broadcaster_collection::iterator end = m_broadcasters.end(); 489 // for (pos = m_broadcasters.find (broadcaster); 490 // pos != end && pos->first == broadcaster; 491 // ++pos) 492 // { 493 // if (exact) 494 // { 495 // if ((event_mask & pos->second.event_mask) == event_mask) 496 // return pos; 497 // } 498 // else 499 // { 500 // if (event_mask & pos->second.event_mask) 501 // return pos; 502 // } 503 // } 504 // return end; 505 //} 506 507 size_t 508 Listener::HandleBroadcastEvent (EventSP &event_sp) 509 { 510 size_t num_handled = 0; 511 Mutex::Locker locker(m_broadcasters_mutex); 512 Broadcaster *broadcaster = event_sp->GetBroadcaster(); 513 broadcaster_collection::iterator pos; 514 broadcaster_collection::iterator end = m_broadcasters.end(); 515 for (pos = m_broadcasters.find (broadcaster); 516 pos != end && pos->first == broadcaster; 517 ++pos) 518 { 519 BroadcasterInfo info = pos->second; 520 if (event_sp->GetType () & info.event_mask) 521 { 522 if (info.callback != NULL) 523 { 524 info.callback (event_sp, info.callback_user_data); 525 ++num_handled; 526 } 527 } 528 } 529 return num_handled; 530 } 531 532 uint32_t 533 Listener::StartListeningForEventSpec (BroadcasterManager &manager, 534 const BroadcastEventSpec &event_spec) 535 { 536 // The BroadcasterManager mutex must be locked before m_broadcasters_mutex 537 // to avoid violating the lock hierarchy (manager before broadcasters). 538 Mutex::Locker manager_locker(manager.m_manager_mutex); 539 Mutex::Locker locker(m_broadcasters_mutex); 540 541 uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec); 542 if (bits_acquired) 543 m_broadcaster_managers.push_back(&manager); 544 545 return bits_acquired; 546 } 547 548 bool 549 Listener::StopListeningForEventSpec (BroadcasterManager &manager, 550 const BroadcastEventSpec &event_spec) 551 { 552 Mutex::Locker locker(m_broadcasters_mutex); 553 return manager.UnregisterListenerForEvents (*this, event_spec); 554 555 } 556 557 558