rpms/nspluginwrapper/devel nspluginwrapper-0.9.91.5-restart.patch, NONE, 1.1 nspluginwrapper-0.9.91.5-rpc-error.patch, NONE, 1.1 nspluginwrapper-0.9.91.5-rh.patch, 1.1, 1.2 nspluginwrapper.spec, 1.16, 1.17
Martin Stransky (stransky)
fedora-extras-commits at redhat.com
Mon Sep 10 08:44:46 UTC 2007
- Previous message (by thread): rpms/hedgewars/F-7 hedgewars-0.9.0-debuginfo.patch, NONE, 1.1 hedgewars.desktop, NONE, 1.1 hedgewars.png, NONE, 1.1 hedgewars.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Next message (by thread): rpms/libcaca/EL-5 .cvsignore, 1.2, 1.3 libcaca.spec, 1.12, 1.13 sources, 1.2, 1.3 libcaca-0.9-man3.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: stransky
Update of /cvs/pkgs/rpms/nspluginwrapper/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv23025
Modified Files:
nspluginwrapper-0.9.91.5-rh.patch nspluginwrapper.spec
Added Files:
nspluginwrapper-0.9.91.5-restart.patch
nspluginwrapper-0.9.91.5-rpc-error.patch
Log Message:
added upstream patches - RPC error handling and plugin restart
nspluginwrapper-0.9.91.5-restart.patch:
--- NEW FILE nspluginwrapper-0.9.91.5-restart.patch ---
Index: src/npw-viewer.c
===================================================================
--- src/npw-viewer.c (révision 466)
+++ src/npw-viewer.c (révision 470)
@@ -2268,6 +2268,8 @@
{
D(bug("handle_NPP_New\n"));
+ rpc_connection_ref(connection);
+
uint32_t instance_id;
NPMIMEType plugin_type;
int32_t mode;
@@ -2344,7 +2346,10 @@
NPSavedData *save_area;
NPError ret = g_NPP_Destroy(instance, &save_area);
- return rpc_method_send_reply(connection, RPC_TYPE_INT32, ret, RPC_TYPE_NP_SAVED_DATA, save_area, RPC_TYPE_INVALID);
+
+ error = rpc_method_send_reply(connection, RPC_TYPE_INT32, ret, RPC_TYPE_NP_SAVED_DATA, save_area, RPC_TYPE_INVALID);
+ rpc_connection_unref(connection);
+ return error;
}
// NPP_SetWindow
@@ -2654,13 +2659,13 @@
g_NPP_WriteReady(NPP instance, NPStream *stream)
{
if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
+ return 0;
if (plugin_funcs.writeready == NULL)
- return NPERR_INVALID_FUNCTABLE_ERROR;
+ return 0;
if (stream == NULL)
- return NPERR_INVALID_PARAM;
+ return 0;
D(bug("NPP_WriteReady instance=%p, stream=%p\n", instance, stream));
int32 ret = plugin_funcs.writeready(instance, stream);
@@ -3086,7 +3091,7 @@
if (g_user_agent)
free(g_user_agent);
if (g_rpc_connection)
- rpc_exit(g_rpc_connection);
+ rpc_connection_unref(g_rpc_connection);
id_kill();
return 0;
Index: src/npw-wrapper.c
===================================================================
--- src/npw-wrapper.c (révision 466)
+++ src/npw-wrapper.c (révision 470)
@@ -21,6 +21,7 @@
#define _GNU_SOURCE 1 /* RTLD_DEFAULT */
#include "sysdeps.h"
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -73,6 +74,9 @@
// Netscape exported functions
static NPNetscapeFuncs mozilla_funcs;
+// NPAPI version nspluginwrapper supports
+static int npapi_version = 0;
+
// Wrapper plugin data
typedef struct {
int initialized;
@@ -89,6 +93,7 @@
typedef struct _PluginInstance {
NPP instance;
uint32_t instance_id;
+ rpc_connection_t *connection;
} PluginInstance;
// Plugin side data for an NPStream instance
@@ -101,7 +106,38 @@
// Prototypes
static void plugin_init(int is_NP_Initialize);
static void plugin_exit(void);
+static NPError plugin_restart_if_needed(void);
+/*
+ * Notes concerning NSPluginWrapper recovery model.
+ *
+ * NSPluginWrapper will restart the Viewer if it detected to be
+ * dead. It will not attempt to "replay" the plugin. This means that
+ * if a plugin crashed, its window will remain grayed: only new
+ * instances will start a new viewer.
+ *
+ * Each PlugInstance holds a reference to the RPC connection it was
+ * created with. g_rpc_connection can be seen as the "master"
+ * connection (used to initialize and shutdown things). The RPC
+ * connections are reference counted so that when the master
+ * connection is set to a new one, previous connections are still
+ * live. That way, old NPP instances are not passed down with the new
+ * 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)?
+ */
+
+// Minimal time between two plugin restarts in sec
+#define MIN_RESTART_INTERVAL 1
+
+// Consume as many bytes as possible when we are not NPP_WriteReady()
+// XXX: move to a common place to Wrapper and Viewer
+#define NPERR_STREAM_BUFSIZ 65536
+
// Helpers
#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
@@ -110,7 +146,16 @@
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif
+#define PLUGIN_INSTANCE(INSTANCE) plugin_instance(INSTANCE)
+static inline PluginInstance *plugin_instance(NPP instance)
+{
+ PluginInstance *plugin = (PluginInstance *)instance->pdata;
+ assert(plugin->instance == instance);
+ return plugin;
+}
+
+
/* ====================================================================== */
/* === RPC communication === */
/* ====================================================================== */
@@ -1177,13 +1222,13 @@
// Creates a new instance of a plug-in
static NPError
-invoke_NPP_New(NPMIMEType mime_type, NPP instance,
+invoke_NPP_New(PluginInstance *plugin, NPMIMEType mime_type,
uint16_t mode, int16_t argc, char *argn[], char *argv[],
NPSavedData *saved)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_NEW,
- RPC_TYPE_UINT32, ((PluginInstance *)instance->pdata)->instance_id,
+ RPC_TYPE_UINT32, plugin->instance_id,
RPC_TYPE_STRING, mime_type,
RPC_TYPE_INT32, (int32_t)mode,
RPC_TYPE_ARRAY, RPC_TYPE_STRING, (uint32_t)argc, argn,
@@ -1197,7 +1242,7 @@
}
int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
@@ -1216,17 +1261,25 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
-
+
+ // Check if we need to restart the plug-in
+ NPError ret = plugin_restart_if_needed();
+ if (ret != NPERR_NO_ERROR)
+ return ret;
+
PluginInstance *plugin = malloc(sizeof(*plugin));
if (plugin == NULL)
return NPERR_OUT_OF_MEMORY_ERROR;
memset(plugin, 0, sizeof(*plugin));
plugin->instance = instance;
plugin->instance_id = id_create(plugin);
+ plugin->connection = g_rpc_connection;
instance->pdata = plugin;
+ rpc_connection_ref(plugin->connection);
+
D(bug("NPP_New instance=%p\n", instance));
- NPError ret = invoke_NPP_New(mime_type, instance, mode, argc, argn, argv, saved);
+ ret = invoke_NPP_New(plugin, mime_type, mode, argc, argn, argv, saved);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
if (saved) {
@@ -1240,11 +1293,11 @@
// Deletes a specific instance of a plug-in
static NPError
-invoke_NPP_Destroy(NPP instance, NPSavedData **save)
+invoke_NPP_Destroy(PluginInstance *plugin, NPSavedData **save)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_DESTROY,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
@@ -1254,7 +1307,7 @@
int32_t ret;
NPSavedData *save_area = NULL;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_NP_SAVED_DATA, &save_area,
RPC_TYPE_INVALID);
@@ -1280,28 +1333,29 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
D(bug("NPP_Destroy instance=%p\n", instance));
- NPError ret = invoke_NPP_Destroy(instance, save);
+ NPError ret = invoke_NPP_Destroy(plugin, save);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
- PluginInstance *plugin = instance->pdata;
- if (plugin) {
- id_remove(plugin->instance_id);
- free(plugin);
- instance->pdata = NULL;
- }
+ rpc_connection_unref(plugin->connection);
+ id_remove(plugin->instance_id);
+ free(plugin);
+ instance->pdata = NULL;
return ret;
}
// Tells the plug-in when a window is created, moved, sized, or destroyed
static NPError
-invoke_NPP_SetWindow(NPP instance, NPWindow *window)
+invoke_NPP_SetWindow(PluginInstance *plugin, NPWindow *window)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_SET_WINDOW,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_NP_WINDOW, window,
RPC_TYPE_INVALID);
@@ -1311,7 +1365,7 @@
}
int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
@@ -1328,20 +1382,23 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
D(bug("NPP_SetWindow instance=%p\n", instance));
- NPError ret = invoke_NPP_SetWindow(instance, window);
+ NPError ret = invoke_NPP_SetWindow(plugin, window);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
return ret;
}
// Allows the browser to query the plug-in for information
static NPError
-invoke_NPP_GetValue(NPP instance, NPPVariable variable, void *value)
+invoke_NPP_GetValue(PluginInstance *plugin, NPPVariable variable, void *value)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_GET_VALUE,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_INT32, variable,
RPC_TYPE_INVALID);
@@ -1355,7 +1412,7 @@
case RPC_TYPE_STRING:
{
char *str = NULL;
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INT32, &ret, RPC_TYPE_STRING, &str, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetValue() wait for reply", error);
ret = NPERR_GENERIC_ERROR;
@@ -1384,7 +1441,7 @@
case RPC_TYPE_INT32:
{
int32_t n = 0;
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_INT32, &n, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INT32, &ret, RPC_TYPE_INT32, &n, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetValue() wait for reply", error);
ret = NPERR_GENERIC_ERROR;
@@ -1396,7 +1453,7 @@
case RPC_TYPE_BOOLEAN:
{
uint32_t b = 0;
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_BOOLEAN, &b, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INT32, &ret, RPC_TYPE_BOOLEAN, &b, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetValue() wait for reply", error);
ret = NPERR_GENERIC_ERROR;
@@ -1408,7 +1465,7 @@
case RPC_TYPE_NP_OBJECT:
{
NPObject *npobj = NULL;
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_NP_OBJECT, &npobj, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INT32, &ret, RPC_TYPE_NP_OBJECT, &npobj, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetValue() wait for reply", error);
ret = NPERR_GENERIC_ERROR;
@@ -1427,6 +1484,9 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
switch (rpc_type_of_NPPVariable(variable)) {
case RPC_TYPE_STRING:
@@ -1440,14 +1500,14 @@
}
D(bug("NPP_GetValue instance=%p, variable=%d\n", instance, variable));
- NPError ret = invoke_NPP_GetValue(instance, variable, value);
+ NPError ret = invoke_NPP_GetValue(plugin, variable, value);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
return ret;
}
// Sets information about the plug-in
static NPError
-invoke_NPP_SetValue(NPP instance, NPPVariable variable, void *value)
+invoke_NPP_SetValue(PluginInstance *plugin, NPPVariable variable, void *value)
{
UNIMPLEMENTED();
@@ -1459,20 +1519,23 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
D(bug("NPP_SetValue instance=%p, variable=%d\n", instance, variable));
- NPError ret = invoke_NPP_SetValue(instance, variable, value);
+ NPError ret = invoke_NPP_SetValue(plugin, variable, value);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
return NPERR_GENERIC_ERROR;
}
// Notifies the instance of the completion of a URL request
static void
-invoke_NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
+invoke_NPP_URLNotify(PluginInstance *plugin, const char *url, NPReason reason, void *notifyData)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_URL_NOTIFY,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_STRING, url,
RPC_TYPE_INT32, reason,
RPC_TYPE_NP_NOTIFY_DATA, notifyData,
@@ -1483,7 +1546,7 @@
return;
}
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR)
npw_perror("NPP_URLNotify() wait for reply", error);
@@ -1494,19 +1557,22 @@
{
if (instance == NULL)
return;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return;
D(bug("NPP_URLNotify instance=%p, url='%s', reason=%d, notifyData=%p\n", instance, url, reason, notifyData));
- invoke_NPP_URLNotify(instance, url, reason, notifyData);
+ invoke_NPP_URLNotify(plugin, url, reason, notifyData);
D(bug(" done\n"));
}
// Notifies a plug-in instance of a new data stream
static NPError
-invoke_NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
+invoke_NPP_NewStream(PluginInstance *plugin, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_NEW_STREAM,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_STRING, type,
RPC_TYPE_UINT32, ((StreamInstance *)stream->pdata)->stream_id,
RPC_TYPE_STRING, stream->url,
@@ -1524,7 +1590,7 @@
int32_t ret;
uint32_t r_stype;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_UINT32, &r_stype,
RPC_TYPE_NP_NOTIFY_DATA, &stream->notifyData,
@@ -1544,6 +1610,9 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
StreamInstance *stream_pdata = malloc(sizeof(*stream_pdata));
if (stream_pdata == NULL)
@@ -1555,18 +1624,18 @@
stream->pdata = stream_pdata;
D(bug("NPP_NewStream instance=%p\n", instance));
- NPError ret = invoke_NPP_NewStream(instance, type, stream, seekable, stype);
+ NPError ret = invoke_NPP_NewStream(plugin, type, stream, seekable, stype);
D(bug(" return: %d [%s], stype=%s\n", ret, string_of_NPError(ret), string_of_NPStreamType(*stype)));
return ret;
}
// Tells the plug-in that a stream is about to be closed or destroyed
static NPError
-invoke_NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
+invoke_NPP_DestroyStream(PluginInstance *plugin, NPStream *stream, NPReason reason)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_DESTROY_STREAM,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_NP_STREAM, stream,
RPC_TYPE_INT32, reason,
RPC_TYPE_INVALID);
@@ -1577,7 +1646,7 @@
}
int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
@@ -1594,9 +1663,12 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
D(bug("NPP_DestroyStream instance=%p\n", instance));
- NPError ret = invoke_NPP_DestroyStream(instance, stream, reason);
+ NPError ret = invoke_NPP_DestroyStream(plugin, stream, reason);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
StreamInstance *stream_pdata = stream->pdata;
@@ -1611,11 +1683,11 @@
// Provides a local file name for the data from a stream
static void
-invoke_NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
+invoke_NPP_StreamAsFile(PluginInstance *plugin, NPStream *stream, const char *fname)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_STREAM_AS_FILE,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_NP_STREAM, stream,
RPC_TYPE_STRING, fname,
RPC_TYPE_INVALID);
@@ -1625,7 +1697,7 @@
return;
}
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INVALID);
+ error = rpc_method_wait_for_reply(plugin->connection, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR)
npw_perror("NPP_StreamAsFile() wait for reply", error);
@@ -1636,35 +1708,38 @@
{
if (instance == NULL)
return;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return;
D(bug("NPP_StreamAsFile instance=%p\n", instance));
- invoke_NPP_StreamAsFile(instance, stream, fname);
+ invoke_NPP_StreamAsFile(plugin, stream, fname);
D(bug(" done\n"));
}
// Determines maximum number of bytes that the plug-in can consume
static int32
-invoke_NPP_WriteReady(NPP instance, NPStream *stream)
+invoke_NPP_WriteReady(PluginInstance *plugin, NPStream *stream)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_WRITE_READY,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_NP_STREAM, stream,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_WriteReady() invoke", error);
- return 0;
+ return NPERR_STREAM_BUFSIZ;
}
int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_WriteReady() wait for reply", error);
- return 0;
+ return NPERR_STREAM_BUFSIZ;
}
return ret;
@@ -1674,10 +1749,13 @@
g_NPP_WriteReady(NPP instance, NPStream *stream)
{
if (instance == NULL)
- return -1;
+ return 0;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return 0;
D(bug("NPP_WriteReady instance=%p\n", instance));
- int32 ret = invoke_NPP_WriteReady(instance, stream);
+ int32 ret = invoke_NPP_WriteReady(plugin, stream);
D(bug(" return: %d\n", ret));
return ret;
}
@@ -1685,11 +1763,11 @@
// Delivers data to a plug-in instance
static int32
-invoke_NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buf)
+invoke_NPP_Write(PluginInstance *plugin, NPStream *stream, int32 offset, int32 len, void *buf)
{
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_WRITE,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_NP_STREAM, stream,
RPC_TYPE_INT32, offset,
RPC_TYPE_ARRAY, RPC_TYPE_CHAR, len, buf,
@@ -1701,7 +1779,7 @@
}
int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
@@ -1718,16 +1796,19 @@
{
if (instance == NULL)
return -1;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return -1;
D(bug("NPP_Write instance=%p\n", instance));
- int32 ret = invoke_NPP_Write(instance, stream, offset, len, buf);
+ int32 ret = invoke_NPP_Write(plugin, stream, offset, len, buf);
D(bug(" return: %d\n", ret));
return ret;
}
// Requests a platform-specific print operation for an embedded or full-screen plug-in
-static void invoke_NPP_Print(NPP instance, NPPrint *PrintInfo)
+static void invoke_NPP_Print(PluginInstance *plugin, NPPrint *PrintInfo)
{
NPPrintCallbackStruct *platformPrint;
switch (PrintInfo->mode) {
@@ -1746,9 +1827,9 @@
platform_print_id = id_create(platformPrint);
D(bug(" platformPrint=%p\n", platformPrint));
- int error = rpc_method_invoke(g_rpc_connection,
+ int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_PRINT,
- RPC_TYPE_NPP, instance,
+ RPC_TYPE_NPP, plugin->instance,
RPC_TYPE_UINT32, platform_print_id,
RPC_TYPE_NP_PRINT, PrintInfo,
RPC_TYPE_INVALID);
@@ -1759,7 +1840,7 @@
}
uint32_t pluginPrinted;
- error = rpc_method_wait_for_reply(g_rpc_connection,
+ error = rpc_method_wait_for_reply(plugin->connection,
RPC_TYPE_BOOLEAN, &pluginPrinted,
RPC_TYPE_INVALID);
@@ -1780,17 +1861,20 @@
{
if (instance == NULL)
return;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return;
if (PrintInfo == NULL)
return;
D(bug("NPP_Print instance=%p\n", instance));
- invoke_NPP_Print(instance, PrintInfo);
+ invoke_NPP_Print(plugin, PrintInfo);
D(bug(" done\n"));
}
// Delivers a platform-specific window event to the instance
-static int16 invoke_NPP_HandleEvent(NPP instance, void *event)
+static int16 invoke_NPP_HandleEvent(PluginInstance *plugin, void *event)
{
UNIMPLEMENTED();
@@ -1801,9 +1885,12 @@
{
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginInstance *plugin = PLUGIN_INSTANCE(instance);
+ if (plugin == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
D(bug("NPP_HandleEvent instance=%p\n", instance));
- int16 ret = invoke_NPP_HandleEvent(instance, event);
+ int16 ret = invoke_NPP_HandleEvent(plugin, event);
D(bug(" return: ret\n", ret));
return ret;
}
@@ -2206,10 +2293,10 @@
g_LONG64_NPP_WriteReady(NPP instance, void *stream)
{
if (instance == NULL)
- return -1L;
+ return 0;
if (stream == NULL)
- return -1L;
+ return 0;
return (int64)(int32)g_NPP_WriteReady(instance, NP_STREAM32(stream));
}
@@ -2310,6 +2397,30 @@
}
// Provides global initialization for a plug-in
+static NPError
+invoke_NP_Initialize(uint32_t npapi_version)
+{
+ int error = rpc_method_invoke(g_rpc_connection,
+ RPC_METHOD_NP_INITIALIZE,
+ RPC_TYPE_UINT32, npapi_version,
+ RPC_TYPE_INVALID);
+
+ if (error != RPC_ERROR_NO_ERROR) {
+ npw_perror("NP_Initialize() invoke", error);
+ return NPERR_MODULE_LOAD_FAILED_ERROR;
+ }
+
+ int32_t ret;
+ error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_INVALID);
+
+ if (error != RPC_ERROR_NO_ERROR) {
+ npw_perror("NP_Initialize() wait for reply", error);
+ return NPERR_MODULE_LOAD_FAILED_ERROR;
+ }
+
+ return ret;
+}
+
NPError
NP_Initialize(NPNetscapeFuncs *moz_funcs, NPPluginFuncs *plugin_funcs)
{
@@ -2374,26 +2485,9 @@
// pass down common NPAPI version supported by both the underlying
// browser and the thunking capabilities of nspluginwrapper
- uint32_t version = min(moz_funcs->version, plugin_funcs->version);
+ npapi_version = min(moz_funcs->version, plugin_funcs->version);
- int error = rpc_method_invoke(g_rpc_connection,
- RPC_METHOD_NP_INITIALIZE,
- RPC_TYPE_UINT32, (uint32_t)version,
- RPC_TYPE_INVALID);
-
- if (error != RPC_ERROR_NO_ERROR) {
- npw_perror("NP_Initialize() invoke", error);
- return NPERR_MODULE_LOAD_FAILED_ERROR;
- }
-
- int32_t ret;
- error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_INVALID);
-
- if (error != RPC_ERROR_NO_ERROR) {
- npw_perror("NP_Initialize() wait for reply", error);
- return NPERR_MODULE_LOAD_FAILED_ERROR;
- }
-
+ NPError ret = invoke_NP_Initialize(npapi_version);
D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
return ret;
}
@@ -2657,7 +2751,7 @@
}
if (g_rpc_connection) {
- rpc_exit(g_rpc_connection);
+ rpc_connection_unref(g_rpc_connection);
g_rpc_connection = NULL;
}
@@ -2708,3 +2802,40 @@
g_plugin.description = NULL;
}
}
+
+static NPError plugin_restart(void)
+{
+ if (g_plugin.is_wrapper)
+ return NPERR_NO_ERROR;
+
+ // Shut it down
+ plugin_exit();
+ g_plugin.initialized = 0;
+ g_plugin.viewer_pid = -1;
+ g_plugin.is_wrapper = 0;
+
+ // And start it again
+ plugin_init(1);
+ if (g_plugin.initialized <= 0)
+ return NPERR_MODULE_LOAD_FAILED_ERROR;
+
+ return invoke_NP_Initialize(npapi_version);
+}
+
+static NPError plugin_restart_if_needed(void)
+{
+ if (rpc_status(g_rpc_connection) != RPC_STATUS_ACTIVE) {
+ static time_t last_restart = 0;
+ time_t now = time(NULL);
+ if (now - last_restart < MIN_RESTART_INTERVAL)
+ return NPERR_GENERIC_ERROR;
+ last_restart = now;
+
+ D(bug("Restart plugins viewer\n"));
+ NPError ret = plugin_restart();
+ D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
+ return ret;
+ }
+
+ return NPERR_NO_ERROR;
+}
Index: src/rpc.c
===================================================================
--- src/rpc.c (révision 466)
+++ src/rpc.c (révision 470)
@@ -289,6 +289,7 @@
// Client / Server connection
struct rpc_connection_t {
int type;
+ int refcnt;
int status;
int socket;
char *socket_path;
@@ -301,6 +302,22 @@
char send_buffer[BUFSIZ];
};
+// Increment connection reference count
+void rpc_connection_ref(rpc_connection_t *connection)
+{
+ if (connection)
+ ++connection->refcnt;
+}
+
+// Decrement connection reference count and destroy it if it reaches zero
+void rpc_connection_unref(rpc_connection_t *connection)
+{
+ if (connection && --connection->refcnt == 0) {
+ D(bug("Close unused connection\n"));
+ rpc_exit(connection);
+ }
+}
+
// Returns connection status
static inline int _rpc_status(rpc_connection_t *connection)
{
@@ -417,6 +434,7 @@
if (connection == NULL)
return NULL;
connection->type = RPC_CONNECTION_SERVER;
+ connection->refcnt = 1;
connection->status = RPC_STATUS_CLOSED;
connection->socket = -1;
connection->server_thread_active = 0;
@@ -468,6 +486,7 @@
if (connection == NULL)
return NULL;
connection->type = RPC_CONNECTION_CLIENT;
+ connection->refcnt = 1;
connection->status = RPC_STATUS_CLOSED;
connection->server_socket = -1;
connection->callbacks = NULL;
Index: src/rpc.h
===================================================================
--- src/rpc.h (révision 466)
+++ src/rpc.h (révision 470)
@@ -42,6 +42,9 @@
// Connection Handling
typedef struct rpc_connection_t rpc_connection_t;
+extern void rpc_connection_ref(rpc_connection_t *connection) attribute_hidden;
+extern void rpc_connection_unref(rpc_connection_t *connection) attribute_hidden;
+
extern rpc_connection_t *rpc_init_server(const char *ident) attribute_hidden;
extern rpc_connection_t *rpc_init_client(const char *ident) attribute_hidden;
extern int rpc_exit(rpc_connection_t *connection) attribute_hidden;
Index: NEWS
===================================================================
--- NEWS (révision 466)
+++ NEWS (révision 470)
@@ -1,6 +1,9 @@
-nspluginwrapper NEWS -- history of user-visible changes. 2007-08-26
+nspluginwrapper NEWS -- history of user-visible changes. 2007-MM-DD
Copyright (C) 2005-2007 Gwenole Beauchesne
+Version 0.9.92 (BETA) - DD.MMM.2007
+* Restart plugins viewer on error (Martin Stransky)
+
Version 0.9.91.5 (BETA) - 26.Aug.2007
* Fix a memory leak in NPP_Destroy()
* Fix DiamondX XEmbed example plugin
nspluginwrapper-0.9.91.5-rpc-error.patch:
--- NEW FILE nspluginwrapper-0.9.91.5-rpc-error.patch ---
Index: src/rpc.c
===================================================================
--- src/rpc.c (révision 460)
+++ src/rpc.c (révision 466)
@@ -29,6 +29,7 @@
#include "sysdeps.h"
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
@@ -288,6 +289,7 @@
// Client / Server connection
struct rpc_connection_t {
int type;
+ int status;
int socket;
char *socket_path;
int server_socket;
@@ -299,6 +301,47 @@
char send_buffer[BUFSIZ];
};
+// Returns connection status
+static inline int _rpc_status(rpc_connection_t *connection)
+{
+ return connection->status;
+}
+
+int rpc_status(rpc_connection_t *connection)
+{
+ if (connection == NULL)
+ return RPC_STATUS_BROKEN;
+ return _rpc_status(connection);
+}
+
+// Set connection status
+static void _rpc_set_status(rpc_connection_t *connection, int error)
+{
+ if (connection->status == RPC_STATUS_ACTIVE) {
+ switch (error) {
+ case RPC_ERROR_NO_ERROR:
+ connection->status = RPC_STATUS_ACTIVE;
+ break;
+ case RPC_ERROR_CONNECTION_CLOSED:
+ connection->status = RPC_STATUS_CLOSED;
+ break;
+ default:
+ connection->status = RPC_STATUS_BROKEN;
+ break;
+ }
+ }
+}
+
+static inline int rpc_error(rpc_connection_t *connection, int error)
+{
+ // XXX: this function must be called only in case of error
+ // (otherwise, it's an internal error)
+ assert(error < 0);
+ assert(connection != NULL);
+ _rpc_set_status(connection, error);
+ return error;
+}
+
// Returns socket fd or -1 if invalid connection
int rpc_socket(rpc_connection_t *connection)
{
@@ -374,6 +417,7 @@
if (connection == NULL)
return NULL;
connection->type = RPC_CONNECTION_SERVER;
+ connection->status = RPC_STATUS_CLOSED;
connection->socket = -1;
connection->server_thread_active = 0;
connection->callbacks = NULL;
@@ -404,6 +448,7 @@
return NULL;
}
+ connection->status = RPC_STATUS_ACTIVE;
return connection;
}
@@ -423,6 +468,7 @@
if (connection == NULL)
return NULL;
connection->type = RPC_CONNECTION_CLIENT;
+ connection->status = RPC_STATUS_CLOSED;
connection->server_socket = -1;
connection->callbacks = NULL;
connection->n_callbacks = 0;
@@ -467,6 +513,7 @@
return NULL;
}
+ connection->status = RPC_STATUS_ACTIVE;
return connection;
}
@@ -1334,11 +1381,14 @@
int32_t msg_tag;
int error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_START)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
- return _rpc_dispatch(connection, &message);
+ int method = _rpc_dispatch(connection, &message);
+ if (method < 0)
+ return rpc_error(connection, method);
+ return method;
}
@@ -1443,6 +1493,8 @@
if (connection == NULL)
return RPC_ERROR_CONNECTION_NULL;
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
+ return RPC_ERROR_CONNECTION_CLOSED;
rpc_message_t message;
rpc_message_init(&message, connection);
@@ -1459,24 +1511,24 @@
// send: <invoke> = MESSAGE_START <method-id> MESSAGE_END
int error = rpc_message_send_int32(&message, RPC_MESSAGE_START);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_send_int32(&message, method);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
// wait: MESSAGE_ACK
int32_t msg_tag;
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
// send optional arguments
va_list args;
@@ -1490,19 +1542,19 @@
error = rpc_message_send_args(&message, args);
va_end(args);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
// wait: MESSAGE_ACK
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
}
-
+
return RPC_ERROR_NO_ERROR;
}
@@ -1513,6 +1565,8 @@
if (connection == NULL)
return RPC_ERROR_CONNECTION_NULL;
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
+ return RPC_ERROR_CONNECTION_CLOSED;
rpc_message_t message;
rpc_message_init(&message, connection);
@@ -1523,15 +1577,15 @@
int error = rpc_message_recv_args(&message, args);
va_end(args);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
// send: MESSAGE_ACK
error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
return RPC_ERROR_NO_ERROR;
}
@@ -1547,6 +1601,8 @@
if (connection == NULL)
return RPC_ERROR_CONNECTION_NULL;
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
+ return RPC_ERROR_CONNECTION_CLOSED;
rpc_message_init(&message, connection);
va_start(args, connection);
@@ -1559,11 +1615,11 @@
while (!done) {
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
switch (msg_tag) {
case RPC_MESSAGE_START:
if ((error = _rpc_dispatch(connection, &message)) < 0)
- return error;
+ return rpc_error(connection, error);
break;
case RPC_MESSAGE_REPLY:
case RPC_MESSAGE_ACK:
@@ -1575,11 +1631,12 @@
int32_t error_code;
error = rpc_message_recv_int32(&message, &error_code);
if (error != RPC_ERROR_NO_ERROR)
- return error;
- return error_code;
+ return rpc_error(connection, error);
+ // return other-side error code
+ return rpc_error(connection, error_code);
}
default:
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
}
}
@@ -1587,35 +1644,35 @@
// wait: <reply>
if (msg_tag != RPC_MESSAGE_REPLY)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
va_start(args, connection);
error = rpc_message_recv_args(&message, args);
va_end(args);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_END)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
// send: MESSAGE_ACK
error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
// wait: MESSAGE_ACK (prepare for final ACK)
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
}
// wait: MESSAGE_ACK
if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
return RPC_ERROR_NO_ERROR;
}
@@ -1626,7 +1683,9 @@
D(bug("rpc_method_send_reply\n"));
if (connection == NULL)
- return RPC_ERROR_GENERIC;
+ return RPC_ERROR_CONNECTION_NULL;
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
+ return RPC_ERROR_CONNECTION_CLOSED;
rpc_message_t message;
rpc_message_init(&message, connection);
@@ -1634,27 +1693,27 @@
// send: <reply> = MESSAGE_REPLY [ <method-args> ] MESSAGE_END
int error = rpc_message_send_int32(&message, RPC_MESSAGE_REPLY);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
va_list args;
va_start(args, connection);
error = rpc_message_send_args(&message, args);
va_end(args);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
// wait: MESSAGE_ACK
int32_t msg_tag;
error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
- return error;
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
return RPC_ERROR_NO_ERROR;
}
Index: src/rpc.h
===================================================================
--- src/rpc.h (révision 460)
+++ src/rpc.h (révision 466)
@@ -51,6 +51,13 @@
extern int rpc_wait_dispatch(rpc_connection_t *connection, int timeout) attribute_hidden;
extern int rpc_socket(rpc_connection_t *connection) attribute_hidden;
+enum {
+ RPC_STATUS_BROKEN = -1,
+ RPC_STATUS_CLOSED = 0,
+ RPC_STATUS_ACTIVE = 1,
+};
+extern int rpc_status(rpc_connection_t *connection) attribute_hidden;
+
// Message Passing
enum {
RPC_TYPE_INVALID = 0,
nspluginwrapper-0.9.91.5-rh.patch:
Index: nspluginwrapper-0.9.91.5-rh.patch
===================================================================
RCS file: /cvs/pkgs/rpms/nspluginwrapper/devel/nspluginwrapper-0.9.91.5-rh.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- nspluginwrapper-0.9.91.5-rh.patch 28 Aug 2007 11:12:58 -0000 1.1
+++ nspluginwrapper-0.9.91.5-rh.patch 10 Sep 2007 08:44:43 -0000 1.2
@@ -643,28 +643,6 @@
#include "utils.h"
#define XP_UNIX 1
-@@ -85,6 +86,8 @@ typedef struct {
-
- static Plugin g_plugin = { 0, -1, 0, NULL, NULL, NULL };
-
-+static uint32_t version = 0;
-+
- // Instance state information about the plugin
- typedef struct _PluginInstance {
- NPP instance;
-@@ -101,6 +104,12 @@ typedef struct _StreamInstance {
- // Prototypes
- static void plugin_init(int is_NP_Initialize);
- static void plugin_exit(void);
-+static NPError plugin_restart(void);
-+static NPError check_restart(void);
-+static time_t last_restart = 0;
-+
-+// Minimal time between two plugin restarts in sec
-+#define RESTART_INTERVAL 1
-
- // Helpers
- #ifndef min
@@ -211,7 +220,7 @@ g_NPN_GetValue(NPP instance, NPNVariable
if (mozilla_funcs.getvalue == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
@@ -682,20 +660,6 @@
abort();
}
-@@ -1216,7 +1226,12 @@ g_NPP_New(NPMIMEType mime_type, NPP inst
- {
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
--
-+
-+ // Check if we need to restart the plug-in
-+ NPError rt = check_restart();
-+ if(rt != NPERR_NO_ERROR)
-+ return(rt);
-+
- PluginInstance *plugin = malloc(sizeof(*plugin));
- if (plugin == NULL)
- return NPERR_OUT_OF_MEMORY_ERROR;
@@ -1485,8 +1500,9 @@ invoke_NPP_URLNotify(NPP instance, const
error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INVALID);
@@ -707,15 +671,6 @@
}
static void
-@@ -2374,7 +2390,7 @@ NP_Initialize(NPNetscapeFuncs *moz_funcs
-
- // pass down common NPAPI version supported by both the underlying
- // browser and the thunking capabilities of nspluginwrapper
-- uint32_t version = min(moz_funcs->version, plugin_funcs->version);
-+ version = min(moz_funcs->version, plugin_funcs->version);
-
- int error = rpc_method_invoke(g_rpc_connection,
- RPC_METHOD_NP_INITIALIZE,
@@ -2467,9 +2483,9 @@ static void plugin_init(int is_NP_Initia
static int init_count = 0;
++init_count;
@@ -728,71 +683,6 @@
// Cache MIME info and plugin name/description
if (g_plugin.name == NULL && g_plugin.description == NULL && g_plugin.formats == NULL) {
-@@ -2708,3 +2724,64 @@ static void __attribute__((destructor))
- g_plugin.description = NULL;
- }
- }
-+
-+static NPError plugin_restart(void)
-+{
-+ if(!g_plugin.is_wrapper) {
-+ D(bug("plugin restart\n"));
-+
-+ // Shut it down
-+ plugin_exit();
-+
-+ g_plugin.initialized = 0;
-+ g_plugin.viewer_pid = -1;
-+ g_plugin.is_wrapper = 0;
-+
-+ // And start it again
-+ plugin_init(1);
-+ if (g_plugin.initialized <= 0)
-+ return NPERR_MODULE_LOAD_FAILED_ERROR;
-+
-+ int error = rpc_method_invoke(g_rpc_connection,
-+ RPC_METHOD_NP_INITIALIZE,
-+ RPC_TYPE_UINT32, (uint32_t)version,
-+ RPC_TYPE_INVALID);
-+
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ npw_perror("NP_Initialize() invoke", error);
-+ return NPERR_MODULE_LOAD_FAILED_ERROR;
-+ }
-+
-+ int32_t ret;
-+ error = rpc_method_wait_for_reply(g_rpc_connection, RPC_TYPE_INT32, &ret, RPC_TYPE_INVALID);
-+
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ npw_perror("NP_Initialize() wait for reply", error);
-+ return NPERR_MODULE_LOAD_FAILED_ERROR;
-+ }
-+
-+ D(bug(" return: %d [%s]\n", ret, string_of_NPError(ret)));
-+ return ret;
-+ }
-+ return NPERR_NO_ERROR;
-+}
-+
-+static NPError check_restart(void)
-+{
-+ if(rpc_status_get(g_rpc_connection)) {
-+
-+ time_t atime = time(NULL);
-+ if(atime - last_restart < RESTART_INTERVAL)
-+ return(NPERR_GENERIC_ERROR);
-+ last_restart = atime;
-+
-+ D(bug("Plugin restart\n"));
-+ int ret = plugin_restart();
-+ if(ret == NPERR_NO_ERROR) {
-+ rpc_error_clear(g_rpc_connection);
-+ }
-+ D(bug("check_restart return %d [%s]\n", ret, string_of_NPError(ret)));
-+ return(ret);
-+ }
-+ return(NPERR_NO_ERROR);
-+}
--- /dev/null 2007-08-28 09:06:54.719628589 +0200
+++ nspluginwrapper-0.9.91.5/src/npw-dir.c 2007-08-28 11:10:19.000000000 +0200
@@ -0,0 +1,97 @@
@@ -1405,326 +1295,3 @@
}
return 0;
---- nspluginwrapper-0.9.91.5/src/rpc.h.rh 2007-03-04 16:01:22.000000000 +0100
-+++ nspluginwrapper-0.9.91.5/src/rpc.h 2007-08-28 11:10:19.000000000 +0200
-@@ -103,4 +103,11 @@ extern int rpc_method_wait_for_reply(rpc
- extern int rpc_method_get_args(rpc_connection_t *connection, ...) attribute_hidden;
- extern int rpc_method_send_reply(rpc_connection_t *connection, ...) attribute_hidden;
-
-+// Error handling
-+void rpc_error_check(rpc_connection_t *connection, int err_code);
-+int rpc_error_get(rpc_connection_t *connection);
-+void rpc_error_set(rpc_connection_t *connection);
-+void rpc_error_clear(rpc_connection_t *connection);
-+int rpc_status_get(rpc_connection_t *connection);
-+
- #endif /* RPC_H */
---- nspluginwrapper-0.9.91.5/src/rpc.c.rh 2007-04-02 22:03:07.000000000 +0200
-+++ nspluginwrapper-0.9.91.5/src/rpc.c 2007-08-28 11:10:19.000000000 +0200
-@@ -232,6 +232,7 @@ const char *rpc_strerror(int error)
- return str;
- }
-
-+
- // Set non blocking I/O on the specified socket
- static int rpc_set_non_blocking_io(int socket)
- {
-@@ -293,12 +294,41 @@ struct rpc_connection_t {
- int server_socket;
- int server_thread_active;
- pthread_t server_thread;
-+ int last_error;
- rpc_method_descriptor_t *callbacks;
- int n_callbacks;
- int send_offset;
- char send_buffer[BUFSIZ];
- };
-
-+#define ERROR_RPC(error) ((error) > -1100 && (error) <= -1000)
-+
-+void rpc_error_check(rpc_connection_t *connection, int err_code)
-+{
-+ if(ERROR_RPC(err_code))
-+ connection->last_error = err_code;
-+}
-+
-+int rpc_error_get(rpc_connection_t *connection)
-+{
-+ return(connection->last_error);
-+}
-+
-+void rpc_error_set(rpc_connection_t *connection)
-+{
-+ connection->last_error = RPC_ERROR_GENERIC;
-+}
-+
-+void rpc_error_clear(rpc_connection_t *connection)
-+{
-+ connection->last_error = 0;
-+}
-+
-+int rpc_status_get(rpc_connection_t *connection)
-+{
-+ return(ERROR_RPC(connection->last_error));
-+}
-+
- // Returns socket fd or -1 if invalid connection
- int rpc_socket(rpc_connection_t *connection)
- {
-@@ -378,6 +408,7 @@ rpc_connection_t *rpc_init_server(const
- connection->server_thread_active = 0;
- connection->callbacks = NULL;
- connection->n_callbacks = 0;
-+ connection->last_error = 0;
-
- if ((connection->server_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- perror("server socket");
-@@ -426,6 +457,7 @@ rpc_connection_t *rpc_init_client(const
- connection->server_socket = -1;
- connection->callbacks = NULL;
- connection->n_callbacks = 0;
-+ connection->last_error = 0;
-
- if ((connection->socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- perror("client socket");
-@@ -1441,8 +1473,9 @@ int rpc_method_invoke(rpc_connection_t *
- {
- D(bug("rpc_method_invoke method=%d\n", method));
-
-- if (connection == NULL)
-+ if (connection == NULL) {
- return RPC_ERROR_CONNECTION_NULL;
-+ }
-
- rpc_message_t message;
- rpc_message_init(&message, connection);
-@@ -1452,29 +1485,41 @@ int rpc_method_invoke(rpc_connection_t *
- int ret = _rpc_wait_dispatch(connection, 0);
- if (ret == 0)
- break;
-- if (ret < 0 || (ret = rpc_dispatch(connection)) < 0)
-+ if (ret < 0 || (ret = rpc_dispatch(connection)) < 0) {
-+ rpc_error_check(connection,ret);
- return ret;
-+ }
- }
-
- // send: <invoke> = MESSAGE_START <method-id> MESSAGE_END
- int error = rpc_message_send_int32(&message, RPC_MESSAGE_START);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_send_int32(&message, method);
-- if (error != RPC_ERROR_NO_ERROR)
-- return error;
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
-+ return error;
-+ }
- error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
-- if (error != RPC_ERROR_NO_ERROR)
-- return error;
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
-+ return error;
-+ }
- error = rpc_message_flush(&message);
-- if (error != RPC_ERROR_NO_ERROR)
-- return error;
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
-+ return error;
-+ }
-
- // wait: MESSAGE_ACK
- int32_t msg_tag;
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-- return error;
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
-+ return error;
-+ }
- if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
-
-@@ -1489,16 +1534,22 @@ int rpc_method_invoke(rpc_connection_t *
- va_start(args, method);
- error = rpc_message_send_args(&message, args);
- va_end(args);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_flush(&message);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
-
- // wait: MESSAGE_ACK
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
- }
-@@ -1522,16 +1573,22 @@ int rpc_method_get_args(rpc_connection_t
- va_start(args, connection);
- int error = rpc_message_recv_args(&message, args);
- va_end(args);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
-
- // send: MESSAGE_ACK
- error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_flush(&message);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
-
- return RPC_ERROR_NO_ERROR;
- }
-@@ -1545,8 +1602,9 @@ int rpc_method_wait_for_reply(rpc_connec
- va_list args;
- rpc_message_t message;
-
-- if (connection == NULL)
-+ if (connection == NULL) {
- return RPC_ERROR_CONNECTION_NULL;
-+ }
-
- rpc_message_init(&message, connection);
- va_start(args, connection);
-@@ -1558,12 +1616,16 @@ int rpc_method_wait_for_reply(rpc_connec
- bool done = false;
- while (!done) {
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- switch (msg_tag) {
- case RPC_MESSAGE_START:
-- if ((error = _rpc_dispatch(connection, &message)) < 0)
-+ if ((error = _rpc_dispatch(connection, &message)) < 0) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- break;
- case RPC_MESSAGE_REPLY:
- case RPC_MESSAGE_ACK:
-@@ -1574,8 +1636,10 @@ int rpc_method_wait_for_reply(rpc_connec
- // wait: <error-code>
- int32_t error_code;
- error = rpc_message_recv_int32(&message, &error_code);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- return error_code;
- }
- default:
-@@ -1591,26 +1655,36 @@ int rpc_method_wait_for_reply(rpc_connec
- va_start(args, connection);
- error = rpc_message_recv_args(&message, args);
- va_end(args);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- if (msg_tag != RPC_MESSAGE_END)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
-
- // send: MESSAGE_ACK
- error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_flush(&message);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
-
- // wait: MESSAGE_ACK (prepare for final ACK)
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- }
-
- // wait: MESSAGE_ACK
-@@ -1633,26 +1707,36 @@ int rpc_method_send_reply(rpc_connection
-
- // send: <reply> = MESSAGE_REPLY [ <method-args> ] MESSAGE_END
- int error = rpc_message_send_int32(&message, RPC_MESSAGE_REPLY);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- va_list args;
- va_start(args, connection);
- error = rpc_message_send_args(&message, args);
- va_end(args);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- error = rpc_message_flush(&message);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
-
- // wait: MESSAGE_ACK
- int32_t msg_tag;
- error = rpc_message_recv_int32(&message, &msg_tag);
-- if (error != RPC_ERROR_NO_ERROR)
-+ if (error != RPC_ERROR_NO_ERROR) {
-+ rpc_error_check(connection,error);
- return error;
-+ }
- if (msg_tag != RPC_MESSAGE_ACK)
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
-
Index: nspluginwrapper.spec
===================================================================
RCS file: /cvs/pkgs/rpms/nspluginwrapper/devel/nspluginwrapper.spec,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- nspluginwrapper.spec 28 Aug 2007 11:12:58 -0000 1.16
+++ nspluginwrapper.spec 10 Sep 2007 08:44:43 -0000 1.17
@@ -70,13 +70,15 @@
Summary: A compatibility layer for Netscape 4 plugins
Name: nspluginwrapper
Version: 0.9.91.5
-Release: 1%{?dist}
+Release: 2%{?dist}
Source0: %{name}-%{version}%{?svndate:-%{svndate}}.tar.bz2
Source1: %{plugin_config_name}.tar.gz
Source2: plugin-config.sh.in
Source3: %{name}.sh.in
-Patch0: nspluginwrapper-0.9.91.5-rh.patch
-Patch1: nspluginwrapper-0.9.91.4-config.patch
+Patch0: nspluginwrapper-0.9.91.5-rpc-error.patch
+Patch1: nspluginwrapper-0.9.91.5-restart.patch
+Patch2: nspluginwrapper-0.9.91.5-rh.patch
+Patch3: nspluginwrapper-0.9.91.4-config.patch
License: GPL
Group: Networking/WWW
Url: http://gwenole.beauchesne.info/projects/nspluginwrapper/
@@ -104,8 +106,10 @@
%prep
%setup -q -a 1
-%patch0 -p1 -b .rh
-%patch1 -p1 -b .cnf
+%patch0 -p0
+%patch1 -p0
+%patch2 -p1 -b .rh
+%patch3 -p1 -b .cnf
# remove old/incompatibile stuff
rm -rf npapi
@@ -221,6 +225,9 @@
%{_sysconfdir}/sysconfig/%{name}
%changelog
+* Mon Sep 10 2007 Martin Stransky <stransky at redhat.com> 0.9.91.5-2
+- added upstream patches - RPC error handling and plugin restart
+
* Mon Aug 27 2007 Martin Stransky <stransky at redhat.com> 0.9.91.5-1
- update to the latest upstream
- Previous message (by thread): rpms/hedgewars/F-7 hedgewars-0.9.0-debuginfo.patch, NONE, 1.1 hedgewars.desktop, NONE, 1.1 hedgewars.png, NONE, 1.1 hedgewars.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Next message (by thread): rpms/libcaca/EL-5 .cvsignore, 1.2, 1.3 libcaca.spec, 1.12, 1.13 sources, 1.2, 1.3 libcaca-0.9-man3.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list