Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > by-pkgid > 8604cbc4d16ebbba706929d8df6004ee > files > 4

nspluginwrapper-1.1.0-7mdv2009.0.src.rpm

diff -up nspluginwrapper-1.1.0/src/npruntime.c.restart nspluginwrapper-1.1.0/src/npruntime.c
--- nspluginwrapper-1.1.0/src/npruntime.c.restart	2008-06-21 22:13:34.000000000 +0200
+++ nspluginwrapper-1.1.0/src/npruntime.c	2008-07-08 14:10:19.000000000 +0200
@@ -59,6 +59,14 @@ NPClass npclass_bridge = {
   npclass_invoke_RemoveProperty
 };
 
+int npclass_check(NPObject *npobj)
+{
+  NPObjectInfo *p_info = npobject_info_lookup(npobj);
+  if(!p_info->valid)
+    npw_printf("ERROR: NPObject %p is not valid!\n",npobj);
+  return(p_info->valid);
+}
+
 // NPClass::Invalidate
 int npclass_handle_Invalidate(rpc_connection_t *connection)
 {
@@ -72,7 +80,7 @@ int npclass_handle_Invalidate(rpc_connec
 	return error;
   }
 
-  if (npobj && npobj->_class && npobj->_class->invalidate) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->invalidate) {
 	D(bug("NPClass::Invalidate(npobj %p)\n", npobj));
 	npobj->_class->invalidate(npobj);
 	D(bug(" done\n"));
@@ -83,6 +91,9 @@ int npclass_handle_Invalidate(rpc_connec
 
 void npclass_invoke_Invalidate(NPObject *npobj)
 {
+  if(!npclass_check(npobj))
+	return;
+  
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_INVALIDATE,
 								RPC_TYPE_NP_OBJECT, npobj,
@@ -117,7 +128,7 @@ int npclass_handle_HasMethod(rpc_connect
   }
 
   uint32_t ret = 0;
-  if (npobj && npobj->_class && npobj->_class->hasMethod) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->hasMethod) {
 	D(bug("NPClass::HasMethod(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->hasMethod(npobj, name);
 	D(bug(" return: %d\n", ret));
@@ -128,6 +139,9 @@ int npclass_handle_HasMethod(rpc_connect
 
 bool npclass_invoke_HasMethod(NPObject *npobj, NPIdentifier name)
 {
+  if(!npclass_check(npobj))
+	return false;
+  
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_HAS_METHOD,
 								RPC_TYPE_NP_OBJECT, npobj,
@@ -171,7 +185,7 @@ int npclass_handle_Invoke(rpc_connection
   uint32_t ret = 0;
   NPVariant result;
   VOID_TO_NPVARIANT(result);
-  if (npobj && npobj->_class && npobj->_class->invoke) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->invoke) {
 	D(bug("NPClass::Invoke(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->invoke(npobj, name, args, argCount, &result);
 	D(bug(" return: %d\n", ret));
@@ -191,6 +205,9 @@ bool npclass_invoke_Invoke(NPObject *npo
   if (result == NULL)
 	return false;
   VOID_TO_NPVARIANT(*result);
+  
+  if(!npclass_check(npobj))
+	return false;  
 
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_INVOKE,
@@ -237,7 +254,7 @@ int npclass_handle_InvokeDefault(rpc_con
   uint32_t ret = 0;
   NPVariant result;
   VOID_TO_NPVARIANT(result);
-  if (npobj && npobj->_class && npobj->_class->invokeDefault) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->invokeDefault) {
 	D(bug("NPClass::InvokeDefault(npobj %p)\n", npobj));
 	ret = npobj->_class->invokeDefault(npobj, args, argCount, &result);
 	D(bug(" return: %d\n", ret));
@@ -257,6 +274,9 @@ bool npclass_invoke_InvokeDefault(NPObje
   if (result == NULL)
 	return false;
   VOID_TO_NPVARIANT(*result);
+  
+  if(!npclass_check(npobj))
+	return false;
 
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_INVOKE_DEFAULT,
@@ -299,7 +319,7 @@ int npclass_handle_HasProperty(rpc_conne
   }
 
   uint32_t ret = 0;
-  if (npobj && npobj->_class && npobj->_class->hasProperty) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->hasProperty) {
 	D(bug("NPClass::HasProperty(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->hasProperty(npobj, name);
 	D(bug(" return: %d\n", ret));
@@ -310,6 +330,9 @@ int npclass_handle_HasProperty(rpc_conne
 
 bool npclass_invoke_HasProperty(NPObject *npobj, NPIdentifier name)
 {
+  if(!npclass_check(npobj))
+	return false;
+  
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_HAS_PROPERTY,
 								RPC_TYPE_NP_OBJECT, npobj,
@@ -350,7 +373,7 @@ int npclass_handle_GetProperty(rpc_conne
   uint32_t ret = 0;
   NPVariant result;
   VOID_TO_NPVARIANT(result);
-  if (npobj && npobj->_class && npobj->_class->getProperty) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->getProperty) {
 	D(bug("NPClass::GetProperty(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->getProperty(npobj, name, &result);
 	D(bug(" return: %d\n", ret));
@@ -367,7 +390,10 @@ bool npclass_invoke_GetProperty(NPObject
   if (result == NULL)
 	return false;
   VOID_TO_NPVARIANT(*result);
-
+  
+  if(!npclass_check(npobj))
+	return false;
+  
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_GET_PROPERTY,
 								RPC_TYPE_NP_OBJECT, npobj,
@@ -411,7 +437,7 @@ int npclass_handle_SetProperty(rpc_conne
   }
 
   uint32_t ret = 0;
-  if (npobj && npobj->_class && npobj->_class->setProperty) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->setProperty) {
 	D(bug("NPClass::SetProperty(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->setProperty(npobj, name, &value);
 	D(bug(" return: %d\n", ret));
@@ -426,6 +452,9 @@ bool npclass_invoke_SetProperty(NPObject
 {
   if (value == NULL)
 	return false;
+  
+  if(!npclass_check(npobj))
+	return false;
 
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_SET_PROPERTY,
@@ -468,7 +497,7 @@ int npclass_handle_RemoveProperty(rpc_co
   }
 
   uint32_t ret = 0;
-  if (npobj && npobj->_class && npobj->_class->removeProperty) {
+  if (npobj && npobj->_class && npclass_check(npobj) && npobj->_class->removeProperty) {
 	D(bug("NPClass::RemoveProperty(npobj %p, name id %p)\n", npobj, name));
 	ret = npobj->_class->removeProperty(npobj, name);
 	D(bug(" return: %d\n", ret));
@@ -479,6 +508,9 @@ int npclass_handle_RemoveProperty(rpc_co
 
 bool npclass_invoke_RemoveProperty(NPObject *npobj, NPIdentifier name)
 {
+  if(!npclass_check(npobj))
+	return false;
+  
   int error = rpc_method_invoke(g_rpc_connection,
 								RPC_METHOD_NPCLASS_REMOVE_PROPERTY,
 								RPC_TYPE_NP_OBJECT, npobj,
@@ -513,6 +545,7 @@ NPObjectInfo *npobject_info_new(NPObject
 	static uint32_t id;
 	npobj_info->npobj = npobj;
 	npobj_info->npobj_id = ++id;
+	npobj_info->valid = 1;
   }
   return npobj_info;
 }
@@ -638,3 +671,14 @@ NPObject *npobject_lookup(uint32_t npobj
 {
   return g_hash_table_lookup(g_npobject_ids, (void *)(uintptr_t)npobj_id);
 }
+
+static void npruntime_deactivate_func(gpointer key, gpointer value, gpointer user_data)
+{
+  NPObjectInfo *p_info = (NPObjectInfo *)value;
+  p_info->valid = 0;
+}
+
+void npruntime_deactivate(void)
+{
+  g_hash_table_foreach(g_npobjects, npruntime_deactivate_func, NULL);
+}
diff -up nspluginwrapper-1.1.0/src/npruntime-impl.h.restart nspluginwrapper-1.1.0/src/npruntime-impl.h
--- nspluginwrapper-1.1.0/src/npruntime-impl.h.restart	2008-06-21 22:13:34.000000000 +0200
+++ nspluginwrapper-1.1.0/src/npruntime-impl.h	2008-07-08 14:10:19.000000000 +0200
@@ -25,6 +25,7 @@
 typedef struct {
   NPObject *npobj;
   uint32_t npobj_id;
+  uint32_t valid;
 } NPObjectInfo;
 
 extern NPObjectInfo *npobject_info_new(NPObject *npobj) attribute_hidden;
@@ -63,4 +64,7 @@ extern int npclass_handle_Invalidate(rpc
 struct _NPNetscapeFuncs;
 extern void npruntime_init_callbacks(struct _NPNetscapeFuncs *mozilla_funcs);
 
+// Deactivate all NPObject instances
+extern void npruntime_deactivate(void);
+
 #endif /* NPRUNTIME_IMPL_H */
diff -up nspluginwrapper-1.1.0/src/npw-wrapper.c.restart nspluginwrapper-1.1.0/src/npw-wrapper.c
--- nspluginwrapper-1.1.0/src/npw-wrapper.c.restart	2008-07-08 14:10:19.000000000 +0200
+++ nspluginwrapper-1.1.0/src/npw-wrapper.c	2008-07-08 14:10:19.000000000 +0200
@@ -107,7 +107,11 @@ typedef struct _StreamInstance {
 // Prototypes
 static void plugin_init(int is_NP_Initialize);
 static void plugin_exit(void);
-static NPError plugin_restart_if_needed(void);
+
+static void plugin_kill(rpc_connection_t *connection);
+static NPError plugin_start(void);
+static NPError plugin_start_if_needed(void);
+static int  plugin_killed = 0;
 
 /*
  *  Notes concerning NSPluginWrapper recovery model.
@@ -126,10 +130,8 @@ static NPError plugin_restart_if_needed(
  *  connection and thus can fail early/gracefully in subsequent calls
  *  to NPP_*() functions.
  *
- *  TODO: make NPRuntime aware of per-plugin connections? This
- *  shouldn't matter from the Wrapper side because npruntime requests
- *  come from the Viewer side (see NPN_*() handlers). XXX: even with a
- *  running script (NPClass handlers)?
+ *  All active NPRuntime objects are marked as inactive and 
+ *  are not processed.
  */
 
 // Minimal time between two plugin restarts in sec
@@ -1361,7 +1363,7 @@ g_NPP_New(NPMIMEType mime_type, NPP inst
 	return NPERR_INVALID_INSTANCE_ERROR;
 	
   // Check if we need to restart the plug-in
-  NPError ret = plugin_restart_if_needed();
+  NPError ret = plugin_start_if_needed();
   if (ret != NPERR_NO_ERROR)
   	return ret;
 		
@@ -2870,6 +2872,9 @@ static void plugin_init(int is_NP_Initia
 	return;
   }
 
+  // Set error handler - stop plugin if there's a connection error
+  rpc_connection_error_callback_set(g_rpc_connection, plugin_kill);
+  
   g_plugin.initialized = 1 + is_NP_Initialize;
   D(bug("--- INIT ---\n"));
 }
@@ -2942,17 +2947,39 @@ static void __attribute__((destructor)) 
   }
 }
 
-static NPError plugin_restart(void)
+static void plugin_kill(rpc_connection_t *connection)
 {
   if (g_plugin.is_wrapper)
-	return NPERR_NO_ERROR;
+	return;  
 
-  // Shut it down    
+  D(bug("plugin_kill, connection %p\n",connection));
+	
+  // Kill viewer and plugin
   plugin_exit();
+
+  // Clear-up
   g_plugin.initialized = 0;
   g_plugin.viewer_pid = -1;
   g_plugin.is_wrapper = 0;
 
+  npruntime_deactivate();
+
+  // Set the kill flag
+  plugin_killed = 1;
+}
+
+static NPError plugin_start(void)
+{
+  D(bug("plugin_start\n"));
+
+  if(!plugin_killed) {
+    // Plugin is still active
+    // terminate it before the restart
+    D(bug("plugin_start: plugin_killed = 0!\n"));
+    plugin_kill(g_rpc_connection);
+  }
+  plugin_killed = 0;
+
   // And start it again
   plugin_init(1);
   if (g_plugin.initialized <= 0)
@@ -2961,7 +2988,7 @@ static NPError plugin_restart(void)
   return invoke_NP_Initialize(npapi_version);
 }
 
-static NPError plugin_restart_if_needed(void)
+static NPError plugin_start_if_needed(void)
 {
   if (rpc_status(g_rpc_connection) != RPC_STATUS_ACTIVE) {
 	static time_t last_restart = 0;
@@ -2971,7 +2998,7 @@ static NPError plugin_restart_if_needed(
 	last_restart = now;
 
 	D(bug("Restart plugins viewer\n"));
-	NPError ret = plugin_restart();
+	NPError ret = plugin_start();
 	D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
 	return ret;
   }
diff -up nspluginwrapper-1.1.0/src/rpc.c.restart nspluginwrapper-1.1.0/src/rpc.c
--- nspluginwrapper-1.1.0/src/rpc.c.restart	2008-07-06 21:54:45.000000000 +0200
+++ nspluginwrapper-1.1.0/src/rpc.c	2008-07-08 14:18:41.000000000 +0200
@@ -427,6 +427,7 @@ struct rpc_connection {
   pthread_t server_thread;
   rpc_map_t *types;
   rpc_map_t *methods;
+  rpc_error_callback_t callback_error;
 };
 
 // Increment connection reference count
@@ -446,6 +447,29 @@ void rpc_connection_unref(rpc_connection
   }
 }
 
+// Set error callback
+void rpc_connection_error_callback_set(rpc_connection_t *connection,
+                                       rpc_error_callback_t callback)
+{
+  if (connection == NULL)
+	return;
+  if (connection->callback_error != NULL)
+	return;  
+  connection->callback_error = callback;
+}
+
+// Call error callback if the connection is closed
+static void rpc_connection_error_callback_call(rpc_connection_t *connection)
+{
+  if (connection == NULL)
+	return;
+  if (connection->callback_error == NULL)
+	return;
+  
+  (connection->callback_error)(connection);
+  connection->callback_error = NULL;
+}
+
 // Returns connection status
 static inline int _rpc_status(rpc_connection_t *connection)
 {
@@ -484,6 +508,11 @@ static inline int rpc_error(rpc_connecti
   assert(error < 0);
   assert(connection != NULL);
   _rpc_set_status(connection, error);
+	
+  if(_rpc_status(connection) == RPC_STATUS_CLOSED || _rpc_status(connection) == RPC_STATUS_BROKEN) {
+	rpc_connection_error_callback_call(connection);
+  }
+  
   return error;
 }
 
@@ -566,6 +595,7 @@ rpc_connection_t *rpc_init_server(const 
   connection->status = RPC_STATUS_CLOSED;
   connection->socket = -1;
   connection->server_thread_active = 0;
+  connection->callback_error = NULL;
   if ((connection->types = rpc_map_new_full((free))) == NULL) {
 	rpc_exit(connection);
 	return NULL;
@@ -623,6 +653,7 @@ rpc_connection_t *rpc_init_client(const 
   connection->refcnt = 1;
   connection->status = RPC_STATUS_CLOSED;
   connection->server_socket = -1;
+  connection->callback_error = NULL;
   if ((connection->types = rpc_map_new_full((free))) == NULL) {
 	rpc_exit(connection);
 	return NULL;
diff -up nspluginwrapper-1.1.0/src/rpc.h.restart nspluginwrapper-1.1.0/src/rpc.h
--- nspluginwrapper-1.1.0/src/rpc.h.restart	2008-06-21 22:13:34.000000000 +0200
+++ nspluginwrapper-1.1.0/src/rpc.h	2008-07-08 14:10:19.000000000 +0200
@@ -122,4 +122,10 @@ extern int rpc_method_send_reply(rpc_con
 }
 #endif
 
+// This callback is called when the connection is closed or broken
+typedef int (*rpc_error_callback_t)(rpc_connection_t *connection);
+
+// Set callback for a connection
+void rpc_connection_error_callback_set(rpc_connection_t *connection, rpc_error_callback_t callback);
+
 #endif /* RPC_H */