Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Unified Diff: native_client_sdk/src/examples/dlopen/dlopen.cc

Issue 9234043: Support GLBIC example. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: re-enable the full build Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698