Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / native_client_sdk / src / examples / tutorial / dlopen / dlopen.cc
blob81aa015342d6fcba33aae56891d6c851d97b1326
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.
5 #include <dlfcn.h>
6 #include <pthread.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
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"
19 #include "reverse.h"
21 #if defined(NACL_SDK_DEBUG)
22 #define CONFIG_NAME "Debug"
23 #else
24 #define CONFIG_NAME "Release"
25 #endif
27 #if defined __arm__
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"
33 #else
34 #error "Unknown arch"
35 #endif
37 class DlOpenInstance : public pp::Instance {
38 public:
39 explicit DlOpenInstance(PP_Instance instance)
40 : pp::Instance(instance),
41 eightball_so_(NULL),
42 reverse_so_(NULL),
43 eightball_(NULL),
44 reverse_(NULL),
45 tid_(NULL) {}
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
61 // server.
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.");
67 return false;
69 return true;
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.
75 void LoadLibrary() {
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: ";
82 message += dlerror();
83 logmsg(message.c_str());
84 return;
87 logmsg("Loaded libeightball.so");
88 } else {
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());
102 return;
104 logmsg("Loaded libreverse.so");
105 } else {
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.");
114 return;
117 std::string message = var_message.AsString();
118 if (message == "eightball") {
119 if (NULL == eightball_) {
120 logmsg("Eightball library not loaded");
121 return;
124 std::string ballmessage = "The Magic 8-Ball says: ";
125 ballmessage += eightball_();
126 ballmessage += "!";
128 logmsg(ballmessage.c_str());
129 } else if (message.find("reverse:") == 0) {
130 if (NULL == reverse_) {
131 logmsg("Reverse library not loaded");
132 return;
135 std::string s = message.substr(strlen("reverse:"));
136 char* result = reverse_(s.c_str());
138 std::string message = "Your string reversed: \"";
139 message += result;
140 message += "\"";
142 free(result);
144 logmsg(message.c_str());
145 } else {
146 std::string errormsg = "Unexpected message: ";
147 errormsg += message;
148 logmsg(errormsg.c_str());
152 static void* LoadLibrariesOnWorker(void* pInst) {
153 DlOpenInstance* inst = static_cast<DlOpenInstance*>(pInst);
154 inst->LoadLibrary();
155 return NULL;
158 private:
159 void* eightball_so_;
160 void* reverse_so_;
161 TYPE_eightball eightball_;
162 TYPE_reverse reverse_;
163 pthread_t tid_;
166 class DlOpenModule : public pp::Module {
167 public:
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);
177 namespace pp {
178 Module* CreateModule() { return new DlOpenModule(); }
179 } // namespace pp