OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/multi_process_notification.h" | 5 #include "chrome/browser/multi_process_notification.h" |
6 | 6 |
7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
8 #include <notify.h> | 8 #include <notify.h> |
9 #include <sys/select.h> | 9 #include <sys/select.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 void OnListen(); | 182 void OnListen(); |
183 | 183 |
184 // Watcher overrides | 184 // Watcher overrides |
185 virtual void OnFileCanReadWithoutBlocking(int fd); | 185 virtual void OnFileCanReadWithoutBlocking(int fd); |
186 virtual void OnFileCanWriteWithoutBlocking(int fd); | 186 virtual void OnFileCanWriteWithoutBlocking(int fd); |
187 | 187 |
188 private: | 188 private: |
189 std::string name_; | 189 std::string name_; |
190 Domain domain_; | 190 Domain domain_; |
191 Listener::Delegate* delegate_; | 191 Listener::Delegate* delegate_; |
| 192 bool started_; |
192 int fd_; | 193 int fd_; |
193 int token_; | 194 int token_; |
194 Lock switchboard_lock_; | 195 Lock switchboard_lock_; |
195 static LeopardSwitchboardThread* g_switchboard_thread_; | 196 static LeopardSwitchboardThread* g_switchboard_thread_; |
196 base::MessagePumpLibevent::FileDescriptorWatcher watcher_; | 197 base::MessagePumpLibevent::FileDescriptorWatcher watcher_; |
197 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 198 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
198 | 199 |
199 void StartLeopard(); | 200 void StartLeopard(); |
200 void StartSnowLeopard(); | 201 void StartSnowLeopard(); |
201 DISALLOW_COPY_AND_ASSIGN(ListenerImpl); | 202 DISALLOW_COPY_AND_ASSIGN(ListenerImpl); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 } | 409 } |
409 | 410 |
410 void LeopardSwitchboardThread::OnFileCanWriteWithoutBlocking(int fd) { | 411 void LeopardSwitchboardThread::OnFileCanWriteWithoutBlocking(int fd) { |
411 NOTREACHED(); | 412 NOTREACHED(); |
412 } | 413 } |
413 | 414 |
414 LeopardSwitchboardThread* ListenerImpl::g_switchboard_thread_ = NULL; | 415 LeopardSwitchboardThread* ListenerImpl::g_switchboard_thread_ = NULL; |
415 | 416 |
416 ListenerImpl::ListenerImpl( | 417 ListenerImpl::ListenerImpl( |
417 const std::string& name, Domain domain, Listener::Delegate* delegate) | 418 const std::string& name, Domain domain, Listener::Delegate* delegate) |
418 : name_(name), domain_(domain), delegate_(delegate), fd_(-1), token_(-1) { | 419 : name_(name), domain_(domain), delegate_(delegate), started_(false), |
| 420 fd_(-1), token_(-1) { |
419 } | 421 } |
420 | 422 |
421 ListenerImpl::~ListenerImpl() { | 423 ListenerImpl::~ListenerImpl() { |
422 if (!UseLeopardSwitchboardThread()) { | 424 if (started_) { |
423 if (fd_ != -1) { | 425 if (!UseLeopardSwitchboardThread()) { |
424 uint32_t status = notify_cancel(token_); | 426 if (fd_ != -1) { |
425 DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); | 427 uint32_t status = notify_cancel(token_); |
426 } | 428 DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); |
427 } else { | 429 } |
428 base::AutoLock autolock(switchboard_lock_); | 430 } else { |
429 if (g_switchboard_thread_) { | 431 base::AutoLock autolock(switchboard_lock_); |
430 std::string notification = AddPrefixToNotification(name_, domain_); | 432 if (g_switchboard_thread_) { |
431 CHECK(g_switchboard_thread_->RemoveListener(this, notification)); | 433 std::string notification = AddPrefixToNotification(name_, domain_); |
| 434 CHECK(g_switchboard_thread_->RemoveListener(this, notification)); |
| 435 } |
432 } | 436 } |
433 } | 437 } |
434 } | 438 } |
435 | 439 |
436 bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) { | 440 bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) { |
437 DCHECK_EQ(fd_, -1); | 441 DCHECK_EQ(fd_, -1); |
438 DCHECK_EQ(token_, -1); | 442 DCHECK_EQ(token_, -1); |
439 if (io_loop_to_listen_on->type() != MessageLoop::TYPE_IO) { | 443 if (io_loop_to_listen_on->type() != MessageLoop::TYPE_IO) { |
440 DLOG(ERROR) << "io_loop_to_listen_on must be TYPE_IO"; | 444 DLOG(ERROR) << "io_loop_to_listen_on must be TYPE_IO"; |
441 return false; | 445 return false; |
(...skipping 26 matching lines...) Expand all Loading... |
468 success = g_switchboard_thread_->Init(); | 472 success = g_switchboard_thread_->Init(); |
469 if (success) { | 473 if (success) { |
470 g_switchboard_thread_->Start(); | 474 g_switchboard_thread_->Start(); |
471 } | 475 } |
472 } | 476 } |
473 if (success) { | 477 if (success) { |
474 std::string notification = AddPrefixToNotification(name_, domain_); | 478 std::string notification = AddPrefixToNotification(name_, domain_); |
475 success = g_switchboard_thread_->AddListener(this, notification); | 479 success = g_switchboard_thread_->AddListener(this, notification); |
476 } | 480 } |
477 } | 481 } |
| 482 started_ = success; |
478 Task* task = | 483 Task* task = |
479 new Listener::ListenerStartedTask(name_, domain_, delegate_, success); | 484 new Listener::ListenerStartedTask(name_, domain_, delegate_, success); |
480 CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); | 485 CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); |
481 } | 486 } |
482 | 487 |
483 void ListenerImpl::StartSnowLeopard() { | 488 void ListenerImpl::StartSnowLeopard() { |
484 DCHECK(!UseLeopardSwitchboardThread()); | 489 DCHECK(!UseLeopardSwitchboardThread()); |
485 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); | 490 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); |
486 bool success = true; | 491 bool success = true; |
487 std::string notification = AddPrefixToNotification(name_, domain_); | 492 std::string notification = AddPrefixToNotification(name_, domain_); |
488 uint32_t status = notify_register_file_descriptor( | 493 uint32_t status = notify_register_file_descriptor( |
489 notification.c_str(), &fd_, 0, &token_); | 494 notification.c_str(), &fd_, 0, &token_); |
490 if (status != NOTIFY_STATUS_OK) { | 495 if (status != NOTIFY_STATUS_OK) { |
491 LOG(ERROR) << "unable to notify_register_file_descriptor for '" | 496 LOG(ERROR) << "unable to notify_register_file_descriptor for '" |
492 << notification << "' Status: " << status; | 497 << notification << "' Status: " << status; |
493 success = false; | 498 success = false; |
494 } | 499 } |
495 if (success) { | 500 if (success) { |
496 MessageLoopForIO* io_loop = MessageLoopForIO::current(); | 501 MessageLoopForIO* io_loop = MessageLoopForIO::current(); |
497 success = io_loop->WatchFileDescriptor( | 502 success = io_loop->WatchFileDescriptor( |
498 fd_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); | 503 fd_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); |
| 504 if (!success) { |
| 505 uint32_t status = notify_cancel(token_); |
| 506 DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); |
| 507 fd_ = -1; |
| 508 } |
499 } | 509 } |
| 510 started_ = success; |
500 Task* task = | 511 Task* task = |
501 new Listener::ListenerStartedTask(name_, domain_, delegate_, success); | 512 new Listener::ListenerStartedTask(name_, domain_, delegate_, success); |
502 CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); | 513 CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); |
503 } | 514 } |
504 | 515 |
505 void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) { | 516 void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) { |
506 DCHECK(!UseLeopardSwitchboardThread()); | 517 DCHECK(!UseLeopardSwitchboardThread()); |
507 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); | 518 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); |
508 DCHECK_EQ(fd, fd_); | 519 DCHECK_EQ(fd, fd_); |
509 int token; | 520 int token; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 return impl_->name(); | 563 return impl_->name(); |
553 } | 564 } |
554 | 565 |
555 Domain Listener::domain() const { | 566 Domain Listener::domain() const { |
556 return impl_->domain(); | 567 return impl_->domain(); |
557 } | 568 } |
558 | 569 |
559 } // namespace multi_process_notification | 570 } // namespace multi_process_notification |
560 | 571 |
561 DISABLE_RUNNABLE_METHOD_REFCOUNT(multi_process_notification::ListenerImpl); | 572 DISABLE_RUNNABLE_METHOD_REFCOUNT(multi_process_notification::ListenerImpl); |
OLD | NEW |