Chromium Code Reviews| Index: native_client_sdk/src/examples/dlopen/dlopen.cc |
| =================================================================== |
| --- native_client_sdk/src/examples/dlopen/dlopen.cc (revision 0) |
| +++ native_client_sdk/src/examples/dlopen/dlopen.cc (revision 0) |
| @@ -0,0 +1,174 @@ |
| +// Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
|
Brad Chen
2012/01/28 01:00:52
Where should a developer expect to see an overview
noelallen1
2012/01/31 21:03:21
None of the examples have docs locally. The docs
|
| +#include <dlfcn.h> // for dlopen |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <pthread.h> // for pthreads |
| + |
| +#include <ppapi/cpp/module.h> |
| +#include <ppapi/cpp/completion_callback.h> |
| +#include <ppapi/cpp/var.h> |
| +#include <ppapi/cpp/instance.h> |
| + |
| +#include "eightball.h" |
| + |
| + |
| +// NOTE, dlopen is a BLOCKING call; Behind the scenes, it will kick off an |
| +// XHR request to dynamically load the .so file from the server, and return |
|
Brad Chen
2012/01/28 01:00:52
XHR needs a definition or cross-reference.
noelallen1
2012/01/31 21:03:21
removed
|
| +// when the .so has been loaded. As such, it cannot be called from the main |
| +// thread until the .so file has been cached. (otherwise you will stall the |
|
Brad Chen
2012/01/28 01:00:52
Not grammatical.
noelallen1
2012/01/31 21:03:21
Done.
|
| +// process and block indefenitally.) To fix this, you must spin up a temporary |
| +// thread to call dlopen and dlclose on all of your target .so files before |
| +// allowing your main thread to query them. |
| + |
| + |
| +// a global handle to the CORE object; this will make it easier to issue |
|
Brad Chen
2012/01/28 01:00:52
Especially in external examples I think we should
noelallen1
2012/01/31 21:03:21
Globals removed.
On 2012/01/28 01:00:52, Brad Chen
|
| +// CallOnMainThread functions w/o API restrictions. |
| +pp::Core* g_core = NULL; |
| + |
| +void* loadLibrariesOnThread(void *pInst); |
| + |
| + char *(*eightball)(void); |
|
Brad Chen
2012/01/28 01:00:52
The use of indentation and spaces in the above thr
noelallen1
2012/01/31 21:03:21
Done.
|
| +// the Instance class. |
|
Brad Chen
2012/01/28 01:00:52
If this is the first NaCl example a developer look
noelallen1
2012/01/31 21:03:21
Done.
|
| +class dlOpenInstance : public pp::Instance { |
|
Brad Chen
2012/01/28 01:00:52
It sure makes me sad we can't do a simple example
noelallen1
2012/01/31 21:03:21
Done.
|
| + public: |
| + explicit dlOpenInstance(PP_Instance instance):pp::Instance(instance) { |
| + eightball=(NULL); |
|
Brad Chen
2012/01/28 01:00:52
" = "
noelallen1
2012/01/31 21:03:21
Done.
|
| + }; |
| + virtual ~dlOpenInstance(){}; |
| + |
| + // helper function to post a message back to the JS and stdout functions |
| + void logmsg(const char* pStr){ |
| + PostMessage(pp::Var(pStr)); |
| + fprintf(stdout,(const char*)pStr); |
| + } |
| + |
| + |
| + // this function will run on the main thread and will grab a handle to the |
| + // .so and it's exposed function. Note that this function is called |
|
Brad Chen
2012/01/28 01:00:52
"its" ; also non-standard capitalization. Maybe we
|
| + // once the library has been loaded properly from a pthread. |
| + void* loadLibs(void* userData, int32_t result) { |
| + |
| + logmsg("calling dlopen() from main thread\n"); |
|
Brad Chen
2012/01/28 01:00:52
Why is this not indented? Why the white space befo
|
| + |
| + // NOTE, we have not called dlclose on this .so object. Doing so will unload |
| + // it, and cause this function to go attempt to fetch it again :( |
| + dlhandle = dlopen("libeightball.so", RTLD_LAZY); |
| + if(dlhandle == NULL){ |
|
Brad Chen
2012/01/28 01:00:52
"if (dlhandle == NULL) {"
I really think we need t
noelallen1
2012/01/31 21:03:21
Done.
|
| + logmsg("libeightball.so did not load"); |
| + return false; |
| + } |
| + else { |
| + eightball = (TYPE_eightball) dlsym(dlhandle, "Magic8Ball"); |
| + if (eightball == NULL) { |
| + std::string ballmessage; |
| + sprintf(&ballmessage[0], "dlsym() returned NULL : %s\n",dlerror()); |
| + logmsg(ballmessage.c_str()); |
| + return false; |
| + } |
| + else{ |
| + logmsg("Eightball loaded!"); |
| + } |
| + } |
| + |
| + return 0; |
| + } |
| + |
| + // Init the module |
| + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]){ |
| + // spawn a thread to load up our .so objects |
| + pthread_t threadHdl; |
| + logmsg("Spawning thread to cache .so files..."); |
| + int rc = pthread_create(&threadHdl, NULL, loadLibrariesOnThread, NULL); |
| + if (rc){ |
| + logmsg("ERROR; return code from pthread_create()\n"); |
| + return false; |
| + } |
| + |
| + return true; |
| + } |
| + |
| + // Called by the browser to handle the postMessage() call in Javascript. |
| + virtual void HandleMessage(const pp::Var& var_message) { |
| + if(eightball == NULL){ |
| + logmsg("Eightball library not loaded"); |
| + } |
| + else if (!var_message.is_string()) { |
| + logmsg("Unknown"); |
| + } |
| + else{ |
| + std::string message = var_message.AsString(); |
| + if (message == "query") { |
| + std::string ballmessage; |
| + sprintf(&ballmessage[0], "!The Magic 8-Ball says: %s", eightball()); |
| + logmsg(ballmessage.c_str()); |
| + } |
| + } |
| + } |
| + private: |
| + void *dlhandle; |
| + |
| + }; |
| + |
| +// A global instance of the dlOpenInstance object; This will make the callbacks easier |
|
Brad Chen
2012/01/28 01:00:52
long line, grammar, punctuation, capitalization et
|
| +// from the pthread doing the loading of dlobjects. |
| +dlOpenInstance* gInstance; |
| + |
| +// The Module class. The browser calls the CreateInstance() method to create |
| +// an instance of your NaCl module on the web page. The browser creates a new |
| +// instance for each <embed> tag with type="application/x-nacl". |
| +class dlOpenModule : public pp::Module { |
| + public: |
| + dlOpenModule() : pp::Module() {} |
| + virtual ~dlOpenModule() {} |
| + |
| + // Create and return a dlOpenInstance object. |
| + virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| + g_core = core(); |
| + gInstance= new dlOpenInstance(instance); |
| + return gInstance; |
| + } |
| +}; |
| + |
| +// this callback is here simply to help us call the static instance. |
| +// We can't pass pointers to members in g++ so this is the fix. |
| +void libLoaderCBHelper(void* userData, int32_t result){ |
| + gInstance->loadLibs(userData,result); |
| +} |
| + |
| + |
| +// this function is called on a worker thread, and will call dlopen to load the |
| +// object remember, dlopen is a blocking call, and thus, cannot be called on |
| +// the main thread in addition, note that this function does NOT call dlclose; |
| +// That would close the shared object and unload it from memory, such that |
| +// subisquent dlopens would attempt to re-load them from cache / network. |
| +void* loadLibrariesOnThread(void *pInst) |
| +{ |
| + |
|
Brad Chen
2012/01/28 01:00:52
Please get rid of the extra whitespace.
|
| + const int err=-27; |
| + void* dlhandle = dlopen("libeightball.so", RTLD_LAZY); |
| + if(dlhandle == NULL) |
| + pthread_exit((void*)&err); |
| + |
| + |
| + // issue a callback on the main thread to load the libraries there. |
| + pp::CompletionCallback cc(libLoaderCBHelper, 0); |
| + g_core->CallOnMainThread(0, cc , 0); |
|
Brad Chen
2012/01/28 01:00:52
What do you actually need to do on the main thread
|
| + |
| + pthread_exit(NULL); |
| +} |
| + |
| + |
| + |
| +// Factory function called by the browser when the module is first loaded. |
| +// The browser keeps a singleton of this module. It calls the |
| +// CreateInstance() method on the object you return to make instances. There |
| +// is one instance per <embed> tag on the page. This is the main binding |
| +// point for your NaCl module with the browser. |
| +namespace pp { |
| + Module* CreateModule() { |
| + return new dlOpenModule(); |
| + } |
| +} // namespace pp |
| + |
| Property changes on: native_client_sdk/src/examples/dlopen/dlopen.cc |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |