diff options
author | Deepak Bhole <[email protected]> | 2011-06-08 14:38:52 -0400 |
---|---|---|
committer | Deepak Bhole <[email protected]> | 2011-06-08 14:38:52 -0400 |
commit | 57a1d6169ce4b03610a1ba56567821f16cf661ce (patch) | |
tree | 6e850d89a19999b19a67009bacb472a8db72a7f4 /plugin/icedteanp/IcedTeaPluginUtils.cc | |
parent | bb07f5268340fcb25ccc80130d2be0e0b9820760 (diff) |
Fix PR721: IcedTeaPlugin.so cannot run g_main_context_iteration on a different thread unless a different GMainContext *context is used
Diffstat (limited to 'plugin/icedteanp/IcedTeaPluginUtils.cc')
-rw-r--r-- | plugin/icedteanp/IcedTeaPluginUtils.cc | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc index 69daef2..854430d 100644 --- a/plugin/icedteanp/IcedTeaPluginUtils.cc +++ b/plugin/icedteanp/IcedTeaPluginUtils.cc @@ -54,6 +54,9 @@ pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALI std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>(); std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>(); +/* Plugin async call queue */ +static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >(); + /** * Given a context number, constructs a message prefix to send to Java * @@ -910,6 +913,108 @@ IcedTeaPluginUtilities::decodeURL(const gchar* url, gchar** decoded_url) PLUGIN_DEBUG("SENDING URL: %s\n", *decoded_url); } + +/** + * Posts a function for execution on the plug-in thread and wait for result. + * + * @param instance The NPP instance + * @param func The function to post + * @param data Arguments to *func + */ +void +IcedTeaPluginUtilities::callAndWaitForResult(NPP instance, void (*func) (void *), AsyncCallThreadData* data) +{ + + struct timespec t; + struct timespec curr_t; + clock_gettime(CLOCK_REALTIME, &t); + t.tv_sec += REQUESTTIMEOUT; // timeout + + // post request + postPluginThreadAsyncCall(instance, func, data); + + do + { + clock_gettime(CLOCK_REALTIME, &curr_t); + if (data != NULL && !data->result_ready && (curr_t.tv_sec < t.tv_sec)) + { + usleep(2000); + } else + { + break; + } + } while (1); +} + + +/** + * Posts a request that needs to be handled in a plugin thread. + * + * @param instance The plugin instance + * @param func The function to execute + * @param userData The userData for the function to consume/write to + * @return if the call was posted successfully + */ + +bool +IcedTeaPluginUtilities::postPluginThreadAsyncCall(NPP instance, void (*func) (void *), void* data) +{ + if (instance) + { + PluginThreadCall* call = new PluginThreadCall(); + call->instance = instance; + call->func = func; + call->userData = data; + + pthread_mutex_lock(&pluginAsyncCallMutex); + pendingPluginThreadRequests->push_back(call); + pthread_mutex_unlock(&pluginAsyncCallMutex); + + browser_functions.pluginthreadasynccall(instance, &processAsyncCallQueue, NULL); // Always returns immediately + + PLUGIN_DEBUG("Pushed back call evt %p\n", call); + + return true; + } + + // Else + PLUGIN_DEBUG("Instance is not active. Call rejected.\n"); + return false; +} + +/** + * Runs through the async call wait queue and executes all calls + * + * @param param Ignored -- required to conform to NPN_PluginThreadAsynCall API + */ +void +processAsyncCallQueue(void* param /* ignored */) +{ + do { + PluginThreadCall* call = NULL; + + pthread_mutex_lock(&pluginAsyncCallMutex); + if (pendingPluginThreadRequests->size() > 0) + { + call = pendingPluginThreadRequests->front(); + pendingPluginThreadRequests->erase(pendingPluginThreadRequests->begin()); + } + pthread_mutex_unlock(&pluginAsyncCallMutex); + + if (call) + { + PLUGIN_DEBUG("Processing call evt %p\n", call); + call->func(call->userData); + PLUGIN_DEBUG("Call evt %p processed\n", call); + + delete call; + } else + { + break; + } + } while(1); +} + /****************************************** * Begin JavaMessageSender implementation * ****************************************** |