| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /// @file | 5 /// @file |
| 6 /// This example demonstrates building a dynamic library which is loaded by the | 6 /// This example demonstrates building a dynamic library which is loaded by the |
| 7 /// NaCl module. To load the NaCl module, the browser first looks for the | 7 /// NaCl module. To load the NaCl module, the browser first looks for the |
| 8 /// CreateModule() factory method (at the end of this file). It calls | 8 /// CreateModule() factory method (at the end of this file). It calls |
| 9 /// CreateModule() once to load the module code from your .nexe. After the | 9 /// CreateModule() once to load the module code from your .nexe. After the |
| 10 /// .nexe code is loaded, CreateModule() is not called again. | 10 /// .nexe code is loaded, CreateModule() is not called again. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 #include <ppapi/cpp/completion_callback.h> | 24 #include <ppapi/cpp/completion_callback.h> |
| 25 #include <ppapi/cpp/instance.h> | 25 #include <ppapi/cpp/instance.h> |
| 26 #include <ppapi/cpp/module.h> | 26 #include <ppapi/cpp/module.h> |
| 27 #include <ppapi/cpp/var.h> | 27 #include <ppapi/cpp/var.h> |
| 28 | 28 |
| 29 #include "eightball.h" | 29 #include "eightball.h" |
| 30 #include "nacl_io/nacl_io.h" | 30 #include "nacl_io/nacl_io.h" |
| 31 #include "reverse.h" | 31 #include "reverse.h" |
| 32 | 32 |
| 33 #if defined(NACL_SDK_DEBUG) |
| 34 #define CONFIG_NAME "Debug" |
| 35 #else |
| 36 #define CONFIG_NAME "Release" |
| 37 #endif |
| 38 |
| 39 #define XSTRINGIFY(x) STRINGIFY(x) |
| 40 #define STRINGIFY(x) #x |
| 41 #define NACL_ARCH_STRING XSTRINGIFY(NACL_ARCH) |
| 42 |
| 33 | 43 |
| 34 class DlopenInstance : public pp::Instance { | 44 class DlopenInstance : public pp::Instance { |
| 35 public: | 45 public: |
| 36 explicit DlopenInstance(PP_Instance instance) | 46 explicit DlopenInstance(PP_Instance instance) |
| 37 : pp::Instance(instance), | 47 : pp::Instance(instance), |
| 38 eightball_so_(NULL), | 48 eightball_so_(NULL), |
| 39 reverse_so_(NULL), | 49 reverse_so_(NULL), |
| 40 eightball_(NULL), | 50 eightball_(NULL), |
| 41 reverse_(NULL), | 51 reverse_(NULL), |
| 42 tid_(NULL) {} | 52 tid_(NULL) {} |
| 43 | 53 |
| 44 virtual ~DlopenInstance(){}; | 54 virtual ~DlopenInstance(){}; |
| 45 | 55 |
| 46 // Helper function to post a message back to the JS and stdout functions. | 56 // Helper function to post a message back to the JS and stdout functions. |
| 47 void logmsg(const char* pStr){ | 57 void logmsg(const char* pStr){ |
| 48 PostMessage(pp::Var(std::string("log:") + pStr)); | 58 PostMessage(pp::Var(std::string("log:") + pStr)); |
| 49 fprintf(stdout, pStr); | 59 fprintf(stdout, pStr); |
| 50 } | 60 } |
| 51 | 61 |
| 52 // Initialize the module, staring a worker thread to load the shared object. | 62 // Initialize the module, staring a worker thread to load the shared object. |
| 53 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]){ | 63 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]){ |
| 54 nacl_io_init_ppapi(pp_instance(), | 64 nacl_io_init_ppapi(pp_instance(), |
| 55 pp::Module::Get()->get_browser_interface()); | 65 pp::Module::Get()->get_browser_interface()); |
| 56 // Mount a HTTP mount at /http. All reads from /http/* will read from the | 66 // Mount a HTTP mount at /http. All reads from /http/* will read from the |
| 57 // server. | 67 // server. |
| 58 mount("", "/http", "httpfs", 0, ""); | 68 mount("", "/http", "httpfs", 0, ""); |
| 59 | 69 |
| 60 logmsg("Spawning thread to cache .so files..."); | 70 logmsg("Spawning thread to cache .so files...\n"); |
| 61 if (pthread_create(&tid_, NULL, LoadLibrariesOnWorker, this)) { | 71 if (pthread_create(&tid_, NULL, LoadLibrariesOnWorker, this)) { |
| 62 logmsg("ERROR; pthread_create() failed.\n"); | 72 logmsg("ERROR; pthread_create() failed.\n"); |
| 63 return false; | 73 return false; |
| 64 } | 74 } |
| 65 return true; | 75 return true; |
| 66 } | 76 } |
| 67 | 77 |
| 68 // This function is called on a worker thread, and will call dlopen to load | 78 // This function is called on a worker thread, and will call dlopen to load |
| 69 // the shared object. In addition, note that this function does NOT call | 79 // the shared object. In addition, note that this function does NOT call |
| 70 // dlclose, which would close the shared object and unload it from memory. | 80 // dlclose, which would close the shared object and unload it from memory. |
| 71 void LoadLibrary() { | 81 void LoadLibrary() { |
| 82 const char reverse_so_path[] = |
| 83 "/http/glibc/" CONFIG_NAME "/libreverse_" NACL_ARCH_STRING ".so"; |
| 72 const int32_t IMMEDIATELY = 0; | 84 const int32_t IMMEDIATELY = 0; |
| 73 eightball_so_ = dlopen("libeightball.so", RTLD_LAZY); | 85 eightball_so_ = dlopen("libeightball.so", RTLD_LAZY); |
| 74 reverse_so_ = dlopen("/http/glibc/Debug/libreverse_x86_64.so", RTLD_LAZY); | 86 reverse_so_ = dlopen(reverse_so_path, RTLD_LAZY); |
| 75 pp::CompletionCallback cc(LoadDoneCB, this); | 87 pp::CompletionCallback cc(LoadDoneCB, this); |
| 76 pp::Module::Get()->core()->CallOnMainThread(IMMEDIATELY, cc , 0); | 88 pp::Module::Get()->core()->CallOnMainThread(IMMEDIATELY, cc , 0); |
| 77 } | 89 } |
| 78 | 90 |
| 79 // This function will run on the main thread and use the handle it stored by | 91 // This function will run on the main thread and use the handle it stored by |
| 80 // the worker thread, assuming it successfully loaded, to get a pointer to the | 92 // the worker thread, assuming it successfully loaded, to get a pointer to the |
| 81 // message function in the shared object. | 93 // message function in the shared object. |
| 82 void UseLibrary() { | 94 void UseLibrary() { |
| 83 if (eightball_so_ != NULL) { | 95 if (eightball_so_ != NULL) { |
| 84 intptr_t offset = (intptr_t) dlsym(eightball_so_, "Magic8Ball"); | 96 intptr_t offset = (intptr_t) dlsym(eightball_so_, "Magic8Ball"); |
| 85 eightball_ = (TYPE_eightball) offset; | 97 eightball_ = (TYPE_eightball) offset; |
| 86 if (NULL == eightball_) { | 98 if (NULL == eightball_) { |
| 87 std::string message = "dlsym() returned NULL: "; | 99 std::string message = "dlsym() returned NULL: "; |
| 88 message += dlerror(); | 100 message += dlerror(); |
| 89 message += "\n"; | 101 message += "\n"; |
| 90 logmsg(message.c_str()); | 102 logmsg(message.c_str()); |
| 91 return; | 103 return; |
| 92 } | 104 } |
| 93 | 105 |
| 94 logmsg("Loaded libeightball.so"); | 106 logmsg("Loaded libeightball.so\n"); |
| 95 } else { | 107 } else { |
| 96 logmsg("libeightball.so did not load"); | 108 logmsg("libeightball.so did not load\n"); |
| 97 } | 109 } |
| 98 | 110 |
| 99 | 111 |
| 100 if (reverse_so_ != NULL) { | 112 if (reverse_so_ != NULL) { |
| 101 intptr_t offset = (intptr_t) dlsym(reverse_so_, "Reverse"); | 113 intptr_t offset = (intptr_t) dlsym(reverse_so_, "Reverse"); |
| 102 reverse_ = (TYPE_reverse) offset; | 114 reverse_ = (TYPE_reverse) offset; |
| 103 if (NULL == reverse_) { | 115 if (NULL == reverse_) { |
| 104 std::string message = "dlsym() returned NULL: "; | 116 std::string message = "dlsym() returned NULL: "; |
| 105 message += dlerror(); | 117 message += dlerror(); |
| 106 message += "\n"; | 118 message += "\n"; |
| 107 logmsg(message.c_str()); | 119 logmsg(message.c_str()); |
| 108 return; | 120 return; |
| 109 } | 121 } |
| 110 logmsg("Loaded libreverse.so"); | 122 logmsg("Loaded libreverse.so\n"); |
| 111 } else { | 123 } else { |
| 112 logmsg("libreverse.so did not load"); | 124 logmsg("libreverse.so did not load\n"); |
| 113 } | 125 } |
| 114 } | 126 } |
| 115 | 127 |
| 116 // Called by the browser to handle the postMessage() call in Javascript. | 128 // Called by the browser to handle the postMessage() call in Javascript. |
| 117 virtual void HandleMessage(const pp::Var& var_message) { | 129 virtual void HandleMessage(const pp::Var& var_message) { |
| 118 if (!var_message.is_string()) { | 130 if (!var_message.is_string()) { |
| 119 logmsg("Message is not a string."); | 131 logmsg("Message is not a string.\n"); |
| 120 return; | 132 return; |
| 121 } | 133 } |
| 122 | 134 |
| 123 std::string message = var_message.AsString(); | 135 std::string message = var_message.AsString(); |
| 124 if (message == "eightball") { | 136 if (message == "eightball") { |
| 125 if (NULL == eightball_){ | 137 if (NULL == eightball_){ |
| 126 logmsg("Eightball library not loaded"); | 138 logmsg("Eightball library not loaded\n"); |
| 127 return; | 139 return; |
| 128 } | 140 } |
| 129 | 141 |
| 130 std::string ballmessage = "The Magic 8-Ball says: "; | 142 std::string ballmessage = "The Magic 8-Ball says: "; |
| 131 ballmessage += eightball_(); | 143 ballmessage += eightball_(); |
| 132 ballmessage += "!"; | 144 ballmessage += "!\n"; |
| 133 | 145 |
| 134 logmsg(ballmessage.c_str()); | 146 logmsg(ballmessage.c_str()); |
| 135 } else if (message.find("reverse:") == 0) { | 147 } else if (message.find("reverse:") == 0) { |
| 136 if (NULL == reverse_) { | 148 if (NULL == reverse_) { |
| 137 logmsg("Reverse library not loaded"); | 149 logmsg("Reverse library not loaded\n"); |
| 138 return; | 150 return; |
| 139 } | 151 } |
| 140 | 152 |
| 141 std::string s = message.substr(strlen("reverse:")); | 153 std::string s = message.substr(strlen("reverse:")); |
| 142 char* result = reverse_(s.c_str()); | 154 char* result = reverse_(s.c_str()); |
| 143 | 155 |
| 144 std::string message = "Your string reversed: \""; | 156 std::string message = "Your string reversed: \""; |
| 145 message += result; | 157 message += result; |
| 146 message += "\""; | 158 message += "\"\n"; |
| 147 | 159 |
| 148 free(result); | 160 free(result); |
| 149 | 161 |
| 150 logmsg(message.c_str()); | 162 logmsg(message.c_str()); |
| 151 } else { | 163 } else { |
| 152 std::string errormsg = "Unexpected message: "; | 164 std::string errormsg = "Unexpected message: "; |
| 153 errormsg += message + "\n"; | 165 errormsg += message + "\n"; |
| 154 logmsg(errormsg.c_str()); | 166 logmsg(errormsg.c_str()); |
| 155 } | 167 } |
| 156 } | 168 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 // The browser keeps a singleton of this module. It calls the | 205 // The browser keeps a singleton of this module. It calls the |
| 194 // CreateInstance() method on the object you return to make instances. There | 206 // CreateInstance() method on the object you return to make instances. There |
| 195 // is one instance per <embed> tag on the page. This is the main binding | 207 // is one instance per <embed> tag on the page. This is the main binding |
| 196 // point for your NaCl module with the browser. | 208 // point for your NaCl module with the browser. |
| 197 namespace pp { | 209 namespace pp { |
| 198 Module* CreateModule() { | 210 Module* CreateModule() { |
| 199 return new dlOpenModule(); | 211 return new dlOpenModule(); |
| 200 } | 212 } |
| 201 } // namespace pp | 213 } // namespace pp |
| 202 | 214 |
| OLD | NEW |