rpms/nspluginwrapper/devel nspluginwrapper-1.1.0-concurrent-rpc_method_invoke_rediff.patch, NONE, 1.1 nspluginwrapper-1.1.0-visual-id.patch, 1.3, 1.4 nspluginwrapper.spec, 1.60, 1.61
Warren Togami 砥上勇
wtogami at fedoraproject.org
Mon Oct 6 21:33:35 UTC 2008
Author: wtogami
Update of /cvs/pkgs/rpms/nspluginwrapper/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv3877
Modified Files:
nspluginwrapper-1.1.0-visual-id.patch nspluginwrapper.spec
Added Files:
nspluginwrapper-1.1.0-concurrent-rpc_method_invoke_rediff.patch
Log Message:
- Unrevert patch from -7 because Warren was wrong
- Concurrent rpc_method_invoke() patch
nspluginwrapper-1.1.0-concurrent-rpc_method_invoke_rediff.patch:
--- NEW FILE nspluginwrapper-1.1.0-concurrent-rpc_method_invoke_rediff.patch ---
Rediff against fedora's .src.rpm
diff -urN nspluginwrapper-1.1.0.orig/Makefile nspluginwrapper-1.1.0/Makefile
--- nspluginwrapper-1.1.0.orig/Makefile 2008-10-06 14:45:47.000000000 -0400
+++ nspluginwrapper-1.1.0/Makefile 2008-10-06 14:46:15.000000000 -0400
@@ -137,6 +137,18 @@
nploader_RAWSRCS = npw-viewer.sh
nploader_SOURCES = $(nploader_RAWSRCS:%.sh=$(SRC_PATH)/src/%.sh)
+test_rpc_RAWSRCS = test-rpc-common.c debug.c rpc.c
+test_rpc_client_OBJECTS = $(test_rpc_RAWSRCS:%.c=%-client.o)
+test_rpc_server_OBJECTS = $(test_rpc_RAWSRCS:%.c=%-server.o)
+test_rpc_client_CPPFLAGS = $(CPPFLAGS) -I$(SRC_PATH)/src -DBUILD_CLIENT -DNPW_COMPONENT_NAME="\"Client\""
+test_rpc_server_CPPFLAGS = $(CPPFLAGS) -I$(SRC_PATH)/src -DBUILD_SERVER -DNPW_COMPONENT_NAME="\"Server\""
+test_rpc_CFLAGS = -I$(SRC_PATH)/src $(GLIB_CFLAGS)
+test_rpc_LDFLAGS = $(GLIB_LDFLAGS) $(libpthread_LDFLAGS)
+test_rpc_RAWPROGS = test-rpc-types test-rpc-nested test-rpc-concurrent
+test_rpc_PROGRAMS = \
+ $(test_rpc_RAWPROGS:%=%-client) \
+ $(test_rpc_RAWPROGS:%=%-server)
+
CPPFLAGS = -I. -I$(SRC_PATH)
TARGETS = $(npconfig_PROGRAM)
TARGETS += $(nploader_PROGRAM)
@@ -146,6 +158,7 @@
ifeq ($(build_player),yes)
TARGETS += $(npplayer_PROGRAM)
endif
+TARGETS += $(test_rpc_PROGRAMS)
archivedir = files/
SRCARCHIVE = $(PACKAGE)-$(VERSION)$(VERSION_SUFFIX).tar
@@ -336,3 +349,16 @@
$(CC) $(LDFLAGS) -nostdlib $(DSO_LDFLAGS) $< -o $@ \
-Wl,--version-script,$(patsubst $(LSB_OBJ_DIR)/%.o,$(LSB_SRC_DIR)/%.Version,$<) \
-Wl,-soname,`grep "$(patsubst $(LSB_OBJ_DIR)/%.o,%,$<) " $(LSB_SRC_DIR)/LibNameMap.txt | cut -f2 -d' '`
+
+test-rpc-%-client: test-rpc-%-client.o $(test_rpc_client_OBJECTS)
+ $(CC) -o $@ $< $(test_rpc_client_OBJECTS) $(test_rpc_LDFLAGS)
+test-rpc-%-client.o: $(SRC_PATH)/tests/test-rpc-%.c
+ $(CC) -o $@ -c $< $(test_rpc_client_CPPFLAGS) $(test_rpc_CFLAGS)
+%-client.o: $(SRC_PATH)/src/%.c
+ $(CC) -o $@ -c $< $(test_rpc_client_CPPFLAGS) $(test_rpc_CFLAGS)
+test-rpc-%-server: test-rpc-%-server.o $(test_rpc_server_OBJECTS)
+ $(CC) -o $@ $< $(test_rpc_server_OBJECTS) $(test_rpc_LDFLAGS)
+test-rpc-%-server.o: $(SRC_PATH)/tests/test-rpc-%.c
+ $(CC) -o $@ -c $< $(test_rpc_server_CPPFLAGS) $(test_rpc_CFLAGS)
+%-server.o: $(SRC_PATH)/src/%.c
+ $(CC) -o $@ -c $< $(test_rpc_server_CPPFLAGS) $(test_rpc_CFLAGS)
diff -urN nspluginwrapper-1.1.0.orig/src/npruntime.c nspluginwrapper-1.1.0/src/npruntime.c
--- nspluginwrapper-1.1.0.orig/src/npruntime.c 2008-10-06 14:45:47.000000000 -0400
+++ nspluginwrapper-1.1.0/src/npruntime.c 2008-10-06 14:46:15.000000000 -0400
@@ -86,7 +86,7 @@
D(bug(" done\n"));
}
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
void npclass_invoke_Invalidate(NPObject *npobj)
diff -urN nspluginwrapper-1.1.0.orig/src/npw-viewer.c nspluginwrapper-1.1.0/src/npw-viewer.c
--- nspluginwrapper-1.1.0.orig/src/npw-viewer.c 2008-10-06 14:45:47.000000000 -0400
+++ nspluginwrapper-1.1.0/src/npw-viewer.c 2008-10-06 14:46:15.000000000 -0400
@@ -2389,6 +2389,12 @@
{
D(bug("handle_NP_GetMIMEDescription\n"));
+ int error = rpc_method_get_args(connection, RPC_TYPE_INVALID);
+ if (error != RPC_ERROR_NO_ERROR) {
+ npw_perror("NP_GetMIMEDescription() get args", error);
+ return error;
+ }
+
char *str = g_NP_GetMIMEDescription();
return rpc_method_send_reply(connection, RPC_TYPE_STRING, str, RPC_TYPE_INVALID);
}
@@ -2555,6 +2561,12 @@
{
D(bug("handle_NP_Shutdown\n"));
+ int error = rpc_method_get_args(connection, RPC_TYPE_INVALID);
+ if (error != RPC_ERROR_NO_ERROR) {
+ npw_perror("NP_Shutdown() get args", error);
+ return error;
+ }
+
NPError ret = g_NP_Shutdown();
return rpc_method_send_reply(connection, RPC_TYPE_INT32, ret, RPC_TYPE_INVALID);
}
@@ -2872,7 +2884,7 @@
if (url)
free(url);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPP_NewStream
@@ -3121,7 +3133,7 @@
if (fname)
free(fname);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPP_Print
@@ -3139,7 +3151,8 @@
D(bug(" done\n"));
}
-static void invoke_NPN_PrintData(PluginInstance *plugin, uint32_t platform_print_id, NPPrintData *printData)
+static void
+invoke_NPN_PrintData(PluginInstance *plugin, uint32_t platform_print_id, NPPrintData *printData)
{
if (printData == NULL)
return;
diff -urN nspluginwrapper-1.1.0.orig/src/npw-wrapper.c nspluginwrapper-1.1.0/src/npw-wrapper.c
--- nspluginwrapper-1.1.0.orig/src/npw-wrapper.c 2008-10-06 14:45:47.000000000 -0400
+++ nspluginwrapper-1.1.0/src/npw-wrapper.c 2008-10-06 14:46:15.000000000 -0400
@@ -246,6 +246,12 @@
{
D(bug("handle_NPN_UserAgent\n"));
+ int error = rpc_method_get_args(connection, RPC_TYPE_INVALID);
+ if (error != RPC_ERROR_NO_ERROR) {
+ npw_perror("NPN_UserAgent() get args", error);
+ return error;
+ }
+
const char *user_agent = g_NPN_UserAgent(NULL);
return rpc_method_send_reply(connection, RPC_TYPE_STRING, user_agent, RPC_TYPE_INVALID);
}
@@ -273,7 +279,7 @@
mozilla_funcs.status(instance, message);
if (message)
free(message);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_GetValue
@@ -394,7 +400,7 @@
g_NPN_InvalidateRect(instance, &invalidRect);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_GetURL
@@ -595,7 +601,7 @@
if (fwrite(printData.data, printData.size, 1, platformPrint->fp) != 1)
return RPC_ERROR_ERRNO_SET;
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_RequestRead
@@ -835,7 +841,7 @@
g_NPN_PushPopupsEnabledState(instance, enabled);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_PopPopupsEnabledState
@@ -865,7 +871,7 @@
g_NPN_PopPopupsEnabledState(instance);
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_CreateObject
@@ -1175,7 +1181,7 @@
// XXX memory leak (message)
- return RPC_ERROR_NO_ERROR;
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
}
// NPN_GetStringIdentifier
diff -urN nspluginwrapper-1.1.0.orig/src/rpc.c nspluginwrapper-1.1.0/src/rpc.c
--- nspluginwrapper-1.1.0.orig/src/rpc.c 2008-10-06 14:45:47.000000000 -0400
+++ nspluginwrapper-1.1.0/src/rpc.c 2008-10-06 14:46:15.000000000 -0400
@@ -516,6 +516,16 @@
return error;
}
+#if DEBUG
+static inline int rpc_error_debug(rpc_connection_t *connection, int error, const char *filename, int line)
+{
+ npw_printf("ERROR: RPC error %d caught at %s:%d\n", error, filename, line);
+ return rpc_error(connection, error);
+}
+#define rpc_error(connection, error) \
+ rpc_error_debug(connection, error, __FILE__, __LINE__)
+#endif
+
// Returns socket fd or -1 if invalid connection
int rpc_socket(rpc_connection_t *connection)
{
@@ -1472,7 +1482,7 @@
// Dispatch message received in the server loop
static int _rpc_dispatch(rpc_connection_t *connection, rpc_message_t *message)
{
- // wait: <invoke> (body: <method-id> MESSAGE_END
+ // recv: <invoke> (body: <method-id> MESSAGE_END
D(bug("receiving message\n"));
int32_t method;
int error = rpc_message_recv_int32(message, &method);
@@ -1486,14 +1496,6 @@
return RPC_ERROR_MESSAGE_TYPE_INVALID;
D(bug(" -- message received [%d]\n", method));
- // send: MESSAGE_ACK
- error = rpc_message_send_int32(message, RPC_MESSAGE_ACK);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
- error = rpc_message_flush(message);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
-
// call: <method>
rpc_method_callback_t callback = rpc_lookup_callback(connection, method);
if (callback)
@@ -1503,37 +1505,35 @@
if (error != RPC_ERROR_NO_ERROR) {
int error_code = error;
- // send: MESSAGE_FAILURE <error-code>
- error = rpc_message_send_int32(message, RPC_MESSAGE_FAILURE);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
- error = rpc_message_send_int32(message, error_code);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
- error = rpc_message_flush(message);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
+ // send: MESSAGE_FAILURE <error-code> ("high-level" error codes only)
+ switch (error) {
+ case RPC_ERROR_GENERIC:
+ case RPC_ERROR_ERRNO_SET:
+ case RPC_ERROR_NO_MEMORY:
+ error = rpc_message_send_int32(message, RPC_MESSAGE_FAILURE);
+ if (error != RPC_ERROR_NO_ERROR)
+ return error;
+ error = rpc_message_send_int32(message, error_code);
+ if (error != RPC_ERROR_NO_ERROR)
+ return error;
+ error = rpc_message_flush(message);
+ if (error != RPC_ERROR_NO_ERROR)
+ return error;
+ break;
+ }
return error_code;
}
- // send: MESSAGE_ACK
- error = rpc_message_send_int32(message, RPC_MESSAGE_ACK);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
- error = rpc_message_flush(message);
- if (error != RPC_ERROR_NO_ERROR)
- return error;
-
return method;
}
int rpc_dispatch(rpc_connection_t *connection)
{
+ int32_t msg_tag;
rpc_message_t message;
rpc_message_init(&message, connection);
- // wait: <invoke> (header: MESSAGE_START)
- int32_t msg_tag;
+ // recv: <invoke> (header: MESSAGE_START)
int error = rpc_message_recv_int32(&message, &msg_tag);
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
@@ -1546,6 +1546,35 @@
return method;
}
+// Dispatch pending remote calls until we get MSG_TAG
+static int _rpc_dispatch_until(rpc_connection_t *connection, rpc_message_t *message, int32_t expected_msg_tag)
+{
+ if (expected_msg_tag) {
+ for (;;) {
+ int32_t msg_tag;
+ int error = rpc_message_recv_int32(message, &msg_tag);
+ if (error != RPC_ERROR_NO_ERROR)
+ return error;
+ if (msg_tag == expected_msg_tag)
+ break;
+ if (msg_tag != RPC_MESSAGE_START)
+ return RPC_ERROR_MESSAGE_TYPE_INVALID;
+ if ((error = _rpc_dispatch(connection, message)) < 0)
+ return error;
+ }
+ }
+ else {
+ for (;;) {
+ int ret = _rpc_wait_dispatch(connection, 0);
+ if (ret == 0)
+ break;
+ if (ret < 0 || (ret = rpc_dispatch(connection)) < 0)
+ return ret;
+ }
+ }
+ return RPC_ERROR_NO_ERROR;
+}
+
/* ====================================================================== */
/* === Method Callbacks Handling === */
@@ -1634,16 +1663,12 @@
rpc_message_init(&message, connection);
// call: rpc_dispatch() (pending remote calls)
- for (;;) {
- int ret = _rpc_wait_dispatch(connection, 0);
- if (ret == 0)
- break;
- if (ret < 0 || (ret = rpc_dispatch(connection)) < 0)
- return ret;
- }
+ int error = _rpc_dispatch_until(connection, &message, 0);
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
// send: <invoke> = MESSAGE_START <method-id> MESSAGE_END
- int error = rpc_message_send_int32(&message, RPC_MESSAGE_START);
+ error = rpc_message_send_int32(&message, RPC_MESSAGE_START);
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
error = rpc_message_send_int32(&message, method);
@@ -1656,14 +1681,6 @@
if (error != RPC_ERROR_NO_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 rpc_error(connection, error);
- if (msg_tag != RPC_MESSAGE_ACK)
- return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
-
// send optional arguments
va_list args;
va_start(args, method);
@@ -1680,15 +1697,15 @@
error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
-
- // wait: MESSAGE_ACK
- error = rpc_message_recv_int32(&message, &msg_tag);
- if (error != RPC_ERROR_NO_ERROR)
- return rpc_error(connection, error);
- if (msg_tag != RPC_MESSAGE_ACK)
- return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
}
+ // wait: MESSAGE_ACK
+ error = _rpc_dispatch_until(connection, &message, RPC_MESSAGE_ACK);
+ if (error == RPC_ERROR_ERRNO_SET)
+ perror("rpc_method_invoke");
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
+
return RPC_ERROR_NO_ERROR;
}
@@ -1705,7 +1722,11 @@
rpc_message_t message;
rpc_message_init(&message, connection);
- // wait: <method-args>
+ // we can't have pending calls here because the method invocation
+ // message and its arguments are atomic (i.e. they are sent right
+ // away, no wait for ACK)
+
+ // recv: <method-args>
va_list args;
va_start(args, connection);
int error = rpc_message_recv_args(&message, args);
@@ -1735,76 +1756,42 @@
return RPC_ERROR_CONNECTION_CLOSED;
int error;
+ int32_t msg_tag;
rpc_message_t message;
rpc_message_init(&message, connection);
// call: rpc_dispatch() (pending remote calls)
- int32_t msg_tag;
- bool done = false;
- while (!done) {
- error = rpc_message_recv_int32(&message, &msg_tag);
- if (error != RPC_ERROR_NO_ERROR)
- return rpc_error(connection, error);
- switch (msg_tag) {
- case RPC_MESSAGE_START:
- if ((error = _rpc_dispatch(connection, &message)) < 0)
- return rpc_error(connection, error);
- break;
- case RPC_MESSAGE_REPLY:
- case RPC_MESSAGE_ACK:
- done = true;
- break;
- case RPC_MESSAGE_FAILURE:
- {
- // wait: <error-code>
- int32_t error_code;
- error = rpc_message_recv_int32(&message, &error_code);
- if (error != RPC_ERROR_NO_ERROR)
- return rpc_error(connection, error);
- // return other-side error code
- return rpc_error(connection, error_code);
- }
- default:
- return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
- }
- }
+ // recv: MESSAGE_REPLY
+ error = _rpc_dispatch_until(connection, &message, RPC_MESSAGE_REPLY);
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
+ // receive optional arguments
va_list args;
va_start(args, connection);
int type = va_arg(args, int);
va_end(args);
-
if (type != RPC_TYPE_INVALID) {
- // wait: <reply>
- if (msg_tag != RPC_MESSAGE_REPLY)
- return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
+ // recv: [ <method-args> ]
va_start(args, connection);
error = rpc_message_recv_args(&message, args);
va_end(args);
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
- error = rpc_message_recv_int32(&message, &msg_tag);
- if (error != RPC_ERROR_NO_ERROR)
- return rpc_error(connection, error);
- if (msg_tag != RPC_MESSAGE_END)
- 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 rpc_error(connection, error);
- error = rpc_message_flush(&message);
- if (error != RPC_ERROR_NO_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 rpc_error(connection, error);
}
+ // recv: MESSAGE_END
+ error = rpc_message_recv_int32(&message, &msg_tag);
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
+ if (msg_tag != RPC_MESSAGE_END)
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
+
// wait: MESSAGE_ACK
+ error = rpc_message_recv_int32(&message, &msg_tag);
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
if (msg_tag != RPC_MESSAGE_ACK)
return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
@@ -1841,13 +1828,13 @@
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
- // wait: MESSAGE_ACK
- int32_t msg_tag;
- error = rpc_message_recv_int32(&message, &msg_tag);
+ // send: MESSAGE_ACK
+ error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
+ if (error != RPC_ERROR_NO_ERROR)
+ return rpc_error(connection, error);
+ error = rpc_message_flush(&message);
if (error != RPC_ERROR_NO_ERROR)
return rpc_error(connection, error);
- if (msg_tag != RPC_MESSAGE_ACK)
- return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
return RPC_ERROR_NO_ERROR;
}
diff -urN nspluginwrapper-1.1.0.orig/tests/test-rpc-common.c nspluginwrapper-1.1.0/tests/test-rpc-common.c
--- nspluginwrapper-1.1.0.orig/tests/test-rpc-common.c 1969-12-31 19:00:00.000000000 -0500
+++ nspluginwrapper-1.1.0/tests/test-rpc-common.c 2008-10-06 14:46:15.000000000 -0400
@@ -0,0 +1,318 @@
+/*
+ * test-rpc-common.c - Common RPC test code
+ *
+ * nspluginwrapper (C) 2005-2008 Gwenole Beauchesne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "sysdeps.h"
+#include "test-rpc-common.h"
+#include <signal.h>
+
+#define DEBUG 1
+#include "debug.h"
+
+#ifdef BUILD_WRAPPER
+#define BUILD_CLIENT 1
+#endif
+
+#ifdef BUILD_VIEWER
+#define BUILD_SERVER 1
+#endif
+
+typedef struct _RPCTest RPCTest;
+struct _RPCTest
+{
+ RPCTestFuncs funcs;
+ gpointer user_data;
+};
+
+static RPCTest g_test;
+static rpc_connection_t *g_connection;
+static const gchar *g_connection_path;
+static GMainLoop *g_main_loop;
+static GPid g_child_pid;
+static guint g_child_watch_id;
+static guint g_source_id;
+static gint g_exit_status;
+
+void
+rpc_test_set_funcs (const RPCTestFuncs *funcs, gpointer user_data)
+{
+ g_test.user_data = user_data;
+ if (funcs && funcs->pre_dispatch_hook)
+ g_test.funcs.pre_dispatch_hook = funcs->pre_dispatch_hook;
+ if (funcs && funcs->post_dispatch_hook)
+ g_test.funcs.post_dispatch_hook = funcs->post_dispatch_hook;
+}
+
+rpc_connection_t *
+rpc_test_get_connection (void)
+{
+ return g_connection;
+}
+
+#ifdef BUILD_CLIENT
+static void
+child_exited_cb (GPid pid, gint status, gpointer user_data)
+{
+ g_print ("child_exited_cb(), pid %d, status %d\n", pid, status);
+ if (status)
+ g_exit_status = status;
+ g_main_loop_quit (g_main_loop);
+ if (g_child_watch_id)
+ g_source_remove (g_child_watch_id);
+ g_spawn_close_pid (pid);
+}
+
+static void
+kill_child_now (void)
+{
+ if (g_child_watch_id)
+ g_source_remove (g_child_watch_id);
+ if (g_child_pid)
+ {
+ g_spawn_close_pid (g_child_pid);
+ kill (g_child_pid, SIGTERM);
+ }
+}
+
+static void
+urgent_exit_sig (int sig)
+{
+ kill_child_now ();
+}
+#endif
+
+#ifdef BUILD_SERVER
+static gboolean
+rpc_event_prepare (GSource *source, gint *timeout)
+{
+ *timeout = -1;
+ return FALSE;
+}
+
+static gboolean
+rpc_event_check (GSource *source)
+{
+ return rpc_wait_dispatch (g_connection, 0) > 0;
+}
+
+static gboolean
+rpc_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ gint rc;
+
+ if (g_test.funcs.pre_dispatch_hook)
+ {
+ if (!g_test.funcs.pre_dispatch_hook (g_test.user_data))
+ return TRUE;
+ }
+
+ rc = rpc_dispatch (g_connection);
+
+ if (g_test.funcs.post_dispatch_hook)
+ g_test.funcs.post_dispatch_hook (g_test.user_data);
+
+ return rc != RPC_ERROR_CONNECTION_CLOSED;
+}
+
+typedef gboolean (*GSourcePrepare) (GSource *, gint *);
+typedef gboolean (*GSourceCheckFunc) (GSource *);
+typedef gboolean (*GSourceDispatchFunc) (GSource *, GSourceFunc, gpointer);
+typedef void (*GSourceFinalizeFunc) (GSource *);
+
+static GSourceFuncs rpc_event_funcs =
+ {
+ rpc_event_prepare,
+ rpc_event_check,
+ rpc_event_dispatch,
+ (GSourceFinalizeFunc)g_free,
+ (GSourceFunc)NULL,
+ (GSourceDummyMarshal)NULL
+ };
+#endif
+
+static gboolean
+rpc_test_execute_cb (gpointer user_data)
+{
+ int rc = RPC_TEST_EXECUTE_SUCCESS;
+
+ if (rpc_test_execute)
+ rc = rpc_test_execute (g_test.user_data);
+ g_assert ((rc & ~RPC_TEST_EXECUTE_DONT_QUIT) == RPC_TEST_EXECUTE_SUCCESS);
+
+#ifdef BUILD_CLIENT
+ if ((rc & RPC_TEST_EXECUTE_DONT_QUIT) == 0)
+ rpc_test_exit_full (0);
+#endif
+ return FALSE;
+}
+
+static gchar **
+clone_args (gchar **args)
+{
+ gchar **new_args;
+ gint i, n, rc = 0;
+
+ if ((new_args = g_strdupv (args)) == NULL)
+ g_error ("could not duplicate the program arguments");
+ n = g_strv_length (new_args);
+
+#ifdef BUILD_CLIENT
+ /* first arg was path to server program, skip it */
+ g_assert (n >= 2);
+ g_free (new_args[1]);
+ for (i = 1; i < n - 1; i++)
+ new_args[i] = new_args[i + 1];
+ new_args[i] = NULL;
+#endif
+
+ return new_args;
+}
+
+static void
+rpc_test_init_invoke (gchar **program_args)
+{
+ gchar **args = NULL;
+ gint n, rc = 0;
+
+ if ((args = clone_args (program_args)) == NULL)
+ g_error ("could not clone program arguments");
+ n = g_strv_length (args);
+
+ if (rpc_test_init)
+ rc = rpc_test_init (n, args);
+ g_strfreev (args);
+ g_assert (rc == 0);
+
+ g_timeout_add (0, rpc_test_execute_cb, NULL);
+}
+
+void
+rpc_test_exit (int status)
+{
+ if (status)
+ g_exit_status = status;
+ if (g_source_id)
+ g_source_remove (g_source_id);
+ if (g_connection)
+ rpc_exit (g_connection);
+ g_main_loop_quit (g_main_loop);
+}
+
+void
+rpc_test_exit_full (int status)
+{
+#ifdef BUILD_CLIENT
+ /* Tell server to quit, don't expect any reply from him */
+ rpc_method_invoke (g_connection,
+ RPC_TEST_METHOD_EXIT,
+ RPC_TYPE_INT32, status,
+ RPC_TYPE_INVALID);
+#endif
+
+ rpc_test_exit (status);
+}
+
+static int
+handle_rpc_test_exit (rpc_connection_t *connection)
+{
+ int error;
+ gint32 status;
+
+ error = rpc_method_get_args (connection,
+ RPC_TYPE_INT32, &status,
+ RPC_TYPE_INVALID);
+
+ if (error == RPC_ERROR_NO_ERROR)
+ rpc_test_exit (status);
+
+ return error;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (rpc_test_get_connection_path)
+ g_connection_path = rpc_test_get_connection_path ();
+ else
+ g_connection_path = NPW_CONNECTION_PATH "/Test.RPC";
+
+#ifdef BUILD_CLIENT
+ gchar **child_args;
+
+ if (argc < 2)
+ g_error ("no server program provided on command line");
+
+ signal (SIGSEGV, urgent_exit_sig);
+ signal (SIGBUS, urgent_exit_sig);
+ signal (SIGINT, urgent_exit_sig);
+ signal (SIGABRT, urgent_exit_sig);
+
+ if ((child_args = clone_args (argv)) == NULL)
+ g_error ("could not create server program arguments\n");
+ g_free (child_args[0]);
+ child_args[0] = g_strdup (argv[1]);
+
+ if (!g_spawn_async (NULL,
+ child_args,
+ NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL,
+ NULL,
+ &g_child_pid,
+ NULL))
+ g_error ("could not start server program '%s'", child_args[0]);
+
+ g_strfreev (child_args);
+
+ if ((g_connection = rpc_init_client (g_connection_path)) == NULL)
+ g_error ("failed to initialize RPC client connection");
+#endif
+
+#ifdef BUILD_SERVER
+ if ((g_connection = rpc_init_server (g_connection_path)) == NULL)
+ g_error ("failed to initialize RPC server connection");
+
+ GSource *rpc_source;
+ GPollFD rpc_event_poll_fd;
+
+ if ((rpc_source = g_source_new (&rpc_event_funcs, sizeof (GSource))) == NULL)
+ g_error ("failed to initialize RPC source");
+
+ g_source_id = g_source_attach (rpc_source, NULL);
+ memset (&rpc_event_poll_fd, 0, sizeof (rpc_event_poll_fd));
+ rpc_event_poll_fd.fd = rpc_listen_socket (g_connection);
+ rpc_event_poll_fd.events = G_IO_IN;
+ rpc_event_poll_fd.revents = 0;
+ g_source_add_poll (rpc_source, &rpc_event_poll_fd);
+#endif
+
+ static const rpc_method_descriptor_t vtable[] = {
+ { RPC_TEST_METHOD_EXIT, handle_rpc_test_exit }
+ };
+ if (rpc_connection_add_method_descriptor (g_connection, &vtable[0]) < 0)
+ g_error ("could not add method descriptor for TEST_RPC_METHOD_EXIT");
+
+ g_main_loop = g_main_loop_new (NULL, TRUE);
+#ifdef BUILD_CLIENT
+ g_child_watch_id = g_child_watch_add (g_child_pid, child_exited_cb, NULL);
+#endif
+ rpc_test_init_invoke (argv);
+ g_main_loop_run (g_main_loop);
+ return g_exit_status;
+}
diff -urN nspluginwrapper-1.1.0.orig/tests/test-rpc-common.h nspluginwrapper-1.1.0/tests/test-rpc-common.h
--- nspluginwrapper-1.1.0.orig/tests/test-rpc-common.h 1969-12-31 19:00:00.000000000 -0500
+++ nspluginwrapper-1.1.0/tests/test-rpc-common.h 2008-10-06 14:46:15.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * test-rpc-common.h - Common RPC test code
+ *
+ * nspluginwrapper (C) 2005-2008 Gwenole Beauchesne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TEST_RPC_COMMON_H
+#define TEST_RPC_COMMON_H
+
+#include "rpc.h"
+#include <glib.h>
+
+enum
+ {
+ /* void rpc_test_exit (int status); */
+ RPC_TEST_METHOD_EXIT = 0,
+ };
+
+enum
+ {
+ RPC_TEST_EXECUTE_SUCCESS = 0,
+ RPC_TEST_EXECUTE_FAILURE = 1,
+ RPC_TEST_EXECUTE_DONT_QUIT = 0x8000,
+ };
+
+typedef struct _RPCTestFuncs RPCTestFuncs;
+struct _RPCTestFuncs
+{
+ gboolean (*pre_dispatch_hook) (gpointer user_data);
+ void (*post_dispatch_hook) (gpointer user_data);
+};
+
+void
+rpc_test_set_funcs (const RPCTestFuncs *funcs, gpointer user_data);
+
+rpc_connection_t *
+rpc_test_get_connection (void);
+
+/* IMPLEMENT: default is NPW_CONNECTION_PATH "/Test.RPC"; */
+const gchar *
+rpc_test_get_connection_path (void)
+ __attribute__((__weak__));
+
+/* IMPLEMENT: default is return 0; */
+int
+rpc_test_init (int argc, char *argv[])
+ __attribute__((__weak__));
+
+/* IMPLEMENT: default is return 0; */
+int
+rpc_test_execute (gpointer user_data)
+ __attribute__((__weak__));
+
+void
+rpc_test_exit (int status);
+
+void
+rpc_test_exit_full (int status);
+
+#endif /* TEST_RPC_COMMON_H */
diff -urN nspluginwrapper-1.1.0.orig/tests/test-rpc-concurrent.c nspluginwrapper-1.1.0/tests/test-rpc-concurrent.c
--- nspluginwrapper-1.1.0.orig/tests/test-rpc-concurrent.c 1969-12-31 19:00:00.000000000 -0500
+++ nspluginwrapper-1.1.0/tests/test-rpc-concurrent.c 2008-10-06 14:46:15.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * test-rpc-concurrent.c - Test concurrent RPC invoke
+ *
+ * nspluginwrapper (C) 2005-2008 Gwenole Beauchesne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "sysdeps.h"
+#include "test-rpc-common.h"
+#include <string.h>
+
+#define DEBUG 1
+#include "debug.h"
+
+#define RPC_TEST_USE_IDLE TRUE
+
+enum
+ {
+ RPC_TEST_METHOD_PRINT = 1
+ };
+
+static gboolean g_is_silent = TRUE;
+static gint g_print_count = 5000;
+
+static void
+invoke_print (const gchar *str)
+{
+ rpc_connection_t *connection;
+ int error;
+
+ connection = rpc_test_get_connection ();
+ g_assert (connection != NULL);
+
+ error = rpc_method_invoke (connection,
+ RPC_TEST_METHOD_PRINT,
+ RPC_TYPE_STRING, str,
+ RPC_TYPE_INVALID);
+ /* Error out early for invalid messages types.
+
+ The problem we are looking at is rpc_method_invoke() waiting for
+ the other side MSG_ACK prior to sending the arguments. Sometimes,
+ the other side sends a new message first (MSG_START). So, we get
+ a mismatch. */
+ g_assert (error != RPC_ERROR_MESSAGE_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+
+ error = rpc_method_wait_for_reply (connection, RPC_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+}
+
+static int
+handle_print (rpc_connection_t *connection)
+{
+ char *str;
+ int error;
+
+ error = rpc_method_get_args (connection,
+ RPC_TYPE_STRING, &str,
+ RPC_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+ g_assert (str != NULL);
+
+ if (!g_is_silent)
+ npw_printf ("Got message from the other end: '%s'\n", str);
+ free (str);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static inline void
+print_msg (void)
+{
+ invoke_print ("Hello from " NPW_COMPONENT_NAME);
+}
+
+static gboolean
+invoke_print_cb (gpointer user_data)
+{
+ print_msg ();
+
+ --g_print_count;
+#ifdef BUILD_CLIENT
+ if (g_print_count == 0)
+ rpc_test_exit_full (0);
+#endif
+ return g_print_count > 0;
+}
+
+int
+rpc_test_init (int argc, char *argv[])
+{
+ rpc_connection_t *connection;
+
+ for (int i = 1; i < argc; i++)
+ {
+ const gchar *arg = argv[i];
+ if (strcmp (arg, "--silent") == 0 || strcmp (arg, "-q") == 0)
+ g_is_silent = TRUE;
+ else if (strcmp (arg, "--verbose") == 0 || strcmp (arg, "-v") == 0)
+ g_is_silent = FALSE;
+ else if (strcmp (arg, "--count") == 0)
+ {
+ if (++i < argc)
+ {
+ unsigned long v = strtoul (argv[i], NULL, 10);
+ if (v > 0)
+ g_print_count = v;
+ }
+ }
+ else if (strcmp (arg, "--help") == 0)
+ {
+ g_print ("Usage: %s [--silent|--verbose] [--count COUNT]\n", argv[0]);
+ rpc_test_exit (0);
+ }
+ }
+
+ connection = rpc_test_get_connection ();
+ g_assert (connection != NULL);
+
+ static const rpc_method_descriptor_t vtable[] = {
+ { RPC_TEST_METHOD_PRINT, handle_print },
+ };
+
+ if (rpc_connection_add_method_descriptor (connection, &vtable[0]) < 0)
+ g_error ("could not add method descriptors");
+
+ if (RPC_TEST_USE_IDLE)
+ {
+ /* XXX: we hope to trigger concurrent rpc_method_invoke() */
+ /* XXX: add a barrier to synchronize both processes? */
+ //g_idle_add (invoke_print_cb, NULL);
+ g_timeout_add (0, invoke_print_cb, NULL);
+ }
+ else
+ {
+ while (--g_print_count >= 0)
+ print_msg ();
+ }
+ return 0;
+}
+
+int
+rpc_test_execute (gpointer user_data)
+{
+#ifdef BUILD_CLIENT
+ if (RPC_TEST_USE_IDLE)
+ return RPC_TEST_EXECUTE_SUCCESS|RPC_TEST_EXECUTE_DONT_QUIT;
+#endif
+ return RPC_TEST_EXECUTE_SUCCESS;
+}
diff -urN nspluginwrapper-1.1.0.orig/tests/test-rpc-nested.c nspluginwrapper-1.1.0/tests/test-rpc-nested.c
--- nspluginwrapper-1.1.0.orig/tests/test-rpc-nested.c 1969-12-31 19:00:00.000000000 -0500
+++ nspluginwrapper-1.1.0/tests/test-rpc-nested.c 2008-10-06 14:46:15.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * test-rpc-nested.c - Test nested RPC invoke
+ *
+ * nspluginwrapper (C) 2005-2008 Gwenole Beauchesne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "sysdeps.h"
+#include "test-rpc-common.h"
+#include <unistd.h>
+
+#define DEBUG 1
+#include "debug.h"
+
+enum
+ {
+ RPC_TEST_METHOD_GET_PID = 1
+ };
+
+static gint
+get_remote_pid (void)
+{
+ rpc_connection_t *connection;
+ int error;
+ gint32 pid;
+
+ connection = rpc_test_get_connection ();
+ g_assert (connection != NULL);
+
+ error = rpc_method_invoke (connection,
+ RPC_TEST_METHOD_GET_PID,
+ RPC_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+
+ error = rpc_method_wait_for_reply (connection,
+ RPC_TYPE_INT32, &pid,
+ RPC_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+
+ return pid;
+}
+
+static inline gint
+get_local_pid (void)
+{
+ return getpid ();
+}
+
+static inline gint
+get_client_pid (void)
+{
+#ifdef BUILD_CLIENT
+ return get_local_pid ();
+#endif
+#ifdef BUILD_SERVER
+ return get_remote_pid ();
+#endif
+ return -1;
+}
+
+static int
+handle_get_pid (rpc_connection_t *connection)
+{
+ gint pid;
+ int error;
+
+ error = rpc_method_get_args (connection, RPC_TYPE_INVALID);
+ g_assert (error == RPC_ERROR_NO_ERROR);
+
+ pid = get_client_pid ();
+
+ return rpc_method_send_reply (connection,
+ RPC_TYPE_INT32, pid,
+ RPC_TYPE_INVALID);
+}
+
+int
+rpc_test_init (int argc, char *argv[])
+{
+ rpc_connection_t *connection;
+
+ connection = rpc_test_get_connection ();
+ g_assert (connection != NULL);
+
+ static const rpc_method_descriptor_t vtable[] = {
+ { RPC_TEST_METHOD_GET_PID, handle_get_pid },
+ };
+
+ if (rpc_connection_add_method_descriptor (connection, &vtable[0]) < 0)
+ g_error ("could not add method descriptors");
+
+ return 0;
+}
+
+int
+rpc_test_execute (gpointer user_data)
+{
+#ifdef BUILD_CLIENT
+ gint pid = get_remote_pid ();
+ g_assert (pid == get_local_pid ());
+#endif
+ return RPC_TEST_EXECUTE_SUCCESS;
+}
diff -urN nspluginwrapper-1.1.0.orig/tests/test-rpc-types.c nspluginwrapper-1.1.0/tests/test-rpc-types.c
--- nspluginwrapper-1.1.0.orig/tests/test-rpc-types.c 1969-12-31 19:00:00.000000000 -0500
+++ nspluginwrapper-1.1.0/tests/test-rpc-types.c 2008-10-06 14:46:15.000000000 -0400
@@ -0,0 +1,504 @@
+/*
+ * test-rpc-types.c - Test marshaling of common data types
+ *
+ * nspluginwrapper (C) 2005-2008 Gwenole Beauchesne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "sysdeps.h"
+#include "test-rpc-common.h"
+#include "utils.h"
+#include <stdarg.h>
+
+#define DEBUG 1
+#include "debug.h"
+
+#define RPC_TEST_MAX_ARGS 32
+
+enum
+ {
+ RPC_TEST_METHOD_VOID__VOID = 1,
+ RPC_TEST_METHOD_VOID__CHAR,
+ RPC_TEST_METHOD_VOID__CHARx10,
+ RPC_TEST_METHOD_VOID__BOOL,
+ RPC_TEST_METHOD_VOID__BOOLx10,
+ RPC_TEST_METHOD_VOID__INT32x10,
+ RPC_TEST_METHOD_VOID__UINT32x10,
+ RPC_TEST_METHOD_VOID__UINT64x10,
+ RPC_TEST_METHOD_VOID__DOUBLEx5,
+ RPC_TEST_METHOD_VOID__STRINGx3,
+ };
+
+const gchar *
+rpc_test_get_connection_path (void)
+{
+ return NPW_CONNECTION_PATH "/Test.RPC.Types";
+}
+
+static void
+rpc_test_signature (gboolean is_invoke, ...)
+{
+ va_list args;
+ gint type, n_args;
+ gboolean was_array;
+ GString *str;
+
+ if ((str = g_string_new (NULL)) == NULL)
+ return;
+ n_args = 0;
+ was_array = FALSE;
+ va_start (args, is_invoke);
+ while ((type = va_arg (args, gint)) != RPC_TYPE_INVALID)
+ {
+ if (++n_args > 1 && !was_array)
+ g_string_append (str, ", ");
+ was_array = FALSE;
+ switch (type)
+ {
+ case RPC_TYPE_CHAR:
+ g_string_append (str, "char");
+ if (is_invoke)
+ va_arg (args, int);
+ break;
+ case RPC_TYPE_BOOLEAN:
+ g_string_append (str, "bool");
+ if (is_invoke)
+ va_arg (args, int);
+ break;
+ case RPC_TYPE_INT32:
+ g_string_append (str, "int32");
+ if (is_invoke)
+ va_arg (args, gint32);
+ break;
+ case RPC_TYPE_UINT32:
+ g_string_append (str, "uint32");
+ if (is_invoke)
+ va_arg (args, guint32);
+ break;
+ case RPC_TYPE_UINT64:
+ g_string_append (str, "uint64");
+ if (is_invoke)
+ va_arg (args, guint64);
+ break;
+ case RPC_TYPE_DOUBLE:
+ g_string_append (str, "double");
+ if (is_invoke)
+ va_arg (args, gdouble);
+ break;
+ case RPC_TYPE_STRING:
+ g_string_append (str, "string");
+ if (is_invoke)
+ va_arg (args, gchar *);
+ break;
+ case RPC_TYPE_ARRAY:
+ g_string_append (str, "array of");
+ was_array = TRUE;
+ break;
+ }
+ if (!is_invoke && type != RPC_TYPE_ARRAY)
+ va_arg (args, gpointer);
+ }
+ va_end (args);
+ if (n_args == 0)
+ g_string_append (str, "void");
+ g_print ("void f (%s)\n", str->str);
+ g_string_free (str, TRUE);
+}
+
+#define rpc_test_invoke(method, ...) do { \
+ int error; \
+ rpc_connection_t *connection; \
+ connection = rpc_test_get_connection (); \
+ rpc_test_signature (TRUE, __VA_ARGS__); \
+ error = rpc_method_invoke (connection, method, __VA_ARGS__); \
+ g_assert (error == RPC_ERROR_NO_ERROR); \
+ error = rpc_method_wait_for_reply (connection, RPC_TYPE_INVALID); \
+ g_assert (error == RPC_ERROR_NO_ERROR); \
+} while (0)
+
+#define rpc_test_get_args(connection, ...) do { \
+ int error; \
+ rpc_test_signature (FALSE, __VA_ARGS__); \
+ error = rpc_method_get_args (connection, __VA_ARGS__); \
+ g_assert (error == RPC_ERROR_NO_ERROR); \
+} while (0)
+
+#ifdef BUILD_SERVER
+typedef union _RPCTestArg RPCTestArg;
+
+union _RPCTestArg
+{
+ gchar c;
+ guint b;
+ gint32 i;
+ guint32 u;
+ guint64 j;
+ gdouble d;
+ gchar *s;
+};
+
+static RPCTestArg g_args[RPC_TEST_MAX_ARGS];
+
+static int
+handle_VOID__VOID (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_INVALID);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__CHAR (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_CHAR, &g_args[0].c,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].c == 'a');
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__CHARx10 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_CHAR, &g_args[0].c,
+ RPC_TYPE_CHAR, &g_args[1].c,
+ RPC_TYPE_CHAR, &g_args[2].c,
+ RPC_TYPE_CHAR, &g_args[3].c,
+ RPC_TYPE_CHAR, &g_args[4].c,
+ RPC_TYPE_CHAR, &g_args[5].c,
+ RPC_TYPE_CHAR, &g_args[6].c,
+ RPC_TYPE_CHAR, &g_args[7].c,
+ RPC_TYPE_CHAR, &g_args[8].c,
+ RPC_TYPE_CHAR, &g_args[9].c,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].c == 'a');
+ g_assert (g_args[1].c == 'b');
+ g_assert (g_args[2].c == 'c');
+ g_assert (g_args[3].c == 'd');
+ g_assert (g_args[4].c == 'e');
+ g_assert (g_args[5].c == '1');
+ g_assert (g_args[6].c == '2');
+ g_assert (g_args[7].c == '3');
+ g_assert (g_args[8].c == '4');
+ g_assert (g_args[9].c == '5');
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__BOOL (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_BOOLEAN, &g_args[0].b,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].b == TRUE);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__BOOLx10 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_BOOLEAN, &g_args[0].b,
+ RPC_TYPE_BOOLEAN, &g_args[1].b,
+ RPC_TYPE_BOOLEAN, &g_args[2].b,
+ RPC_TYPE_BOOLEAN, &g_args[3].b,
+ RPC_TYPE_BOOLEAN, &g_args[4].b,
+ RPC_TYPE_BOOLEAN, &g_args[5].b,
+ RPC_TYPE_BOOLEAN, &g_args[6].b,
+ RPC_TYPE_BOOLEAN, &g_args[7].b,
+ RPC_TYPE_BOOLEAN, &g_args[8].b,
+ RPC_TYPE_BOOLEAN, &g_args[9].b,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].b == TRUE);
+ g_assert (g_args[1].b == FALSE);
+ g_assert (g_args[2].b == TRUE);
+ g_assert (g_args[3].b == FALSE);
+ g_assert (g_args[4].b == TRUE);
+ g_assert (g_args[5].b == FALSE);
+ g_assert (g_args[6].b == TRUE);
+ g_assert (g_args[7].b == FALSE);
+ g_assert (g_args[8].b == TRUE);
+ g_assert (g_args[9].b == FALSE);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__INT32x10 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_INT32, &g_args[0].i,
+ RPC_TYPE_INT32, &g_args[1].i,
+ RPC_TYPE_INT32, &g_args[2].i,
+ RPC_TYPE_INT32, &g_args[3].i,
+ RPC_TYPE_INT32, &g_args[4].i,
+ RPC_TYPE_INT32, &g_args[5].i,
+ RPC_TYPE_INT32, &g_args[6].i,
+ RPC_TYPE_INT32, &g_args[7].i,
+ RPC_TYPE_INT32, &g_args[8].i,
+ RPC_TYPE_INT32, &g_args[9].i,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].i == 0);
+ g_assert (g_args[1].i == 1);
+ g_assert (g_args[2].i == -1);
+ g_assert (g_args[3].i == 2);
+ g_assert (g_args[4].i == -2);
+ g_assert (g_args[5].i == G_MAXINT32);
+ g_assert (g_args[6].i == G_MININT32);
+ g_assert (g_args[7].i == G_MAXINT32 - 1);
+ g_assert (g_args[8].i == G_MININT32 + 1);
+ g_assert (g_args[9].i == 0);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__UINT32x10 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_UINT32, &g_args[0].u,
+ RPC_TYPE_UINT32, &g_args[1].u,
+ RPC_TYPE_UINT32, &g_args[2].u,
+ RPC_TYPE_UINT32, &g_args[3].u,
+ RPC_TYPE_UINT32, &g_args[4].u,
+ RPC_TYPE_UINT32, &g_args[5].u,
+ RPC_TYPE_UINT32, &g_args[6].u,
+ RPC_TYPE_UINT32, &g_args[7].u,
+ RPC_TYPE_UINT32, &g_args[8].u,
+ RPC_TYPE_UINT32, &g_args[9].u,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].u == 0);
+ g_assert (g_args[1].u == 1);
+ g_assert (g_args[2].u == 0xffffffff);
+ g_assert (g_args[3].u == 2);
+ g_assert (g_args[4].u == 0xfffffffe);
+ g_assert (g_args[5].u == G_MAXUINT32);
+ g_assert (g_args[6].u == G_MAXUINT32 - 1);
+ g_assert (g_args[7].u == 0x80000000);
+ g_assert (g_args[8].u == 0x80000001);
+ g_assert (g_args[9].u == 0);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__UINT64x10 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_UINT64, &g_args[0].j,
+ RPC_TYPE_UINT64, &g_args[1].j,
+ RPC_TYPE_UINT64, &g_args[2].j,
+ RPC_TYPE_UINT64, &g_args[3].j,
+ RPC_TYPE_UINT64, &g_args[4].j,
+ RPC_TYPE_UINT64, &g_args[5].j,
+ RPC_TYPE_UINT64, &g_args[6].j,
+ RPC_TYPE_UINT64, &g_args[7].j,
+ RPC_TYPE_UINT64, &g_args[8].j,
+ RPC_TYPE_UINT64, &g_args[9].j,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].j == 0);
+ g_assert (g_args[1].j == G_GINT64_CONSTANT (0x00000000000000ffU));
+ g_assert (g_args[2].j == G_GINT64_CONSTANT (0x000000000000ff00U));
+ g_assert (g_args[3].j == G_GINT64_CONSTANT (0x0000000000ff0000U));
+ g_assert (g_args[4].j == G_GINT64_CONSTANT (0x00000000ff000000U));
+ g_assert (g_args[5].j == G_GINT64_CONSTANT (0x000000ff00000000U));
+ g_assert (g_args[6].j == G_GINT64_CONSTANT (0x0000ff0000000000U));
+ g_assert (g_args[7].j == G_GINT64_CONSTANT (0x00ff000000000000U));
+ g_assert (g_args[8].j == G_GINT64_CONSTANT (0xff00000000000000U));
+ g_assert (g_args[9].j == G_GINT64_CONSTANT (0x0123456789abcdefU));
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__DOUBLEx5 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_DOUBLE, &g_args[0].d,
+ RPC_TYPE_DOUBLE, &g_args[1].d,
+ RPC_TYPE_DOUBLE, &g_args[2].d,
+ RPC_TYPE_DOUBLE, &g_args[3].d,
+ RPC_TYPE_DOUBLE, &g_args[4].d,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].d == 0.0);
+ g_assert (g_args[1].d == 1.0);
+ g_assert (g_args[2].d == -1.0);
+ g_assert (g_args[3].d == 2.0);
+ g_assert (g_args[4].d == -2.0);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+
+static int
+handle_VOID__STRINGx3 (rpc_connection_t *connection)
+{
+ rpc_test_get_args (connection,
+ RPC_TYPE_STRING, &g_args[0].s,
+ RPC_TYPE_STRING, &g_args[1].s,
+ RPC_TYPE_STRING, &g_args[2].s,
+ RPC_TYPE_INVALID);
+
+ g_assert (g_args[0].s && strcmp (g_args[0].s, "") == 0);
+ free (g_args[0].s);
+ g_assert (g_args[1].s && strcmp (g_args[1].s, "one") == 0);
+ free (g_args[1].s);
+ g_assert (g_args[2].s == NULL);
+
+ return rpc_method_send_reply (connection, RPC_TYPE_INVALID);
+}
+#endif
+
+int
+rpc_test_init (int argc, char *argv[])
+{
+#ifdef BUILD_SERVER
+ rpc_connection_t *connection;
+
+ static const rpc_method_descriptor_t vtable[] =
+ {
+ { RPC_TEST_METHOD_VOID__VOID, handle_VOID__VOID },
+ { RPC_TEST_METHOD_VOID__CHAR, handle_VOID__CHAR },
+ { RPC_TEST_METHOD_VOID__CHARx10, handle_VOID__CHARx10 },
+ { RPC_TEST_METHOD_VOID__BOOL, handle_VOID__BOOL },
+ { RPC_TEST_METHOD_VOID__BOOLx10, handle_VOID__BOOLx10 },
+ { RPC_TEST_METHOD_VOID__INT32x10, handle_VOID__INT32x10 },
+ { RPC_TEST_METHOD_VOID__UINT32x10, handle_VOID__UINT32x10 },
+ { RPC_TEST_METHOD_VOID__UINT64x10, handle_VOID__UINT64x10 },
+ { RPC_TEST_METHOD_VOID__DOUBLEx5, handle_VOID__DOUBLEx5 },
+ { RPC_TEST_METHOD_VOID__STRINGx3, handle_VOID__STRINGx3 },
+ };
+
+ connection = rpc_test_get_connection ();
+ g_assert (connection != NULL);
+
+ if (rpc_connection_add_method_descriptors(connection,
+ vtable,
+ G_N_ELEMENTS (vtable)) < 0)
+ g_error ("could not add method descriptors");
+#endif
+
+ return 0;
+}
+
+int
+rpc_test_execute (gpointer user_data)
+{
+#ifdef BUILD_CLIENT
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__VOID,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__CHAR,
+ RPC_TYPE_CHAR, 'a',
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__CHARx10,
+ RPC_TYPE_CHAR, 'a',
+ RPC_TYPE_CHAR, 'b',
+ RPC_TYPE_CHAR, 'c',
+ RPC_TYPE_CHAR, 'd',
+ RPC_TYPE_CHAR, 'e',
+ RPC_TYPE_CHAR, '1',
+ RPC_TYPE_CHAR, '2',
+ RPC_TYPE_CHAR, '3',
+ RPC_TYPE_CHAR, '4',
+ RPC_TYPE_CHAR, '5',
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__BOOL,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__BOOLx10,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_BOOLEAN, FALSE,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_BOOLEAN, FALSE,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_BOOLEAN, FALSE,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_BOOLEAN, FALSE,
+ RPC_TYPE_BOOLEAN, TRUE,
+ RPC_TYPE_BOOLEAN, FALSE,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__INT32x10,
+ RPC_TYPE_INT32, 0,
+ RPC_TYPE_INT32, 1,
+ RPC_TYPE_INT32, -1,
+ RPC_TYPE_INT32, 2,
+ RPC_TYPE_INT32, -2,
+ RPC_TYPE_INT32, G_MAXINT32,
+ RPC_TYPE_INT32, G_MININT32,
+ RPC_TYPE_INT32, G_MAXINT32 - 1,
+ RPC_TYPE_INT32, G_MININT32 + 1,
+ RPC_TYPE_INT32, 0,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__UINT32x10,
+ RPC_TYPE_UINT32, 0,
+ RPC_TYPE_UINT32, 1,
+ RPC_TYPE_UINT32, 0xffffffff,
+ RPC_TYPE_UINT32, 2,
+ RPC_TYPE_UINT32, 0xfffffffe,
+ RPC_TYPE_UINT32, G_MAXUINT32,
+ RPC_TYPE_UINT32, G_MAXUINT32 - 1,
+ RPC_TYPE_UINT32, 0x80000000,
+ RPC_TYPE_UINT32, 0x80000001,
+ RPC_TYPE_UINT32, 0,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__UINT64x10,
+ RPC_TYPE_UINT64, 0,
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x00000000000000ffU),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x000000000000ff00U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x0000000000ff0000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x00000000ff000000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x000000ff00000000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x0000ff0000000000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x00ff000000000000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0xff00000000000000U),
+ RPC_TYPE_UINT64, G_GINT64_CONSTANT (0x0123456789abcdefU),
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__DOUBLEx5,
+ RPC_TYPE_DOUBLE, 0.0,
+ RPC_TYPE_DOUBLE, 1.0,
+ RPC_TYPE_DOUBLE, -1.0,
+ RPC_TYPE_DOUBLE, 2.0,
+ RPC_TYPE_DOUBLE, -2.0,
+ RPC_TYPE_INVALID);
+
+ rpc_test_invoke (RPC_TEST_METHOD_VOID__STRINGx3,
+ RPC_TYPE_STRING, "",
+ RPC_TYPE_STRING, "one",
+ RPC_TYPE_STRING, NULL,
+ RPC_TYPE_INVALID);
+#endif
+ return RPC_TEST_EXECUTE_SUCCESS;
+}
diff -urN nspluginwrapper-1.1.0.orig/TODO nspluginwrapper-1.1.0/TODO
--- nspluginwrapper-1.1.0.orig/TODO 2008-07-06 16:50:10.000000000 -0400
+++ nspluginwrapper-1.1.0/TODO 2008-10-06 14:46:15.000000000 -0400
@@ -19,6 +19,7 @@
* Split toolkit specific code (npviewer-{x11,gtk,win}.c)
* Use winelib + override win32 socket to support AF_UNIX (Linux "native")
- RPC
+ * RPC_MESSAGE_FAILURE handling is broken
* Need a way to differenciate array of pointers or array of values
=> RPC_TYPE_DYNAMIC (allocate space), RPC_TYPE_STATIC (assumes data alloc'ed?)
=> Rearrange RPC message type descriptors
nspluginwrapper-1.1.0-visual-id.patch:
Index: nspluginwrapper-1.1.0-visual-id.patch
===================================================================
RCS file: /cvs/pkgs/rpms/nspluginwrapper/devel/nspluginwrapper-1.1.0-visual-id.patch,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nspluginwrapper-1.1.0-visual-id.patch 3 Oct 2008 22:23:55 -0000 1.3
+++ nspluginwrapper-1.1.0-visual-id.patch 6 Oct 2008 21:33:35 -0000 1.4
@@ -1,13 +1,37 @@
-diff -up nspluginwrapper-1.1.0/src/npw-rpc.c.old nspluginwrapper-1.1.0/src/npw-rpc.c
---- nspluginwrapper-1.1.0/src/npw-rpc.c.old 2008-07-06 17:33:14.000000000 +0200
-+++ nspluginwrapper-1.1.0/src/npw-rpc.c 2008-08-01 20:45:33.000000000 +0200
-@@ -381,7 +381,8 @@ static int do_send_NPSetWindowCallbackSt
+2008-09-30 Gwenole Beauchesne <gb.public at free.fr>
+
+ * src/npw-rpc (do_send_NPSetWindowCallbackStruct): Check for
+ NULL visual.
+ * src/npw-viewer.c (create_window_attributes): Get system
+ visual when we are passed a 0 visual ID.
+
+Index: src/npw-viewer.c
+===================================================================
+--- src/npw-viewer.c (revision 645)
++++ src/npw-viewer.c (revision 646)
+@@ -358,7 +358,11 @@
+ {
+ if (ws_info == NULL)
+ return -1;
+- GdkVisual *gdk_visual = gdkx_visual_get((uintptr_t)ws_info->visual);
++ GdkVisual *gdk_visual;
++ if (ws_info->visual)
++ gdk_visual = gdkx_visual_get((uintptr_t)ws_info->visual);
++ else
++ gdk_visual = gdk_visual_get_system();
+ if (gdk_visual == NULL) {
+ npw_printf("ERROR: could not reconstruct XVisual from visualID\n");
+ return -2;
+Index: src/npw-rpc.c
+===================================================================
+--- src/npw-rpc.c (revision 645)
++++ src/npw-rpc.c (revision 646)
+@@ -381,7 +381,7 @@
return error;
if ((error = rpc_message_send_int32(message, ws_info->type)) < 0)
return error;
- if ((error = rpc_message_send_uint32(message, XVisualIDFromVisual(ws_info->visual))) < 0)
-+ uint32_t visual_id = ws_info->visual != NULL ? XVisualIDFromVisual(ws_info->visual) : 0;
-+ if ((error = rpc_message_send_uint32(message, visual_id)) < 0)
++ if ((error = rpc_message_send_uint32(message, ws_info->visual ? XVisualIDFromVisual(ws_info->visual) : 0)) < 0)
return error;
if ((error = rpc_message_send_uint32(message, ws_info->colormap)) < 0)
return error;
Index: nspluginwrapper.spec
===================================================================
RCS file: /cvs/pkgs/rpms/nspluginwrapper/devel/nspluginwrapper.spec,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- nspluginwrapper.spec 5 Oct 2008 14:31:24 -0000 1.60
+++ nspluginwrapper.spec 6 Oct 2008 21:33:35 -0000 1.61
@@ -70,7 +70,7 @@
Summary: A compatibility layer for Netscape 4 plugins
Name: nspluginwrapper
Version: 1.1.0
-Release: 10%{?dist}
+Release: 11%{?dist}
Source0: %{name}-%{version}%{?svndate:-%{svndate}}.tar.bz2
Source1: %{plugin_config_name}.tar.gz
Source2: plugin-config.sh.in
@@ -81,6 +81,7 @@
Patch4: nspluginwrapper-0.9.91.5-shutdown.patch
Patch5: nspluginwrapper-0.9.91.5-sleep.patch
Patch6: nspluginwrapper-1.1.0-visual-id.patch
+Patch7: nspluginwrapper-1.1.0-concurrent-rpc_method_invoke_rediff.patch
Patch100: plugin-config-setuid.patch
License: GPLv2+
Group: Networking/WWW
@@ -110,7 +111,8 @@
%patch3 -p1 -b .fork
%patch4 -p1 -b .shutdown
%patch5 -p1 -b .sleep
-%patch6 -p1 -b .visual_id
+%patch6 -p0 -b .visual_id
+%patch7 -p1 -b .concurrent_rpc_method_invoke
pushd %plugin_config_name
%patch100 -p2
@@ -241,6 +243,10 @@
%config %{_sysconfdir}/sysconfig/%{name}
%changelog
+* Mon Oct 06 2008 Warren Togami <wtogami at redhat.com> 1.1.0-11
+- Unrevert patch from -7 because Warren was wrong
+- Concurrent rpc_method_invoke() patch
+
* Fri Oct 03 2008 Warren Togami <wtogami at redhat.com> 1.1.0-10
- Revert libcurl requires because it was done in an incorrect way
- Revert patch from -7 because it made things worse
More information about the fedora-extras-commits
mailing list