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
),
46 virtual ~DlOpenInstance() {}
48 // Helper function to post a message back to the JS and stdout functions.
49 void logmsg(const char* pStr
) {
50 PostMessage(pp::Var(std::string("log:") + pStr
));
51 fprintf(stdout
, pStr
);
52 fprintf(stdout
, "\n");
55 // Initialize the module, staring a worker thread to load the shared object.
56 virtual bool Init(uint32_t argc
, const char* argn
[], const char* argv
[]) {
57 nacl_io_init_ppapi(pp_instance(),
58 pp::Module::Get()->get_browser_interface());
59 // Mount a HTTP mount at /http. All reads from /http/* will read from the
61 mount("", "/http", "httpfs", 0, "");
64 logmsg("Spawning thread to cache .so files...");
65 int rtn
= pthread_create(&thread
, NULL
, LoadLibrariesOnWorker
, this);
67 logmsg("ERROR; pthread_create() failed.");
70 rtn
= pthread_detach(thread
);
72 logmsg("ERROR; pthread_detach() failed.");
78 // This function is called on a worker thread, and will call dlopen to load
79 // the shared object. In addition, note that this function does NOT call
80 // dlclose, which would close the shared object and unload it from memory.
82 eightball_so_
= dlopen("libeightball.so", RTLD_LAZY
);
83 if (eightball_so_
!= NULL
) {
84 intptr_t offset
= (intptr_t) dlsym(eightball_so_
, "Magic8Ball");
85 eightball_
= (TYPE_eightball
) offset
;
86 if (NULL
== eightball_
) {
87 std::string message
= "dlsym() returned NULL: ";
89 logmsg(message
.c_str());
93 logmsg("Loaded libeightball.so");
95 logmsg("libeightball.so did not load");
98 const char reverse_so_path
[] =
99 "/http/glibc/" CONFIG_NAME
"/libreverse_" NACL_ARCH
".so";
100 reverse_so_
= dlopen(reverse_so_path
, RTLD_LAZY
);
101 if (reverse_so_
!= NULL
) {
102 intptr_t offset
= (intptr_t) dlsym(reverse_so_
, "Reverse");
103 reverse_
= (TYPE_reverse
) offset
;
104 if (NULL
== reverse_
) {
105 std::string message
= "dlsym() returned NULL: ";
106 message
+= dlerror();
107 logmsg(message
.c_str());
110 logmsg("Loaded libreverse.so");
112 logmsg("libreverse.so did not load");
116 // Called by the browser to handle the postMessage() call in Javascript.
117 virtual void HandleMessage(const pp::Var
& var_message
) {
118 if (!var_message
.is_string()) {
119 logmsg("Message is not a string.");
123 std::string message
= var_message
.AsString();
124 if (message
== "eightball") {
125 if (NULL
== eightball_
) {
126 logmsg("Eightball library not loaded");
130 std::string ballmessage
= "The Magic 8-Ball says: ";
131 ballmessage
+= eightball_();
134 logmsg(ballmessage
.c_str());
135 } else if (message
.find("reverse:") == 0) {
136 if (NULL
== reverse_
) {
137 logmsg("Reverse library not loaded");
141 std::string s
= message
.substr(strlen("reverse:"));
142 char* result
= reverse_(s
.c_str());
144 std::string message
= "Your string reversed: \"";
150 logmsg(message
.c_str());
152 std::string errormsg
= "Unexpected message: ";
154 logmsg(errormsg
.c_str());
158 static void* LoadLibrariesOnWorker(void* pInst
) {
159 DlOpenInstance
* inst
= static_cast<DlOpenInstance
*>(pInst
);
167 TYPE_eightball eightball_
;
168 TYPE_reverse reverse_
;
171 class DlOpenModule
: public pp::Module
{
173 DlOpenModule() : pp::Module() {}
174 virtual ~DlOpenModule() {}
176 // Create and return a DlOpenInstance object.
177 virtual pp::Instance
* CreateInstance(PP_Instance instance
) {
178 return new DlOpenInstance(instance
);
183 Module
* CreateModule() { return new DlOpenModule(); }