1 // Copyright 2007, Google Inc.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <nspr.h> // for PR_*
30 #include <windows.h> // must manually #include before nsIEventQueueService.h
33 #include "gears/base/common/message_queue.h"
34 #include "gears/third_party/gecko_internal/nsIEventQueueService.h"
37 // Protects callbacks_ during inserts and finds.
38 static Mutex callback_mutex_
;
39 static std::map
<int, ThreadMessageQueue::HandlerCallback
> callbacks_
;
41 bool ThreadMessageQueue::InitThreadMessageQueue() {
45 bool ThreadMessageQueue::RegisterHandler(int message_id
,
46 HandlerCallback message_handler
) {
47 MutexLock
lock(&callback_mutex_
);
48 callbacks_
[message_id
] = message_handler
;
52 ThreadId
ThreadMessageQueue::GetCurrentThreadId() {
53 return PR_GetCurrentThread();
60 std::string message_data_1
;
61 std::string message_data_2
;
64 void *OnReceiveMessageEvent(MessageEvent
*event
) {
65 // Sanity check the thread.
66 assert(event
->thread
== ThreadMessageQueue::GetCurrentThreadId());
68 // Check that a callback has been registered for this event type.
69 std::map
<int, ThreadMessageQueue::HandlerCallback
>::iterator handler
;
71 // We only need to lock during the find.
72 MutexLock
lock(&callback_mutex_
);
73 handler
= callbacks_
.find(event
->message_id
);
75 if (handler
!= callbacks_
.end()) {
76 handler
->second(event
->message_id
, event
->message_data_1
.c_str(),
77 event
->message_data_2
.c_str());
83 static void OnDestroyMessageEvent(MessageEvent
*event
) {
87 void ThreadMessageQueue::Send(ThreadId thread
,
89 const char *message_data_1
,
90 const char *message_data_2
) {
93 nsCOMPtr
<nsIEventQueueService
> event_queue_service
=
94 do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID
, &nr
);
99 // If there's no event queue on this thread, we can't do anything.
100 nsCOMPtr
<nsIEventQueue
> event_queue
;
101 nr
= event_queue_service
->GetThreadEventQueue(thread
,
102 getter_AddRefs(event_queue
));
107 MessageEvent
*event
= new MessageEvent
;
108 event
->thread
= thread
;
109 event
->message_id
= message_id
;
110 event
->message_data_1
= message_data_1
;
111 event
->message_data_2
= message_data_2
;
113 if (NS_FAILED(event_queue
->InitEvent(
115 reinterpret_cast<PLHandleEventProc
>(OnReceiveMessageEvent
),
116 reinterpret_cast<PLDestroyEventProc
>(OnDestroyMessageEvent
)))) {
120 if (NS_FAILED(event_queue
->PostEvent(&event
->e
))) {
121 // Cleaning up the event at this point would requires access to private
122 // functions, so just clear the strings so that we leak less.
123 event
->message_data_1
.clear();
124 event
->message_data_2
.clear();