1 // Copyright (c) 2012 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.
10 #include <sys/mount.h>
12 #include <ppapi/cpp/completion_callback.h>
13 #include <ppapi/cpp/instance.h>
14 #include <ppapi/cpp/module.h>
15 #include <ppapi/cpp/var.h>
17 #include "eightball.h"
18 #include "nacl_io/nacl_io.h"
21 #if defined(NACL_SDK_DEBUG)
22 #define CONFIG_NAME "Debug"
24 #define CONFIG_NAME "Release"
28 #define NACL_ARCH "arm"
29 #elif defined __i686__
30 #define NACL_ARCH "x86_32"
31 #elif defined __x86_64__
32 #define NACL_ARCH "x86_64"
37 class DlOpenInstance
: public pp::Instance
{
39 explicit DlOpenInstance(PP_Instance instance
)
40 : pp::Instance(instance
),
47 virtual ~DlOpenInstance() {}
49 // Helper function to post a message back to the JS and stdout functions.
50 void logmsg(const char* pStr
) {
51 PostMessage(pp::Var(std::string("log:") + pStr
));
52 fprintf(stdout
, pStr
);
53 fprintf(stdout
, "\n");
56 // Initialize the module, staring a worker thread to load the shared object.
57 virtual bool Init(uint32_t argc
, const char* argn
[], const char* argv
[]) {
58 nacl_io_init_ppapi(pp_instance(),
59 pp::Module::Get()->get_browser_interface());
60 // Mount a HTTP mount at /http. All reads from /http/* will read from the
62 mount("", "/http", "httpfs", 0, "");
64 logmsg("Spawning thread to cache .so files...");
65 if (pthread_create(&tid_
, NULL
, LoadLibrariesOnWorker
, this)) {
66 logmsg("ERROR; pthread_create() failed.");
72 // This function is called on a worker thread, and will call dlopen to load
73 // the shared object. In addition, note that this function does NOT call
74 // dlclose, which would close the shared object and unload it from memory.
76 eightball_so_
= dlopen("libeightball.so", RTLD_LAZY
);
77 if (eightball_so_
!= NULL
) {
78 intptr_t offset
= (intptr_t) dlsym(eightball_so_
, "Magic8Ball");
79 eightball_
= (TYPE_eightball
) offset
;
80 if (NULL
== eightball_
) {
81 std::string message
= "dlsym() returned NULL: ";
83 logmsg(message
.c_str());
87 logmsg("Loaded libeightball.so");
89 logmsg("libeightball.so did not load");
92 const char reverse_so_path
[] =
93 "/http/glibc/" CONFIG_NAME
"/libreverse_" NACL_ARCH
".so";
94 reverse_so_
= dlopen(reverse_so_path
, RTLD_LAZY
);
95 if (reverse_so_
!= NULL
) {
96 intptr_t offset
= (intptr_t) dlsym(reverse_so_
, "Reverse");
97 reverse_
= (TYPE_reverse
) offset
;
98 if (NULL
== reverse_
) {
99 std::string message
= "dlsym() returned NULL: ";
100 message
+= dlerror();
101 logmsg(message
.c_str());
104 logmsg("Loaded libreverse.so");
106 logmsg("libreverse.so did not load");
110 // Called by the browser to handle the postMessage() call in Javascript.
111 virtual void HandleMessage(const pp::Var
& var_message
) {
112 if (!var_message
.is_string()) {
113 logmsg("Message is not a string.");
117 std::string message
= var_message
.AsString();
118 if (message
== "eightball") {
119 if (NULL
== eightball_
) {
120 logmsg("Eightball library not loaded");
124 std::string ballmessage
= "The Magic 8-Ball says: ";
125 ballmessage
+= eightball_();
128 logmsg(ballmessage
.c_str());
129 } else if (message
.find("reverse:") == 0) {
130 if (NULL
== reverse_
) {
131 logmsg("Reverse library not loaded");
135 std::string s
= message
.substr(strlen("reverse:"));
136 char* result
= reverse_(s
.c_str());
138 std::string message
= "Your string reversed: \"";
144 logmsg(message
.c_str());
146 std::string errormsg
= "Unexpected message: ";
148 logmsg(errormsg
.c_str());
152 static void* LoadLibrariesOnWorker(void* pInst
) {
153 DlOpenInstance
* inst
= static_cast<DlOpenInstance
*>(pInst
);
161 TYPE_eightball eightball_
;
162 TYPE_reverse reverse_
;
166 class DlOpenModule
: public pp::Module
{
168 DlOpenModule() : pp::Module() {}
169 virtual ~DlOpenModule() {}
171 // Create and return a DlOpenInstance object.
172 virtual pp::Instance
* CreateInstance(PP_Instance instance
) {
173 return new DlOpenInstance(instance
);
178 Module
* CreateModule() { return new DlOpenModule(); }