aboutsummaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
authorJiri Vanek <[email protected]>2013-12-15 11:07:05 +0100
committerJiri Vanek <[email protected]>2013-12-15 11:07:05 +0100
commitd91bf9ee53eebc7028f4143e03881ee350e4ebef (patch)
treed1886733f58835ff3a9ae5d51a5411139ae55ce5 /plugin
parent3c5836190bd9954c56c7d4180bfc2e7ed9a0d82d (diff)
Console made aware of plugin messages
Diffstat (limited to 'plugin')
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.cc153
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.h9
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.cc33
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.h39
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMain.java17
5 files changed, 245 insertions, 6 deletions
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc
index 9a0d0c4..1317831 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc
@@ -138,6 +138,9 @@ gint in_watch_source;
// Applet viewer output pipe name.
gchar* out_pipe_name;
+// Applet viewer debug pipe name.
+gchar* debug_pipe_name = NULL;
+
// Applet viewer output watch source.
gint out_watch_source;
@@ -147,9 +150,15 @@ pthread_t itnp_plugin_thread_id;
// Mutex to lock async call queue
pthread_mutex_t pluginAsyncCallMutex;
+/*to sync pipe to apletviewer console*/
+pthread_mutex_t debug_pipe_lock = PTHREAD_MUTEX_INITIALIZER;
+
// Applet viewer output channel.
GIOChannel* out_to_appletviewer;
+// Applet viewer debug channel.
+GIOChannel* debug_to_appletviewer = NULL;
+
// Tracks jvm status
gboolean jvm_up = FALSE;
@@ -488,6 +497,34 @@ void start_jvm_if_needed()
}
PLUGIN_DEBUG ("ITNP_New: created output fifo: %s\n", out_pipe_name);
+ // Create plugin-debug-to-appletviewer pipe which we refer to as the
+ // debug pipe.
+ initialize_debug();//should be already initialized, but...
+ if (plugin_debug_to_console){
+ // debug_pipe_name
+ debug_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-debug-to-appletviewer",
+ data_directory.c_str(), getpid());
+
+ if (!debug_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create debug pipe name.\n");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_debug_pipe_name;
+ }
+
+ // clean up any older pip
+ unlink (debug_pipe_name);
+
+ PLUGIN_DEBUG ("ITNP_New: creating debug fifo: %s\n", debug_pipe_name);
+ if (mkfifo (debug_pipe_name, 0600) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR ("Failed to create debug pipe\n", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_debug_pipe_name;
+ }
+ PLUGIN_DEBUG ("ITNP_New: created debug fifo: %s\n", debug_pipe_name);
+ }
+
// Start a separate appletviewer process for each applet, even if
// there are multiple applets in the same page. We may need to
// change this behaviour if we find pages with multiple applets that
@@ -548,12 +585,46 @@ void start_jvm_if_needed()
g_io_add_watch (in_from_appletviewer,
(GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP),
plugin_in_pipe_callback, (gpointer) in_from_appletviewer);
+
+ // Create plugin-to-appletviewer console debug channel. The default encoding for
+ // the file is UTF-8.
+ // debug_to_appletviewer
+ if (plugin_debug_to_console){
+ debug_to_appletviewer = g_io_channel_new_file (debug_pipe_name,
+ "w", &channel_error);
+ if (!debug_to_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR ("Failed to debug output channel, '%s'\n",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create debug channel\n");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_debug_to_appletviewer;
+ }
+ }
jvm_up = TRUE;
-
+
+ if (plugin_debug_to_console){
+ //jvm is up, we can start console producer thread
+ pthread_t debug_to_console_consumer;
+ pthread_create(&debug_to_console_consumer,NULL,&flush_pre_init_messages,NULL);
+ }
goto done;
// Free allocated data in case of error
+ cleanup_debug_to_appletviewer:
+ if (plugin_debug_to_console){
+ if (debug_to_appletviewer)
+ g_io_channel_unref (debug_to_appletviewer);
+ debug_to_appletviewer = NULL;
+ }
cleanup_in_watch_source:
// Removing a source is harmless if it fails since it just means the
@@ -575,6 +646,21 @@ void start_jvm_if_needed()
g_io_channel_unref (out_to_appletviewer);
out_to_appletviewer = NULL;
+ if (plugin_debug_to_console){
+ // cleanup_debug_pipe:
+ // Delete output pipe.
+ PLUGIN_DEBUG ("ITNP_New: deleting debug fifo: %s\n", debug_pipe_name);
+ unlink (debug_pipe_name);
+ PLUGIN_DEBUG ("ITNP_New: deleted debug fifo: %s\n", debug_pipe_name);
+ }
+ cleanup_debug_pipe_name:
+ if (plugin_debug_to_console){
+ g_free (debug_pipe_name);
+ debug_pipe_name = NULL;
+ }
+
+
+
// cleanup_out_pipe:
// Delete output pipe.
PLUGIN_DEBUG ("ITNP_New: deleting input fifo: %s\n", in_pipe_name);
@@ -1401,6 +1487,9 @@ plugin_start_appletviewer (ITNPPluginData* data)
command_line.push_back("sun.applet.PluginMain");
command_line.push_back(out_pipe_name);
command_line.push_back(in_pipe_name);
+ if (plugin_debug_to_console){
+ command_line.push_back(debug_pipe_name);
+ }
// Finished command line parameters
@@ -1576,6 +1665,38 @@ plugin_send_message_to_appletviewer (gchar const* message)
PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n");
}
+// unlike like plugin_send_message_to_appletviewer
+// do not debug
+// do not error
+// do not have its own line end
+// is accesed by only one thread
+// have own pipe
+// jvm must be up
+void
+plugin_send_message_to_appletviewer_console (gchar const* newline_message)
+{
+ gsize bytes_written = 0;
+ if (g_io_channel_write_chars (debug_to_appletviewer,
+ newline_message, -1, &bytes_written,
+ &channel_error) != G_IO_STATUS_NORMAL) {
+ if (channel_error) {
+ //error must be freed
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ }
+}
+//flush only when its full
+void flush_plugin_send_message_to_appletviewer_console (){
+ if (g_io_channel_flush (debug_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL) {
+ if (channel_error) {
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ }
+}
+
/*
* Sends the initialization message (handle/size/url) to the plugin
*/
@@ -2046,6 +2167,36 @@ NP_Shutdown (void)
g_free (in_pipe_name);
in_pipe_name = NULL;
+ if (plugin_debug_to_console){
+ //jvm_up is now false
+ if (g_io_channel_shutdown (debug_to_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR ("Failed to shut down appletviewer"
+ " debug channel\n", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down debug to appletviewer\n");
+ }
+ // cleanup_out_to_appletviewer:
+ if (debug_to_appletviewer)
+ g_io_channel_unref (debug_to_appletviewer);
+ out_to_appletviewer = NULL;
+ // cleanup_debug_pipe:
+ // Delete debug pipe.
+ PLUGIN_DEBUG ("NP_Shutdown: deleting debug fifo: %s\n", debug_pipe_name);
+ unlink (debug_pipe_name);
+ PLUGIN_DEBUG ("NP_Shutdown: deleted debug fifo: %s\n", debug_pipe_name);
+ // cleanup_out_pipe_name:
+ g_free (debug_pipe_name);
+ debug_pipe_name = NULL;
+ }
+
// Destroy the call queue mutex
pthread_mutex_destroy(&pluginAsyncCallMutex);
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.h b/plugin/icedteanp/IcedTeaNPPlugin.h
index 6e1465b..3e66599 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.h
+++ b/plugin/icedteanp/IcedTeaNPPlugin.h
@@ -115,6 +115,9 @@ extern pthread_t itnp_plugin_thread_id;
/* Mutex around plugin async call queue ops */
extern pthread_mutex_t pluginAsyncCallMutex;
+/*to sync pipe to apletviewer console*/
+extern pthread_mutex_t debug_pipe_lock;
+
// debug switches
extern bool debug_initiated;
extern int plugin_debug;
@@ -125,6 +128,9 @@ extern bool plugin_debug_to_system;
extern bool plugin_debug_to_console;
extern FILE * plugin_file_log;
extern std::string plugin_file_log_name;
+extern gchar* debug_pipe_name;
+
+extern gboolean jvm_up;
// Browser function table.
extern NPNetscapeFuncs browser_functions;
@@ -152,6 +158,9 @@ int get_id_from_instance(NPP instance);
/* Sends a message to the appletviewer */
void plugin_send_message_to_appletviewer(gchar const* message);
+/*this method is not logging, do not add \n and is using different pipe*/
+void plugin_send_message_to_appletviewer_console(gchar const* message);
+void flush_plugin_send_message_to_appletviewer_console();
/* Returns an appropriate (package/object) scriptable npobject */
NPObject* get_scriptable_object(NPP instance);
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc
index 0986aa8..5cd4231 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.cc
+++ b/plugin/icedteanp/IcedTeaPluginUtils.cc
@@ -54,10 +54,37 @@ int IcedTeaPluginUtilities::reference = -1;
pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALIZER;
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*>();
+std::queue<std::string> pre_jvm_message;
/* Plugin async call queue */
static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >();
+void *flush_pre_init_messages(void* data) {
+while (true){
+ struct timespec ts;
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ nanosleep(&ts ,0);
+ if (jvm_up) {
+ while (!pre_jvm_message.empty()) {
+ pthread_mutex_lock(&debug_pipe_lock);
+ std::string message = pre_jvm_message.front();
+ pre_jvm_message.pop();
+ pthread_mutex_unlock(&debug_pipe_lock);
+ plugin_send_message_to_appletviewer_console(message.c_str());
+
+ }
+ flush_plugin_send_message_to_appletviewer_console();
+ }
+
+}
+}
+void push_pre_init_messages(char * ldm){
+ pthread_mutex_lock(&debug_pipe_lock);
+ pre_jvm_message.push(std::string(ldm));
+ pthread_mutex_unlock(&debug_pipe_lock);
+}
+
/**
* Given a context number, constructs a message prefix to send to Java
*
@@ -1161,7 +1188,11 @@ void IcedTeaPluginUtilities::printDebugStatus(){
PLUGIN_DEBUG("plugin_debug_to_system: false\n");
}
if (plugin_debug_to_console){
- PLUGIN_DEBUG("plugin_debug_to_console: true\n");
+ if (debug_pipe_name){
+ PLUGIN_DEBUG("plugin_debug_to_console: true, pipe %s\n", debug_pipe_name);
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_console: true, pipe not yet known or broken\n");
+ }
} else {
PLUGIN_DEBUG("plugin_debug_to_console: false\n");
}
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.h b/plugin/icedteanp/IcedTeaPluginUtils.h
index f0f52d7..6967793 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.h
+++ b/plugin/icedteanp/IcedTeaPluginUtils.h
@@ -58,6 +58,7 @@ exception statement from your version. */
#include <sstream>
#include <string>
#include <vector>
+#include <queue>
#include <npapi.h>
#include <glib.h>
@@ -65,6 +66,9 @@ exception statement from your version. */
#include "IcedTeaParseProperties.h"
+void *flush_pre_init_messages(void* data);
+void push_pre_init_messages(char * ldm);
+
// debugging macro.
#define initialize_debug() \
do \
@@ -81,7 +85,7 @@ exception statement from your version. */
IcedTeaPluginUtilities::initFileLog(); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*initialisation done during jvm startup*/ \
} \
IcedTeaPluginUtilities::printDebugStatus(); \
} \
@@ -91,6 +95,7 @@ exception statement from your version. */
#define HEADER_SIZE 500
#define BODY_SIZE 500
#define MESSAGE_SIZE HEADER_SIZE + BODY_SIZE
+#define LDEBUG_MESSAGE_SIZE MESSAGE_SIZE+50
//header is destination char array
#define CREATE_HEADER(ldebug_header) \
@@ -132,7 +137,21 @@ exception statement from your version. */
fflush(plugin_file_log); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*headers are always going to console*/ \
+ if (!plugin_debug_headers){ \
+ CREATE_HEADER(ldebug_header); \
+ } \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \
+ struct timeval current_time; \
+ gettimeofday (&current_time, NULL);\
+ if (jvm_up) { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } else { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } \
} \
} \
} while (0)
@@ -161,7 +180,21 @@ exception statement from your version. */
fflush(plugin_file_log); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*headers are always going to console*/ \
+ if (!plugin_debug_headers){ \
+ CREATE_HEADER(ldebug_header); \
+ } \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \
+ struct timeval current_time; \
+ gettimeofday (&current_time, NULL);\
+ if (jvm_up) { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } else { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } \
} \
} while (0)
diff --git a/plugin/icedteanp/java/sun/applet/PluginMain.java b/plugin/icedteanp/java/sun/applet/PluginMain.java
index e6ba080..421edb5 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java
@@ -84,6 +84,7 @@ import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.security.JNLPAuthenticator;
import net.sourceforge.jnlp.util.logging.JavaConsole;
+import net.sourceforge.jnlp.util.logging.LogConfig;
import net.sourceforge.jnlp.util.logging.OutputController;
/**
@@ -119,16 +120,30 @@ public class PluginMain {
*/
public static void main(String args[])
throws IOException {
+ //we are polite, we reprint start arguments
+ OutputController.getLogger().log("startup arguments: ");
+ for (int i = 0; i < args.length; i++) {
+ String string = args[i];
+ OutputController.getLogger().log(i + ": "+string);
+
+ }
if (AppContext.getAppContext() == null) {
SunToolkit.createNewAppContext();
}
installDummyJavascriptProtocolHandler();
- if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {
+ if (args.length < 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {
OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Invalid pipe names provided. Refusing to proceed.");
JNLPRuntime.exit(1);
}
DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched();
+ if (JavaConsole.isEnabled()) {
+ if ((args.length < 3) || !new File(args[2]).exists()) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Warning, although console is on, plugin debug connection do not exists. No plugin information will be displayed in console (only java ones).");
+ } else {
+ JavaConsole.getConsole().createPluginReader(new File(args[2]));
+ }
+ }
try {
PluginStreamHandler streamHandler = connect(args[0], args[1]);