diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-10 20:52:11 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-10 20:52:11 +0000 |
commit | 6cf6ca58e053f69d88c90b55f3a9011a6caba801 (patch) | |
tree | a10d40846807d905cd014a933135f7856d430067 | |
parent | 6a91ffb0e9bafcde73e134aef4b635e2efeb71db (diff) | |
download | chromium_src-6cf6ca58e053f69d88c90b55f3a9011a6caba801.zip chromium_src-6cf6ca58e053f69d88c90b55f3a9011a6caba801.tar.gz chromium_src-6cf6ca58e053f69d88c90b55f3a9011a6caba801.tar.bz2 |
Simple shell that loads a dll and calls an entrypoint function passing in a handle to a pipe created by the shell app.
To achieve this I had to make mojo_system a <(component) so sample_app.dll could link against it. Trung, Darin tells me you had a different idea about how to achieve this. Consider this CL a starting point for the discussion :-)
R=darin@chromium.org
BUG=
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=227604
Review URL: https://codereview.chromium.org/25895002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227983 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | build/all.gyp | 2 | ||||
-rw-r--r-- | mojo/mojo.gyp | 31 | ||||
-rw-r--r-- | mojo/public/system/core.h | 44 | ||||
-rw-r--r-- | mojo/public/system/system_export.h | 29 | ||||
-rw-r--r-- | mojo/shell/app_container.cc | 92 | ||||
-rw-r--r-- | mojo/shell/app_container.h | 43 | ||||
-rw-r--r-- | mojo/shell/sample_app.cc | 73 | ||||
-rw-r--r-- | mojo/shell/shell.cc | 33 | ||||
-rw-r--r-- | mojo/shell/switches.cc | 11 | ||||
-rw-r--r-- | mojo/shell/switches.h | 14 | ||||
-rw-r--r-- | mojo/system/core_impl.h | 2 | ||||
-rw-r--r-- | mojo/system/dispatcher.h | 4 | ||||
-rw-r--r-- | mojo/system/memory.cc | 6 | ||||
-rw-r--r-- | mojo/system/memory.h | 5 | ||||
-rw-r--r-- | mojo/system/message_pipe.h | 4 | ||||
-rw-r--r-- | mojo/system/message_pipe_dispatcher.h | 3 | ||||
-rw-r--r-- | mojo/system/simple_dispatcher.h | 3 | ||||
-rw-r--r-- | mojo/system/waiter.h | 3 | ||||
-rw-r--r-- | mojo/system/waiter_list.h | 3 |
19 files changed, 374 insertions, 31 deletions
diff --git a/build/all.gyp b/build/all.gyp index ea10e64..d6aa909 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -14,7 +14,6 @@ '../chrome/chrome.gyp:*', '../content/content.gyp:*', '../crypto/crypto.gyp:*', - '../mojo/mojo.gyp:*', '../net/net.gyp:*', '../sdch/sdch.gyp:*', '../sql/sql.gyp:*', @@ -43,6 +42,7 @@ '../jingle/jingle.gyp:*', '../media/cast/cast.gyp:*', '../media/media.gyp:*', + '../mojo/mojo.gyp:*', '../ppapi/ppapi.gyp:*', '../ppapi/ppapi_internal.gyp:*', '../printing/printing.gyp:*', diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index d8f3121..5a86936 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -64,10 +64,13 @@ { 'target_name': 'mojo_system', # TODO(vtl): This should probably be '<(component)'; make it work. - 'type': 'static_library', + 'type': '<(component)', 'dependencies': [ '../base/base.gyp:base', ], + 'defines': [ + 'MOJO_SYSTEM_IMPLEMENTATION', + ], 'sources': [ 'public/system/core.h', 'system/core.cc', @@ -120,5 +123,31 @@ 'system/waiter_unittest.cc', ], }, + { + 'target_name': 'mojo_shell', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:base', + 'mojo_system', + ], + 'sources': [ + 'shell/app_container.cc', + 'shell/app_container.h', + 'shell/shell.cc', + 'shell/switches.cc', + 'shell/switches.h', + ], + }, + { + 'target_name': 'sample_app', + 'type': '<(component)', + 'dependencies': [ + '../base/base.gyp:base', + 'mojo_system', + ], + 'sources': [ + 'shell/sample_app.cc', + ], + }, ], } diff --git a/mojo/public/system/core.h b/mojo/public/system/core.h index cb405ae..9a53a78 100644 --- a/mojo/public/system/core.h +++ b/mojo/public/system/core.h @@ -9,6 +9,8 @@ #include <stdint.h> +#include "mojo/public/system/system_export.h" + // Types ----------------------------------------------------------------------- // TODO(vtl): Notes: Use of undefined flags will lead to undefined behavior @@ -190,7 +192,7 @@ extern "C" { // happen before the close, be cancelled with result |MOJO_RESULT_CANCELLED| if // they properly overlap (this is likely the case with |MojoWait()|, etc.), or // fail with |MOJO_RESULT_INVALID_ARGUMENT| if they happen after. -MojoResult MojoClose(MojoHandle handle); +MOJO_SYSTEM_EXPORT MojoResult MojoClose(MojoHandle handle); // Waits on the given handle until the state indicated by |flags| is satisfied // or until |deadline| has passed. @@ -208,9 +210,9 @@ MojoResult MojoClose(MojoHandle handle); // If there are multiple waiters (on different threads, obviously) waiting on // the same handle and flag and that flag becomes set, all waiters will be // awoken. -MojoResult MojoWait(MojoHandle handle, - MojoWaitFlags flags, - MojoDeadline deadline); +MOJO_SYSTEM_EXPORT MojoResult MojoWait(MojoHandle handle, + MojoWaitFlags flags, + MojoDeadline deadline); // Waits on |handles[0]|, ..., |handles[num_handles-1]| for at least one of them // to satisfy the state indicated by |flags[0]|, ..., |flags[num_handles-1]|, @@ -225,23 +227,27 @@ MojoResult MojoWait(MojoHandle handle, // handles satisfying any of its flags. // |MOJO_RESULT_FAILED_PRECONDITION| if it is or becomes impossible that SOME // |handle[i]| will ever satisfy any of its flags |flags[i]|. -MojoResult MojoWaitMany(const MojoHandle* handles, - const MojoWaitFlags* flags, - uint32_t num_handles, - MojoDeadline deadline); +MOJO_SYSTEM_EXPORT MojoResult MojoWaitMany(const MojoHandle* handles, + const MojoWaitFlags* flags, + uint32_t num_handles, + MojoDeadline deadline); // TODO(vtl): flags? other params (e.g., queue sizes, max message sizes?) -MojoResult MojoCreateMessagePipe(MojoHandle* handle_0, MojoHandle* handle_1); - -MojoResult MojoWriteMessage(MojoHandle handle, - const void* bytes, uint32_t num_bytes, - const MojoHandle* handles, uint32_t num_handles, - MojoWriteMessageFlags flags); - -MojoResult MojoReadMessage(MojoHandle handle, - void* bytes, uint32_t* num_bytes, - MojoHandle* handles, uint32_t* num_handles, - MojoReadMessageFlags flags); +MOJO_SYSTEM_EXPORT MojoResult MojoCreateMessagePipe(MojoHandle* handle_0, + MojoHandle* handle_1); + +MOJO_SYSTEM_EXPORT MojoResult MojoWriteMessage( + MojoHandle handle, + const void* bytes, uint32_t num_bytes, + const MojoHandle* handles, + uint32_t num_handles, + MojoWriteMessageFlags flags); + +MOJO_SYSTEM_EXPORT MojoResult MojoReadMessage(MojoHandle handle, + void* bytes, uint32_t* num_bytes, + MojoHandle* handles, + uint32_t* num_handles, + MojoReadMessageFlags flags); #ifdef __cplusplus } // extern "C" diff --git a/mojo/public/system/system_export.h b/mojo/public/system/system_export.h new file mode 100644 index 0000000..8a1b1e7 --- /dev/null +++ b/mojo/public/system/system_export.h @@ -0,0 +1,29 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_SYSTEM_SYSTEM_EXPORT_H_ +#define MOJO_PUBLIC_SYSTEM_SYSTEM_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(MOJO_SYSTEM_IMPLEMENTATION) +#define MOJO_SYSTEM_EXPORT __declspec(dllexport) +#else +#define MOJO_SYSTEM_EXPORT __declspec(dllimport) +#endif // defined(GFX_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(MOJO_SYSTEM_IMPLEMENTATION) +#define MOJO_SYSTEM_EXPORT __attribute__((visibility("default"))) +#else +#define MOJO_SYSTEM_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define MOJO_SYSTEM_EXPORT +#endif + +#endif // MOJO_PUBLIC_SYSTEM_SYSTEM_EXPORT_H_ diff --git a/mojo/shell/app_container.cc b/mojo/shell/app_container.cc new file mode 100644 index 0000000..b679973 --- /dev/null +++ b/mojo/shell/app_container.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/callback_forward.h" +#include "base/files/file_path.h" +#include "base/native_library.h" +#include "base/thread_task_runner_handle.h" +#include "base/threading/thread.h" +#include "mojo/public/system/core.h" +#include "mojo/shell/app_container.h" + +typedef MojoResult (*MojoMainFunction)(mojo::Handle pipe); + +namespace mojo { +namespace shell { + +void LaunchAppOnThread( + const base::FilePath& app_path, + Handle app_handle) { + MojoResult result = MOJO_RESULT_OK; + MojoMainFunction main_function = NULL; + + base::NativeLibrary app_library = base::LoadNativeLibrary(app_path, NULL); + if (!app_library) { + LOG(ERROR) << "Failed to load library: " << app_path.value().c_str(); + goto completed; + } + + main_function = reinterpret_cast<MojoMainFunction>( + base::GetFunctionPointerFromNativeLibrary(app_library, "MojoMain")); + if (!main_function) { + LOG(ERROR) << "Entrypoint MojoMain not found."; + goto completed; + } + + result = main_function(app_handle); + if (result < MOJO_RESULT_OK) { + LOG(ERROR) << "MojoMain returned an error: " << result; + // TODO(*): error handling? + goto completed; + } + +completed: + base::UnloadNativeLibrary(app_library); + Close(app_handle); +} + +AppContainer::AppContainer() + : weak_factory_(this) { +} + +AppContainer::~AppContainer() { +} + +void AppContainer::LaunchApp(const base::FilePath& app_path) { + Handle app_handle; + MojoResult result = CreateMessagePipe(&shell_handle_, &app_handle); + if (result < MOJO_RESULT_OK) { + // Failure.. + } + + // Launch the app on its own thread. + // TODO(beng): Create a unique thread name. + thread_.reset(new base::Thread("app_thread")); + thread_->Start(); + thread_->message_loop_proxy()->PostTaskAndReply( + FROM_HERE, + base::Bind(&LaunchAppOnThread, app_path, app_handle), + base::Bind(&AppContainer::AppCompleted, weak_factory_.GetWeakPtr())); + + const char* hello_msg = "Hello"; + result = WriteMessage(shell_handle_, hello_msg, strlen(hello_msg)+1, + NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); + if (result < MOJO_RESULT_OK) { + // Failure.. + } +} + + +void AppContainer::AppCompleted() { + thread_.reset(); + Close(shell_handle_); + + // Probably want to do something more sophisticated here, like notify someone + // else to do this. + base::MessageLoop::current()->Quit(); +} + +} // namespace shell +} // namespace mojo diff --git a/mojo/shell/app_container.h b/mojo/shell/app_container.h new file mode 100644 index 0000000..b02a361 --- /dev/null +++ b/mojo/shell/app_container.h @@ -0,0 +1,43 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SHELL_APP_CONTAINER_H_ +#define MOJO_SHELL_APP_CONTAINER_H_ + +#include "base/basictypes.h" +#include "base/memory/weak_ptr.h" +#include "mojo/public/system/core.h" + +namespace base { +class Thread; +} + +namespace mojo { +namespace shell { + +// A container class that runs an app on its own thread. +class AppContainer { + public: + AppContainer(); + ~AppContainer(); + + void LaunchApp(const base::FilePath& app_path); + + private: + void AppCompleted(); + + base::WeakPtrFactory<AppContainer> weak_factory_; + + scoped_ptr<base::Thread> thread_; + + // Following members are valid only on app thread. + Handle shell_handle_; + + DISALLOW_COPY_AND_ASSIGN(AppContainer); +}; + +} // namespace shell +} // namespace mojo + +#endif // MOJO_SHELL_APP_CONTAINER_H_
\ No newline at end of file diff --git a/mojo/shell/sample_app.cc b/mojo/shell/sample_app.cc new file mode 100644 index 0000000..a3acbe3 --- /dev/null +++ b/mojo/shell/sample_app.cc @@ -0,0 +1,73 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdio.h> + +#include "base/basictypes.h" +#include "mojo/public/system/core.h" +#include "mojo/system/core_impl.h" + +#if defined(OS_WIN) +#if !defined(CDECL) +#define CDECL __cdecl +#endif +#define SAMPLE_APP_EXPORT __declspec(dllexport) +#else +#define CDECL +#define SAMPLE_APP_EXPORT __attribute__((visibility("default"))) +#endif + +char* ReadStringFromPipe(mojo::Handle pipe) { + uint32_t len = 0; + char* buf = NULL; + MojoResult result = mojo::ReadMessage(pipe, buf, &len, NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE); + if (result == MOJO_RESULT_RESOURCE_EXHAUSTED) { + buf = new char[len]; + result = mojo::ReadMessage(pipe, buf, &len, NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE); + } + if (result < MOJO_RESULT_OK) { + // Failure.. + if (buf) + delete[] buf; + return NULL; + } + return buf; +} + +class SampleMessageWaiter { + public: + explicit SampleMessageWaiter(mojo::Handle pipe) : pipe_(pipe) {} + ~SampleMessageWaiter() {} + + void Read() { + char* string = ReadStringFromPipe(pipe_); + if (string) { + printf("Read string from pipe: %s\n", string); + delete[] string; + string = NULL; + } + } + + void WaitAndRead() { + MojoResult result = mojo::Wait(pipe_, MOJO_WAIT_FLAG_READABLE, 100); + if (result < MOJO_RESULT_OK) { + // Failure... + } + + Read(); + } + + private: + + mojo::Handle pipe_; + DISALLOW_COPY_AND_ASSIGN(SampleMessageWaiter); +}; + +extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain( + mojo::Handle pipe) { + SampleMessageWaiter(pipe).WaitAndRead(); + return MOJO_RESULT_OK; +} diff --git a/mojo/shell/shell.cc b/mojo/shell/shell.cc new file mode 100644 index 0000000..72f697f --- /dev/null +++ b/mojo/shell/shell.cc @@ -0,0 +1,33 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "mojo/shell/app_container.h" +#include "mojo/shell/switches.h" +#include "mojo/system/core_impl.h" + +int main(int argc, char** argv) { + base::AtExitManager at_exit; + CommandLine::Init(argc, argv); + + mojo::system::CoreImpl::Init(); + + base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (!command_line.HasSwitch(switches::kApp)) { + LOG(ERROR) << "No app path specified."; + return 0; + } + + scoped_ptr<mojo::shell::AppContainer> container( + new mojo::shell::AppContainer); + container->LaunchApp(command_line.GetSwitchValuePath(switches::kApp)); + message_loop.Run(); + return 0; +} diff --git a/mojo/shell/switches.cc b/mojo/shell/switches.cc new file mode 100644 index 0000000..0d3883d --- /dev/null +++ b/mojo/shell/switches.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/shell/switches.h" + +namespace switches { + +const char kApp[] = "app"; + +} // namespace switches diff --git a/mojo/shell/switches.h b/mojo/shell/switches.h new file mode 100644 index 0000000..3ccac80 --- /dev/null +++ b/mojo/shell/switches.h @@ -0,0 +1,14 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_SHELL_SWITCHES_H_ +#define MOJO_SHELL_SWITCHES_H_ + +namespace switches { + +extern const char kApp[]; + +} // namespace switches + +#endif // MOJO_SHELL_SWITCHES_H_
\ No newline at end of file diff --git a/mojo/system/core_impl.h b/mojo/system/core_impl.h index 1417a06..aede29d 100644 --- a/mojo/system/core_impl.h +++ b/mojo/system/core_impl.h @@ -25,7 +25,7 @@ class CoreTestBase; // the (obvious) exception of |Init()|, which must be called first (and the call // completed) before making any other calls, all the public methods are // thread-safe. -class CoreImpl { +class MOJO_SYSTEM_EXPORT CoreImpl { public: static void Init(); diff --git a/mojo/system/dispatcher.h b/mojo/system/dispatcher.h index 6b44f6a..75f6a97 100644 --- a/mojo/system/dispatcher.h +++ b/mojo/system/dispatcher.h @@ -9,6 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "mojo/public/system/core.h" +#include "mojo/public/system/system_export.h" namespace mojo { namespace system { @@ -20,7 +21,8 @@ class Waiter; // object is thread-safe, with its state being protected by a single lock // |lock_|, which is also made available to implementation subclasses (via the // |lock()| method). -class Dispatcher : public base::RefCountedThreadSafe<Dispatcher> { +class MOJO_SYSTEM_EXPORT Dispatcher : + public base::RefCountedThreadSafe<Dispatcher> { public: // These methods implement the various primitives named |Mojo...()|. These // take |lock_| and handle races with |Close()|. Then they call out to diff --git a/mojo/system/memory.cc b/mojo/system/memory.cc index fe7edef..f20b61d 100644 --- a/mojo/system/memory.cc +++ b/mojo/system/memory.cc @@ -23,8 +23,10 @@ bool VerifyUserPointerForSize(const void* pointer, size_t count) { } // Explicitly instantiate the sizes we need. Add instantiations as needed. -template bool VerifyUserPointerForSize<1>(const void*, size_t); -template bool VerifyUserPointerForSize<4>(const void*, size_t); +template MOJO_SYSTEM_EXPORT bool VerifyUserPointerForSize<1>( + const void*, size_t); +template MOJO_SYSTEM_EXPORT bool VerifyUserPointerForSize<4>( + const void*, size_t); } // namespace system } // namespace mojo diff --git a/mojo/system/memory.h b/mojo/system/memory.h index cca3aca..963974a 100644 --- a/mojo/system/memory.h +++ b/mojo/system/memory.h @@ -7,6 +7,8 @@ #include <stddef.h> +#include "mojo/public/system/system_export.h" + namespace mojo { namespace system { @@ -14,7 +16,8 @@ namespace system { // instantiations in the .cc file. This is used by |VerifyUserPointer<T>()| // below, and you should use that instead. template <size_t size> -bool VerifyUserPointerForSize(const void* pointer, size_t count); +bool MOJO_SYSTEM_EXPORT VerifyUserPointerForSize(const void* pointer, + size_t count); // Verify that |count * sizeof(T)| bytes can be read from the user |pointer| // insofar as possible/necessary (note: this is done carefully since |count * diff --git a/mojo/system/message_pipe.h b/mojo/system/message_pipe.h index d8266f7..2be2acd 100644 --- a/mojo/system/message_pipe.h +++ b/mojo/system/message_pipe.h @@ -12,6 +12,7 @@ #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "mojo/public/system/core.h" +#include "mojo/public/system/system_export.h" #include "mojo/system/waiter_list.h" namespace mojo { @@ -23,7 +24,8 @@ class Waiter; // |MessagePipe| is the secondary object implementing a message pipe (see the // explanatory comment in core_impl.cc), and is jointly owned by the two // dispatchers passed in to the constructor. This class is thread-safe. -class MessagePipe : public base::RefCountedThreadSafe<MessagePipe> { +class MOJO_SYSTEM_EXPORT MessagePipe : + public base::RefCountedThreadSafe<MessagePipe> { public: MessagePipe(); diff --git a/mojo/system/message_pipe_dispatcher.h b/mojo/system/message_pipe_dispatcher.h index b52ebb8..a0e2f09 100644 --- a/mojo/system/message_pipe_dispatcher.h +++ b/mojo/system/message_pipe_dispatcher.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "mojo/public/system/system_export.h" #include "mojo/system/dispatcher.h" namespace mojo { @@ -17,7 +18,7 @@ class MessagePipe; // This is the |Dispatcher| implementation for message pipes (created by the // Mojo primitive |MojoCreateMessagePipe()|). This class is thread-safe. -class MessagePipeDispatcher : public Dispatcher { +class MOJO_SYSTEM_EXPORT MessagePipeDispatcher : public Dispatcher { public: MessagePipeDispatcher(); diff --git a/mojo/system/simple_dispatcher.h b/mojo/system/simple_dispatcher.h index f306aba..4ef37d1 100644 --- a/mojo/system/simple_dispatcher.h +++ b/mojo/system/simple_dispatcher.h @@ -8,6 +8,7 @@ #include <list> #include "base/basictypes.h" +#include "mojo/public/system/system_export.h" #include "mojo/system/dispatcher.h" #include "mojo/system/waiter_list.h" @@ -18,7 +19,7 @@ namespace system { // correspondence between handles and dispatchers (see the explanatory comment // in core_impl.cc). This class implements the standard waiter-signalling // mechanism in that case. -class SimpleDispatcher : public Dispatcher { +class MOJO_SYSTEM_EXPORT SimpleDispatcher : public Dispatcher { protected: SimpleDispatcher(); diff --git a/mojo/system/waiter.h b/mojo/system/waiter.h index bdd33fc..a2e8076 100644 --- a/mojo/system/waiter.h +++ b/mojo/system/waiter.h @@ -9,6 +9,7 @@ #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "mojo/public/system/core.h" +#include "mojo/public/system/system_export.h" namespace mojo { namespace system { @@ -17,7 +18,7 @@ namespace system { // under other locks, in particular, |Dispatcher::lock_|s, so |Waiter| methods // must never call out to other objects (in particular, |Dispatcher|s). This // class is thread-safe. -class Waiter { +class MOJO_SYSTEM_EXPORT Waiter { public: Waiter(); ~Waiter(); diff --git a/mojo/system/waiter_list.h b/mojo/system/waiter_list.h index 23933e3..e23c138 100644 --- a/mojo/system/waiter_list.h +++ b/mojo/system/waiter_list.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "mojo/public/system/core.h" +#include "mojo/public/system/system_export.h" namespace mojo { namespace system { @@ -22,7 +23,7 @@ class Waiter; // object (see simple_dispatcher.* and the explanatory comment in core_impl.cc). // This class is thread-unsafe (all concurrent access must be protected by some // lock). -class WaiterList { +class MOJO_SYSTEM_EXPORT WaiterList { public: WaiterList(); ~WaiterList(); |