Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/common/multi_process_notification_mac.mm

Issue 5970015: Add multi-process notification class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Responded to Mark's comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/multi_process_notification.h"
6
7 #import <Foundation/Foundation.h>
8 #include <notify.h>
9 #include <unistd.h>
10
11 #include "base/basictypes.h"
12 #include "base/eintr_wrapper.h"
13 #include "base/file_path.h"
14 #include "base/logging.h"
15 #include "base/mac/mac_util.h"
16 #include "base/mac/scoped_nsautorelease_pool.h"
17 #include "base/message_loop.h"
18 #include "base/message_pump_libevent.h"
19 #include "base/path_service.h"
20 #include "base/stringprintf.h"
21 #include "base/sys_string_conversions.h"
22 #include "base/task.h"
23 #include "chrome/common/chrome_paths.h"
24
25 namespace {
26
27 std::string AddPrefixToNotification(const std::string& name,
28 multi_process_notification::Domain domain) {
29 base::mac::ScopedNSAutoreleasePool pool;
30 NSBundle *bundle = base::mac::MainAppBundle();
31 NSString *ns_bundle_id = [bundle bundleIdentifier];
32 std::string bundle_id = base::SysNSStringToUTF8(ns_bundle_id);
33 std::string domain_string;
34 switch (domain) {
35 case multi_process_notification::ProfileDomain: {
36 FilePath user_data_dir;
37 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
38 NOTREACHED();
39 }
40 domain_string = StringPrintf("user.uid.%u.%s.",
Mark Mentovai 2011/01/06 18:46:44 Put a comment here referencing “man 3 notify” as y
41 getuid(), user_data_dir.value().c_str());
42 break;
43 }
44
45 case multi_process_notification::UserDomain:
46 domain_string = StringPrintf("user.uid.%u.", getuid());
47 break;
48
49 case multi_process_notification::SystemDomain:
50 break;
51 }
52 return domain_string + bundle_id + "." + name;
53 }
54
55
56 } // namespace
57
58 namespace multi_process_notification {
59
60 bool Post(const std::string& name, Domain domain) {
61 std::string notification = AddPrefixToNotification(name, domain);
62 uint32_t status = notify_post(notification.c_str());
63 DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK));
64 return status == NOTIFY_STATUS_OK;
65 }
66
67
68 class ListenerImpl : public base::MessagePumpLibevent::Watcher {
69 public:
70 ListenerImpl(const std::string& name,
71 Domain domain,
72 Listener::Delegate* delegate);
73 virtual ~ListenerImpl();
74
75 bool Start();
76
77 virtual void OnFileCanReadWithoutBlocking(int fd);
78 virtual void OnFileCanWriteWithoutBlocking(int fd);
79
80 private:
81 std::string name_;
82 Domain domain_;
83 Listener::Delegate* delegate_;
84 int fd_;
85 int token_;
86 base::MessagePumpLibevent::FileDescriptorWatcher watcher_;
87
88 DISALLOW_COPY_AND_ASSIGN(ListenerImpl);
89 };
90
91 ListenerImpl::ListenerImpl(const std::string& name,
92 Domain domain,
93 Listener::Delegate* delegate)
94 : name_(name), domain_(domain), delegate_(delegate), fd_(-1), token_(-1) {
95 }
96
97 ListenerImpl::~ListenerImpl() {
98 if (token_ != -1) {
99 uint32_t status = notify_cancel(token_);
100 DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK));
101 token_ = -1;
102 }
103 }
104
105 bool ListenerImpl::Start() {
106 DCHECK_EQ(fd_, -1);
107 DCHECK_EQ(token_, -1);
108 std::string notification = AddPrefixToNotification(name_, domain_);
109
110 uint32_t status = notify_register_file_descriptor(notification.c_str(), &fd_,
111 0, &token_);
112 if (status != NOTIFY_STATUS_OK) {
113 LOG(ERROR) << "Unable to notify_register_file_descriptor for '"
114 << notification << "' Status: " << status;
115 return false;
116 }
117
118 MessageLoopForIO *io_loop = MessageLoopForIO::current();
119 return io_loop->WatchFileDescriptor(fd_, true, MessageLoopForIO::WATCH_READ,
120 &watcher_, this);
121 }
122
123 void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) {
124 DCHECK_EQ(fd, fd_);
125 int token = 0;
126 if (HANDLE_EINTR(read(fd_, &token, sizeof(token))) >= 0) {
127 // Have to swap to native endianness <http://openradar.appspot.com/8821081>.
128 token = static_cast<int>(ntohl(token));
129 if (token == token_) {
130 delegate_->OnNotificationReceived(name_, domain_);
131 } else {
132 LOG(WARNING) << "Unexpected value " << token;
133 }
134 }
135 }
136
137 void ListenerImpl::OnFileCanWriteWithoutBlocking(int fd) {
138 NOTREACHED();
139 }
140
141 Listener::Listener(const std::string& name,
142 Domain domain,
143 Listener::Delegate* delegate)
144 : impl_(new ListenerImpl(name, domain, delegate)) {
145 }
146
147 Listener::~Listener() {
148 }
149
150 bool Listener::Start() {
151 return impl_->Start();
152 }
153
154 } // namespace multi_process_notification
OLDNEW
« no previous file with comments | « chrome/common/multi_process_notification_linux.cc ('k') | chrome/common/multi_process_notification_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698