1 /* 2 * Copyright 2001-2014 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * Erik Jaesler, erik@cgsoftware.com 8 */ 9 10 11 #include <TokenSpace.h> 12 13 #include <AppDefs.h> 14 #include <Handler.h> 15 #include <Looper.h> 16 #include <Message.h> 17 #include <MessageFilter.h> 18 #include <Messenger.h> 19 #include <PropertyInfo.h> 20 21 #include <algorithm> 22 #include <new> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <vector> 27 28 using std::map; 29 using std::vector; 30 using BPrivate::gDefaultTokens; 31 32 33 static const char* kArchiveNameField = "_name"; 34 35 static const uint32 kMsgStartObserving = '_OBS'; 36 static const uint32 kMsgStopObserving = '_OBP'; 37 static const char* kObserveTarget = "be:observe_target"; 38 39 40 static property_info sHandlerPropInfo[] = { 41 { 42 "Suites", // name 43 { B_GET_PROPERTY }, // commands 44 { B_DIRECT_SPECIFIER }, // specifiers 45 NULL, // usage 46 0, // extra data 47 { 0 }, // types 48 { // ctypes (compound_type) 49 { // ctypes[0] 50 { // pairs[0] 51 { 52 "suites", // name 53 B_STRING_TYPE // type 54 } 55 } 56 }, 57 { // ctypes[1] 58 { // pairs[0] 59 { 60 "messages", 61 B_PROPERTY_INFO_TYPE 62 } 63 } 64 } 65 }, 66 {} // reserved 67 }, 68 { 69 "Messenger", 70 { B_GET_PROPERTY }, 71 { B_DIRECT_SPECIFIER }, 72 NULL, 0, 73 { B_MESSENGER_TYPE }, 74 {}, 75 {} 76 }, 77 { 78 "InternalName", 79 { B_GET_PROPERTY }, 80 { B_DIRECT_SPECIFIER }, 81 NULL, 0, 82 { B_STRING_TYPE }, 83 {}, 84 {} 85 }, 86 {} 87 }; 88 89 bool FilterDeleter(void* filter); 90 91 namespace BPrivate { 92 93 class ObserverList { 94 public: 95 ObserverList(); 96 ~ObserverList(); 97 98 status_t SendNotices(uint32 what, const BMessage* notice); 99 status_t Add(const BHandler* handler, uint32 what); 100 status_t Add(const BMessenger& messenger, uint32 what); 101 status_t Remove(const BHandler* handler, uint32 what); 102 status_t Remove(const BMessenger& messenger, uint32 what); 103 bool IsEmpty(); 104 105 private: 106 typedef map<uint32, vector<const BHandler*> > HandlerObserverMap; 107 typedef map<uint32, vector<BMessenger> > MessengerObserverMap; 108 109 void _ValidateHandlers(uint32 what); 110 void _SendNotices(uint32 what, BMessage* notice); 111 112 HandlerObserverMap fHandlerMap; 113 MessengerObserverMap fMessengerMap; 114 }; 115 116 } // namespace BPrivate 117 118 using namespace BPrivate; 119 120 121 // #pragma mark - 122 123 124 BHandler::BHandler(const char* name) 125 : BArchivable(), 126 fName(NULL) 127 { 128 _InitData(name); 129 } 130 131 132 BHandler::~BHandler() 133 { 134 if (LockLooper()) { 135 BLooper* looper = Looper(); 136 looper->RemoveHandler(this); 137 looper->Unlock(); 138 } 139 140 // remove all filters 141 if (fFilters) { 142 int32 count = fFilters->CountItems(); 143 for (int32 i = 0; i < count; i++) 144 delete (BMessageFilter*)fFilters->ItemAtFast(i); 145 delete fFilters; 146 } 147 148 // remove all observers (the observer list manages itself) 149 delete fObserverList; 150 151 // free rest 152 free(fName); 153 gDefaultTokens.RemoveToken(fToken); 154 } 155 156 157 BHandler::BHandler(BMessage* data) 158 : BArchivable(data), 159 fName(NULL) 160 { 161 const char* name = NULL; 162 163 if (data) 164 data->FindString(kArchiveNameField, &name); 165 166 _InitData(name); 167 } 168 169 170 BArchivable* 171 BHandler::Instantiate(BMessage* data) 172 { 173 if (!validate_instantiation(data, "BHandler")) 174 return NULL; 175 176 return new BHandler(data); 177 } 178 179 180 status_t 181 BHandler::Archive(BMessage* data, bool deep) const 182 { 183 status_t status = BArchivable::Archive(data, deep); 184 if (status < B_OK) 185 return status; 186 187 if (fName == NULL) 188 return B_OK; 189 190 return data->AddString(kArchiveNameField, fName); 191 } 192 193 194 void 195 BHandler::MessageReceived(BMessage* message) 196 { 197 BMessage reply(B_REPLY); 198 199 switch (message->what) { 200 case kMsgStartObserving: 201 case kMsgStopObserving: 202 { 203 BMessenger target; 204 uint32 what; 205 if (message->FindMessenger(kObserveTarget, &target) != B_OK 206 || message->FindInt32(B_OBSERVE_WHAT_CHANGE, (int32*)&what) 207 != B_OK) { 208 break; 209 } 210 211 ObserverList* list = _ObserverList(); 212 if (list != NULL) { 213 if (message->what == kMsgStartObserving) 214 list->Add(target, what); 215 else 216 list->Remove(target, what); 217 } 218 break; 219 } 220 221 case B_GET_PROPERTY: 222 { 223 int32 cur; 224 BMessage specifier; 225 int32 form; 226 const char* prop; 227 228 status_t err = message->GetCurrentSpecifier(&cur, &specifier, 229 &form, &prop); 230 if (err != B_OK && err != B_BAD_SCRIPT_SYNTAX) 231 break; 232 bool known = false; 233 // B_BAD_SCRIPT_SYNTAX defaults to the Messenger property 234 if (err == B_BAD_SCRIPT_SYNTAX || cur < 0 235 || (strcmp(prop, "Messenger") == 0)) { 236 err = reply.AddMessenger("result", this); 237 known = true; 238 } else if (strcmp(prop, "Suites") == 0) { 239 err = GetSupportedSuites(&reply); 240 known = true; 241 } else if (strcmp(prop, "InternalName") == 0) { 242 err = reply.AddString("result", Name()); 243 known = true; 244 } 245 246 if (known) { 247 reply.AddInt32("error", B_OK); 248 message->SendReply(&reply); 249 return; 250 } 251 // let's try next handler 252 break; 253 } 254 255 case B_GET_SUPPORTED_SUITES: 256 { 257 reply.AddInt32("error", GetSupportedSuites(&reply)); 258 message->SendReply(&reply); 259 return; 260 } 261 } 262 263 // ToDo: there is some more work needed here 264 // (someone in the know should fill in)! 265 266 if (fNextHandler) { 267 // we need to apply the next handler's filters here, too 268 BHandler* target = Looper()->_HandlerFilter(message, fNextHandler); 269 if (target != NULL && target != this) { 270 // TODO: we also need to make sure that "target" is not before 271 // us in the handler chain - at least in case it wasn't before 272 // the handler actually targeted with this message - this could 273 // get ugly, though. 274 target->MessageReceived(message); 275 } 276 } else if (message->what != B_MESSAGE_NOT_UNDERSTOOD 277 && (message->WasDropped() || message->HasSpecifiers())) { 278 printf("BHandler %s: MessageReceived() couldn't understand the message:\n", Name()); 279 message->PrintToStream(); 280 message->SendReply(B_MESSAGE_NOT_UNDERSTOOD); 281 } 282 } 283 284 285 BLooper* 286 BHandler::Looper() const 287 { 288 return fLooper; 289 } 290 291 292 void 293 BHandler::SetName(const char* name) 294 { 295 if (fName != NULL) { 296 free(fName); 297 fName = NULL; 298 } 299 300 if (name != NULL) 301 fName = strdup(name); 302 } 303 304 305 const char* 306 BHandler::Name() const 307 { 308 return fName; 309 } 310 311 312 void 313 BHandler::SetNextHandler(BHandler* handler) 314 { 315 if (fLooper == NULL) { 316 debugger("handler must belong to looper before setting NextHandler"); 317 return; 318 } 319 320 if (!fLooper->IsLocked()) { 321 debugger("The handler's looper must be locked before setting NextHandler"); 322 return; 323 } 324 325 if (handler != NULL && fLooper != handler->Looper()) { 326 debugger("The handler and its NextHandler must have the same looper"); 327 return; 328 } 329 330 fNextHandler = handler; 331 } 332 333 334 BHandler* 335 BHandler::NextHandler() const 336 { 337 return fNextHandler; 338 } 339 340 341 void 342 BHandler::AddFilter(BMessageFilter* filter) 343 { 344 BLooper* looper = fLooper; 345 if (looper != NULL && !looper->IsLocked()) { 346 debugger("Owning Looper must be locked before calling SetFilterList"); 347 return; 348 } 349 350 if (looper != NULL) 351 filter->SetLooper(looper); 352 353 if (fFilters == NULL) 354 fFilters = new BList; 355 356 fFilters->AddItem(filter); 357 } 358 359 360 bool 361 BHandler::RemoveFilter(BMessageFilter* filter) 362 { 363 BLooper* looper = fLooper; 364 if (looper != NULL && !looper->IsLocked()) { 365 debugger("Owning Looper must be locked before calling SetFilterList"); 366 return false; 367 } 368 369 if (fFilters != NULL && fFilters->RemoveItem((void*)filter)) { 370 filter->SetLooper(NULL); 371 return true; 372 } 373 374 return false; 375 } 376 377 378 void 379 BHandler::SetFilterList(BList* filters) 380 { 381 BLooper* looper = fLooper; 382 if (looper != NULL && !looper->IsLocked()) { 383 debugger("Owning Looper must be locked before calling SetFilterList"); 384 return; 385 } 386 387 /** 388 @note I would like to use BObjectList internally, but this function is 389 spec'd such that fFilters would get deleted and then assigned 390 'filters', which would obviously mess this up. Wondering if 391 anyone ever assigns a list of filters and then checks against 392 FilterList() to see if they are the same. 393 */ 394 395 // TODO: Explore issues with using BObjectList 396 if (fFilters != NULL) { 397 fFilters->DoForEach(FilterDeleter); 398 delete fFilters; 399 } 400 401 fFilters = filters; 402 if (fFilters) { 403 for (int32 i = 0; i < fFilters->CountItems(); ++i) { 404 BMessageFilter* filter = 405 static_cast<BMessageFilter*>(fFilters->ItemAt(i)); 406 if (filter != NULL) 407 filter->SetLooper(looper); 408 } 409 } 410 } 411 412 413 BList* 414 BHandler::FilterList() 415 { 416 return fFilters; 417 } 418 419 420 bool 421 BHandler::LockLooper() 422 { 423 BLooper* looper = fLooper; 424 // Locking the looper also makes sure that the looper is valid 425 if (looper != NULL && looper->Lock()) { 426 // Have we locked the right looper? That's as far as the 427 // "pseudo-atomic" operation mentioned in the BeBook. 428 if (fLooper == looper) 429 return true; 430 431 // we locked the wrong looper, bail out 432 looper->Unlock(); 433 } 434 435 return false; 436 } 437 438 439 status_t 440 BHandler::LockLooperWithTimeout(bigtime_t timeout) 441 { 442 BLooper* looper = fLooper; 443 if (looper == NULL) 444 return B_BAD_VALUE; 445 446 status_t status = looper->LockWithTimeout(timeout); 447 if (status != B_OK) 448 return status; 449 450 if (fLooper != looper) { 451 // we locked the wrong looper, bail out 452 looper->Unlock(); 453 return B_MISMATCHED_VALUES; 454 } 455 456 return B_OK; 457 } 458 459 460 void 461 BHandler::UnlockLooper() 462 { 463 fLooper->Unlock(); 464 } 465 466 467 BHandler* 468 BHandler::ResolveSpecifier(BMessage* message, int32 index, 469 BMessage* specifier, int32 what, const char* property) 470 { 471 // Straight from the BeBook 472 BPropertyInfo propertyInfo(sHandlerPropInfo); 473 if (propertyInfo.FindMatch(message, index, specifier, what, property) >= 0) 474 return this; 475 476 BMessage reply(B_MESSAGE_NOT_UNDERSTOOD); 477 reply.AddInt32("error", B_BAD_SCRIPT_SYNTAX); 478 reply.AddString("message", "Didn't understand the specifier(s)"); 479 message->SendReply(&reply); 480 481 return NULL; 482 } 483 484 485 status_t 486 BHandler::GetSupportedSuites(BMessage* data) 487 { 488 /** 489 @note This is the output from the original implementation (calling 490 PrintToStream() on both data and the contained BPropertyInfo): 491 492 BMessage: what = (0x0, or 0) 493 entry suites, type='CSTR', c=1, size=21, data[0]: "suite/vnd.Be-handler" 494 entry messages, type='SCTD', c=1, size= 0, 495 property commands types specifiers 496 -------------------------------------------------------------------------------- 497 Suites PGET 1 498 (RTSC,suites) 499 (DTCS,messages) 500 501 Messenger PGET GNSM 1 502 InternalName PGET RTSC 1 503 504 With a good deal of trial and error, I determined that the 505 parenthetical clauses are entries in the 'ctypes' field of 506 property_info. 'ctypes' is an array of 'compound_type', which 507 contains an array of 'field_pair's. I haven't the foggiest what 508 either 'compound_type' or 'field_pair' is for, being as the 509 scripting docs are so bloody horrible. The corresponding 510 property_info array is declared in the globals section. 511 */ 512 513 status_t err = B_OK; 514 if (data == NULL) 515 err = B_BAD_VALUE; 516 517 if (err != B_OK) { 518 err = data->AddString("suites", "suite/vnd.Be-handler"); 519 if (err != B_OK) { 520 BPropertyInfo propertyInfo(sHandlerPropInfo); 521 err = data->AddFlat("messages", &propertyInfo); 522 } 523 } 524 525 return err; 526 } 527 528 529 status_t 530 BHandler::StartWatching(BMessenger target, uint32 what) 531 { 532 BMessage message(kMsgStartObserving); 533 message.AddMessenger(kObserveTarget, this); 534 message.AddInt32(B_OBSERVE_WHAT_CHANGE, what); 535 536 return target.SendMessage(&message); 537 } 538 539 540 status_t 541 BHandler::StartWatchingAll(BMessenger target) 542 { 543 return StartWatching(target, B_OBSERVER_OBSERVE_ALL); 544 } 545 546 547 status_t 548 BHandler::StopWatching(BMessenger target, uint32 what) 549 { 550 BMessage message(kMsgStopObserving); 551 message.AddMessenger(kObserveTarget, this); 552 message.AddInt32(B_OBSERVE_WHAT_CHANGE, what); 553 554 return target.SendMessage(&message); 555 } 556 557 558 status_t 559 BHandler::StopWatchingAll(BMessenger target) 560 { 561 return StopWatching(target, B_OBSERVER_OBSERVE_ALL); 562 } 563 564 565 status_t 566 BHandler::StartWatching(BHandler* handler, uint32 what) 567 { 568 ObserverList* list = _ObserverList(); 569 if (list == NULL) 570 return B_NO_MEMORY; 571 572 return list->Add(handler, what); 573 } 574 575 576 status_t 577 BHandler::StartWatchingAll(BHandler* handler) 578 { 579 return StartWatching(handler, B_OBSERVER_OBSERVE_ALL); 580 } 581 582 583 status_t 584 BHandler::StopWatching(BHandler* handler, uint32 what) 585 { 586 ObserverList* list = _ObserverList(); 587 if (list == NULL) 588 return B_NO_MEMORY; 589 590 return list->Remove(handler, what); 591 } 592 593 594 status_t 595 BHandler::StopWatchingAll(BHandler* handler) 596 { 597 return StopWatching(handler, B_OBSERVER_OBSERVE_ALL); 598 } 599 600 601 status_t 602 BHandler::Perform(perform_code d, void* arg) 603 { 604 return BArchivable::Perform(d, arg); 605 } 606 607 608 void 609 BHandler::SendNotices(uint32 what, const BMessage* notice) 610 { 611 if (fObserverList != NULL) 612 fObserverList->SendNotices(what, notice); 613 } 614 615 616 bool 617 BHandler::IsWatched() const 618 { 619 return fObserverList && !fObserverList->IsEmpty(); 620 } 621 622 623 void 624 BHandler::_InitData(const char* name) 625 { 626 SetName(name); 627 628 fLooper = NULL; 629 fNextHandler = NULL; 630 fFilters = NULL; 631 fObserverList = NULL; 632 633 fToken = gDefaultTokens.NewToken(B_HANDLER_TOKEN, this); 634 } 635 636 637 ObserverList* 638 BHandler::_ObserverList() 639 { 640 if (fObserverList == NULL) 641 fObserverList = new (std::nothrow) BPrivate::ObserverList(); 642 643 return fObserverList; 644 } 645 646 647 BHandler::BHandler(const BHandler &) 648 { 649 // No copy construction allowed. 650 } 651 652 653 BHandler & 654 BHandler::operator=(const BHandler &) 655 { 656 // No assignments allowed. 657 return *this; 658 } 659 660 661 void 662 BHandler::SetLooper(BLooper* looper) 663 { 664 fLooper = looper; 665 gDefaultTokens.SetHandlerTarget(fToken, 666 looper ? looper->fDirectTarget : NULL); 667 668 if (fFilters != NULL) { 669 for (int32 i = 0; i < fFilters->CountItems(); i++) { 670 static_cast<BMessageFilter*>( 671 fFilters->ItemAtFast(i))->SetLooper(looper); 672 } 673 } 674 } 675 676 677 #if __GNUC__ < 3 678 // binary compatibility with R4.5 679 680 extern "C" void 681 _ReservedHandler1__8BHandler(BHandler* handler, uint32 what, 682 const BMessage* notice) 683 { 684 handler->BHandler::SendNotices(what, notice); 685 } 686 687 #endif 688 689 void BHandler::_ReservedHandler2() {} 690 void BHandler::_ReservedHandler3() {} 691 void BHandler::_ReservedHandler4() {} 692 693 694 // #pragma mark - 695 696 697 ObserverList::ObserverList() 698 { 699 } 700 701 702 ObserverList::~ObserverList() 703 { 704 } 705 706 707 void 708 ObserverList::_ValidateHandlers(uint32 what) 709 { 710 vector<const BHandler*>& handlers = fHandlerMap[what]; 711 vector<const BHandler*>::iterator iterator = handlers.begin(); 712 713 while (iterator != handlers.end()) { 714 BMessenger target(*iterator); 715 if (!target.IsValid()) { 716 iterator++; 717 continue; 718 } 719 720 Add(target, what); 721 iterator = handlers.erase(iterator); 722 } 723 } 724 725 726 void 727 ObserverList::_SendNotices(uint32 what, BMessage* notice) 728 { 729 // first iterate over the list of handlers and try to make valid 730 // messengers out of them 731 _ValidateHandlers(what); 732 733 // now send it to all messengers we know 734 vector<BMessenger>& messengers = fMessengerMap[what]; 735 vector<BMessenger>::iterator iterator = messengers.begin(); 736 737 while (iterator != messengers.end()) { 738 if (!(*iterator).IsValid()) { 739 iterator = messengers.erase(iterator); 740 continue; 741 } 742 743 (*iterator).SendMessage(notice); 744 iterator++; 745 } 746 } 747 748 749 status_t 750 ObserverList::SendNotices(uint32 what, const BMessage* notice) 751 { 752 BMessage* copy = NULL; 753 if (notice != NULL) { 754 copy = new BMessage(*notice); 755 copy->what = B_OBSERVER_NOTICE_CHANGE; 756 copy->AddInt32(B_OBSERVE_ORIGINAL_WHAT, notice->what); 757 } else 758 copy = new BMessage(B_OBSERVER_NOTICE_CHANGE); 759 760 copy->AddInt32(B_OBSERVE_WHAT_CHANGE, what); 761 762 _SendNotices(what, copy); 763 _SendNotices(B_OBSERVER_OBSERVE_ALL, copy); 764 765 delete copy; 766 767 return B_OK; 768 } 769 770 771 status_t 772 ObserverList::Add(const BHandler* handler, uint32 what) 773 { 774 if (handler == NULL) 775 return B_BAD_HANDLER; 776 777 // if this handler already represents a valid target, add its messenger 778 BMessenger target(handler); 779 if (target.IsValid()) 780 return Add(target, what); 781 782 vector<const BHandler*> &handlers = fHandlerMap[what]; 783 784 vector<const BHandler*>::iterator iter; 785 iter = find(handlers.begin(), handlers.end(), handler); 786 if (iter != handlers.end()) { 787 // TODO: do we want to have a reference count for this? 788 return B_OK; 789 } 790 791 handlers.push_back(handler); 792 return B_OK; 793 } 794 795 796 status_t 797 ObserverList::Add(const BMessenger &messenger, uint32 what) 798 { 799 vector<BMessenger> &messengers = fMessengerMap[what]; 800 801 vector<BMessenger>::iterator iter; 802 iter = find(messengers.begin(), messengers.end(), messenger); 803 if (iter != messengers.end()) { 804 // TODO: do we want to have a reference count for this? 805 return B_OK; 806 } 807 808 messengers.push_back(messenger); 809 return B_OK; 810 } 811 812 813 status_t 814 ObserverList::Remove(const BHandler* handler, uint32 what) 815 { 816 if (handler == NULL) 817 return B_BAD_HANDLER; 818 819 // look into the list of messengers 820 BMessenger target(handler); 821 if (target.IsValid() && Remove(target, what) == B_OK) 822 return B_OK; 823 824 vector<const BHandler*> &handlers = fHandlerMap[what]; 825 826 vector<const BHandler*>::iterator iterator = find(handlers.begin(), 827 handlers.end(), handler); 828 if (iterator != handlers.end()) { 829 handlers.erase(iterator); 830 if (handlers.empty()) 831 fHandlerMap.erase(what); 832 833 return B_OK; 834 } 835 836 return B_BAD_HANDLER; 837 } 838 839 840 status_t 841 ObserverList::Remove(const BMessenger &messenger, uint32 what) 842 { 843 vector<BMessenger> &messengers = fMessengerMap[what]; 844 845 vector<BMessenger>::iterator iterator = find(messengers.begin(), 846 messengers.end(), messenger); 847 if (iterator != messengers.end()) { 848 messengers.erase(iterator); 849 if (messengers.empty()) 850 fMessengerMap.erase(what); 851 852 return B_OK; 853 } 854 855 return B_BAD_HANDLER; 856 } 857 858 859 bool 860 ObserverList::IsEmpty() 861 { 862 return fHandlerMap.empty() && fMessengerMap.empty(); 863 } 864 865 866 // #pragma mark - 867 868 869 bool 870 FilterDeleter(void* _filter) 871 { 872 delete static_cast<BMessageFilter*>(_filter); 873 return false; 874 } 875