You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jk...@apache.org on 2017/02/20 19:05:35 UTC

thrift git commit: THRIFT-3706: Implement multiplexed protocol client and test client for c_glib; test server for java; integrate into crosstest Client: c_glib

Repository: thrift
Updated Branches:
  refs/heads/master 06190874c -> bc0082e02


THRIFT-3706: Implement multiplexed protocol client and test client for c_glib; test server for java; integrate into crosstest
Client: c_glib

This closes #1191
This closes #1199


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/bc0082e0
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/bc0082e0
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/bc0082e0

Branch: refs/heads/master
Commit: bc0082e02357de2f30b997188bdfa94d703331f4
Parents: 0619087
Author: Gonzalo Aguilar Delgado <ga...@level2crm.com>
Authored: Fri Mar 4 13:16:22 2016 +0100
Committer: James E. King, III <jk...@apache.org>
Committed: Mon Feb 20 14:04:17 2017 -0500

----------------------------------------------------------------------
 lib/c_glib/Makefile.am                          |   6 +-
 .../protocol/thrift_multiplexed_protocol.c      | 187 ++++++
 .../protocol/thrift_multiplexed_protocol.h      |  77 +++
 .../c_glib/protocol/thrift_protocol_decorator.c | 651 +++++++++++++++++++
 .../c_glib/protocol/thrift_protocol_decorator.h |  77 +++
 .../test/org/apache/thrift/test/TestServer.java |  62 +-
 test/c_glib/src/test_client.c                   |  57 +-
 test/crossrunner/report.py                      |   8 +-
 test/tests.json                                 |  10 +-
 9 files changed, 1103 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am
index b66c89b..8e7bf88 100755
--- a/lib/c_glib/Makefile.am
+++ b/lib/c_glib/Makefile.am
@@ -35,8 +35,10 @@ libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \
                               src/thrift/c_glib/processor/thrift_processor.c \
                               src/thrift/c_glib/processor/thrift_dispatch_processor.c \
                               src/thrift/c_glib/protocol/thrift_protocol.c \
+                              src/thrift/c_glib/protocol/thrift_protocol_decorator.c \
                               src/thrift/c_glib/protocol/thrift_protocol_factory.c \
                               src/thrift/c_glib/protocol/thrift_binary_protocol.c \
+                              src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c \
                               src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \
                               src/thrift/c_glib/protocol/thrift_compact_protocol.c \
                               src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c \
@@ -67,11 +69,13 @@ include_thrift_HEADERS = \
 
 include_protocoldir = $(include_thriftdir)/protocol
 include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \
+                           src/thrift/c_glib/protocol/thrift_protocol_decorator.h \
                            src/thrift/c_glib/protocol/thrift_protocol_factory.h \
                            src/thrift/c_glib/protocol/thrift_binary_protocol.h \
                            src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \
                            src/thrift/c_glib/protocol/thrift_compact_protocol.h \
-                           src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h
+                           src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h \
+                           src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h 
 
 include_transportdir = $(include_thriftdir)/transport
 include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
----------------------------------------------------------------------
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
new file mode 100644
index 0000000..86f8097
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
+
+
+enum
+{
+  PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME = 1,
+  PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR,
+  PROP_THRIFT_MULTIPLEXED_PROTOCOL_END
+};
+
+G_DEFINE_TYPE(ThriftMultiplexedProtocol, thrift_multiplexed_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR)
+
+
+static GParamSpec *thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_END] = { NULL, };
+
+gint32
+thrift_multiplexed_protocol_write_message_begin (ThriftMultiplexedProtocol *protocol,
+		const gchar *name, const ThriftMessageType message_type,
+		const gint32 seqid, GError **error)
+{
+	gint32 ret;
+	gchar *service_name = NULL;
+	g_return_val_if_fail (THRIFT_IS_MULTIPLEXED_PROTOCOL (protocol), -1);
+
+	ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (protocol);
+	ThriftMultiplexedProtocolClass *multiplexClass = THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(self);
+	ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (multiplexClass);
+
+	if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) {
+		service_name = g_strdup_printf("%s%s%s", self->service_name, self->separator, name);
+
+	}else{
+		service_name = g_strdup(name);
+	}
+
+	// relay to the protocol_decorator
+	ret = thrift_protocol_decorator_write_message_begin(protocol, service_name, message_type, seqid, error);
+
+	g_free(service_name);
+
+	return ret;
+}
+
+
+
+
+static void
+thrift_multiplexed_protocol_set_property (GObject      *object,
+		guint         property_id,
+		const GValue *value,
+		GParamSpec   *pspec)
+{
+	ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object);
+
+	switch (property_id)
+	{
+	case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME:
+		if(self->service_name!=NULL)
+			g_free (self->service_name);
+		self->service_name= g_value_dup_string (value);
+		break;
+
+	case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR:
+		if(self->separator!=NULL)
+			g_free (self->separator);
+		self->separator= g_value_dup_string (value);
+		break;
+
+	default:
+		/* We don't have any other property... */
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+thrift_multiplexed_protocol_get_property (GObject    *object,
+		guint       property_id,
+		GValue     *value,
+		GParamSpec *pspec)
+{
+	ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object);
+
+	switch (property_id)
+	{
+	case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME:
+		g_value_set_string (value, self->service_name);
+		break;
+
+	case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR:
+		g_value_set_string (value, self->separator);
+		break;
+
+	default:
+		/* We don't have any other property... */
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void
+thrift_multiplexed_protocol_init (ThriftMultiplexedProtocol *protocol)
+{
+	//  THRIFT_UNUSED_VAR (protocol);
+	protocol->separator = g_strdup (THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR);
+	protocol->service_name = NULL;
+}
+
+static void
+thrift_multiplexed_protocol_finalize (ThriftMultiplexedProtocol *protocol)
+{
+	if(protocol->separator){
+		g_free(protocol->separator);
+		protocol->separator = NULL;
+	}
+	if(protocol->service_name){
+		g_free(protocol->service_name);
+		protocol->service_name = NULL;
+	}
+	/* Always chain up to the parent class; there is no need to check if
+	 * the parent class implements the dispose() virtual function: it is
+	 * always guaranteed to do so
+	 */
+	/* This fails, why? G_OBJECT_CLASS (protocol)->finalize(protocol); */
+}
+
+
+/* initialize the class */
+static void
+thrift_multiplexed_protocol_class_init (ThriftMultiplexedProtocolClass *klass)
+{
+	ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_debug("Current Multiplexed write_message_begin addr %p, new %p", cls->write_message_begin, thrift_multiplexed_protocol_write_message_begin);
+	cls->write_message_begin = thrift_multiplexed_protocol_write_message_begin;
+
+
+	object_class->set_property = thrift_multiplexed_protocol_set_property;
+	object_class->get_property = thrift_multiplexed_protocol_get_property;
+	object_class->finalize = thrift_multiplexed_protocol_finalize;
+
+	thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME] =
+			g_param_spec_string ("service-name",
+					"Service name the protocol points to",
+					"Set the service name",
+					NULL /* default value */,
+					(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+	thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR] =
+			g_param_spec_string ("separator",
+					"Separator for service name and pointer",
+					"Set service name separator",
+					NULL /* default value */,
+					G_PARAM_READWRITE);
+
+	g_object_class_install_properties (object_class,
+			PROP_THRIFT_MULTIPLEXED_PROTOCOL_END,
+			thrift_multiplexed_protocol_obj_properties);
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
----------------------------------------------------------------------
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
new file mode 100644
index 0000000..58d86ce
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_MULTIPLEXED_PROTOCOL_H
+#define _THRIFT_MULTIPLEXED_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_multiplexed_protocol.h
+ *  \brief Multiplexed protocol implementation of a Thrift protocol.  Implements the
+ *         ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_MULTIPLEXED_PROTOCOL (thrift_multiplexed_protocol_get_type ())
+#define THRIFT_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocol))
+#define THRIFT_IS_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL))
+#define THRIFT_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass))
+#define THRIFT_IS_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL))
+#define THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass))
+
+/* version numbers */
+#define THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR ":"
+
+typedef struct _ThriftMultiplexedProtocol ThriftMultiplexedProtocol;
+
+
+
+/*!
+ * Thrift Multiplexed Protocol instance.
+ */
+struct _ThriftMultiplexedProtocol
+{
+  ThriftProtocolDecorator parent;
+
+  gchar *service_name;
+  gchar *separator;
+};
+
+typedef struct _ThriftMultiplexedProtocolClass ThriftMultiplexedProtocolClass;
+
+/*!
+ * Thrift Multiplexed Protocol class.
+ */
+struct _ThriftMultiplexedProtocolClass
+{
+  ThriftProtocolDecoratorClass parent;
+};
+
+/* used by THRIFT_TYPE_MULTIPLEXED_PROTOCOL */
+GType thrift_multiplexed_protocol_get_type (void);
+
+G_END_DECLS
+
+#endif /* _THRIFT_MULTIPLEXED_PROTOCOL_H */

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
----------------------------------------------------------------------
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
new file mode 100644
index 0000000..1844795
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
@@ -0,0 +1,651 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+
+G_DEFINE_TYPE(ThriftProtocolDecorator, thrift_protocol_decorator, THRIFT_TYPE_PROTOCOL)
+
+
+enum
+{
+  PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL = 1,
+  PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END
+};
+
+static GParamSpec *thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END] = { NULL, };
+
+
+
+
+
+gint32
+thrift_protocol_decorator_write_message_begin (ThriftProtocol *protocol,
+                                     const gchar *name,
+                                     const ThriftMessageType message_type,
+                                     const gint32 seqid, GError **error)
+{
+
+  ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+  ThriftProtocolClass *proto = THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol);
+
+  g_info("Concrete protocol %p | %p", self->concrete_protocol, proto);
+
+  return proto->write_message_begin	(self->concrete_protocol, name,
+                                    message_type, seqid,
+                                    error);
+}
+
+gint32
+thrift_protocol_decorator_write_message_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_message_end (self->concrete_protocol,
+                                                                  error);
+}
+
+gint32
+thrift_protocol_decorator_write_struct_begin (ThriftProtocol *protocol, const gchar *name,
+                                    GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_begin (self->concrete_protocol,
+                                                   name, error);
+}
+
+gint32
+thrift_protocol_decorator_write_struct_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_end (self->concrete_protocol,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_begin (ThriftProtocol *protocol,
+                                   const gchar *name,
+                                   const ThriftType field_type,
+                                   const gint16 field_id,
+                                   GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_begin (self->concrete_protocol,
+                                                   name, field_type,
+                                                   field_id, error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_end (self->concrete_protocol,
+                                                                error);
+}
+
+gint32
+thrift_protocol_decorator_write_field_stop (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_stop (self->concrete_protocol,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_decorator_write_map_begin (ThriftProtocol *protocol,
+                                 const ThriftType key_type,
+                                 const ThriftType value_type,
+                                 const guint32 size, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_begin (self->concrete_protocol,
+                                                   key_type, value_type,
+                                                   size, error);
+}
+
+gint32
+thrift_protocol_decorator_write_map_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_end (self->concrete_protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_decorator_write_list_begin (ThriftProtocol *protocol,
+                                  const ThriftType element_type,
+                                  const guint32 size, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_begin (self->concrete_protocol,
+                                                   element_type, size,
+                                                   error);
+}
+
+gint32
+thrift_protocol_decorator_write_list_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_end (self->concrete_protocol,
+                                                               error);
+}
+
+gint32
+thrift_protocol_decorator_write_set_begin (ThriftProtocol *protocol,
+                                 const ThriftType element_type,
+                                 const guint32 size, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_begin (self->concrete_protocol,
+                                                   element_type, size,
+                                                   error);
+}
+
+gint32
+thrift_protocol_decorator_write_set_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_end (self->concrete_protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_decorator_write_bool (ThriftProtocol *protocol,
+                            const gboolean value, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_bool (self->concrete_protocol, value,
+                                                           error);
+}
+
+gint32
+thrift_protocol_decorator_write_byte (ThriftProtocol *protocol, const gint8 value,
+                            GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_byte (self->concrete_protocol, value,
+                                                           error);
+}
+
+gint32
+thrift_protocol_decorator_write_i16 (ThriftProtocol *protocol, const gint16 value,
+                           GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i16 (self->concrete_protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_decorator_write_i32 (ThriftProtocol *protocol, const gint32 value,
+                           GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i32 (self->concrete_protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_decorator_write_i64 (ThriftProtocol *protocol, const gint64 value,
+                           GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i64 (self->concrete_protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_decorator_write_double (ThriftProtocol *protocol,
+                              const gdouble value, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_double (self->concrete_protocol,
+                                                             value, error);
+}
+
+gint32
+thrift_protocol_decorator_write_string (ThriftProtocol *protocol,
+                              const gchar *str, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_string (self->concrete_protocol, str,
+                                                             error);
+}
+
+gint32
+thrift_protocol_decorator_write_binary (ThriftProtocol *protocol, const gpointer buf,
+                              const guint32 len, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_binary (self->concrete_protocol, buf,
+                                                             len, error);
+}
+
+gint32
+thrift_protocol_decorator_read_message_begin (ThriftProtocol *protocol,
+                                    gchar **name,
+                                    ThriftMessageType *message_type,
+                                    gint32 *seqid, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_begin (self->concrete_protocol,
+                                                   name, message_type,
+                                                   seqid, error);
+}
+
+gint32
+thrift_protocol_decorator_read_message_end (ThriftProtocol *protocol,
+                                  GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_end (self->concrete_protocol,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_decorator_read_struct_begin (ThriftProtocol *protocol,
+                                   gchar **name,
+                                   GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_begin (self->concrete_protocol,
+                                                                  name,
+                                                                  error);
+}
+
+gint32
+thrift_protocol_decorator_read_struct_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_end (self->concrete_protocol,
+                                                                error);
+}
+
+gint32
+thrift_protocol_decorator_read_field_begin (ThriftProtocol *protocol,
+                                  gchar **name,
+                                  ThriftType *field_type,
+                                  gint16 *field_id,
+                                  GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_begin (self->concrete_protocol,
+                                                                 name,
+                                                                 field_type,
+                                                                 field_id,
+                                                                 error);
+}
+
+gint32
+thrift_protocol_decorator_read_field_end (ThriftProtocol *protocol,
+                                GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_end (self->concrete_protocol,
+                                                               error);
+}
+
+gint32
+thrift_protocol_decorator_read_map_begin (ThriftProtocol *protocol,
+                                ThriftType *key_type,
+                                ThriftType *value_type, guint32 *size,
+                                GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_begin (self->concrete_protocol,
+                                                               key_type,
+                                                               value_type,
+                                                               size,
+                                                               error);
+}
+
+gint32
+thrift_protocol_decorator_read_map_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_end (self->concrete_protocol,
+                                                             error);
+}
+
+gint32
+thrift_protocol_decorator_read_list_begin (ThriftProtocol *protocol,
+                                 ThriftType *element_type,
+                                 guint32 *size, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_begin (self->concrete_protocol,
+                                                                element_type,
+                                                                size, error);
+}
+
+gint32
+thrift_protocol_decorator_read_list_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_end (self->concrete_protocol,
+                                                              error);
+}
+
+gint32
+thrift_protocol_decorator_read_set_begin (ThriftProtocol *protocol,
+                                ThriftType *element_type,
+                                guint32 *size, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_begin (self->concrete_protocol,
+                                                               element_type,
+                                                               size, error);
+}
+
+gint32
+thrift_protocol_decorator_read_set_end (ThriftProtocol *protocol, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_end (self->concrete_protocol,
+                                                             error);
+}
+
+gint32
+thrift_protocol_decorator_read_bool (ThriftProtocol *protocol, gboolean *value,
+                           GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_bool (self->concrete_protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_decorator_read_byte (ThriftProtocol *protocol, gint8 *value,
+                           GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_byte (self->concrete_protocol, value,
+                                                          error);
+}
+
+gint32
+thrift_protocol_decorator_read_i16 (ThriftProtocol *protocol, gint16 *value,
+                          GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i16 (self->concrete_protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_decorator_read_i32 (ThriftProtocol *protocol, gint32 *value,
+                          GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i32 (self->concrete_protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_decorator_read_i64 (ThriftProtocol *protocol, gint64 *value,
+                          GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i64 (self->concrete_protocol, value,
+                                                         error);
+}
+
+gint32
+thrift_protocol_decorator_read_double (ThriftProtocol *protocol,
+                             gdouble *value, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_double (self->concrete_protocol, value,
+                                                            error);
+}
+
+gint32
+thrift_protocol_decorator_read_string (ThriftProtocol *protocol,
+                             gchar **str, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_string (self->concrete_protocol, str,
+                                                            error);
+}
+
+gint32
+thrift_protocol_decorator_read_binary (ThriftProtocol *protocol, gpointer *buf,
+                             guint32 *len, GError **error)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+  return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_binary (self->concrete_protocol, buf,
+                                                            len, error);
+}
+
+
+static void
+thrift_protocol_decorator_set_property (GObject      *object,
+		guint         property_id,
+		const GValue *value,
+		GParamSpec   *pspec)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
+	g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
+
+	switch (property_id)
+	{
+	case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+		// FIXME We must finalize it first
+		//g_clear_object (&self->concrete_protocol);
+		self->concrete_protocol=g_value_get_pointer (value);
+		g_info("Setting concrete protocol %p to %p in %s",self,  self->concrete_protocol, g_type_name(G_TYPE_FROM_INSTANCE(object)));
+		// We must get the transport and set it on base class.
+
+		break;
+	default:
+		/* We don't have any other property... */
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+thrift_protocol_decorator_get_property (GObject    *object,
+		guint       property_id,
+		GValue     *value,
+		GParamSpec *pspec)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
+	g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
+
+	switch (property_id)
+	{
+	case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
+		g_value_set_pointer (value, self->concrete_protocol);
+
+		/* But we must also set our */
+
+		break;
+	default:
+		/* We don't have any other property... */
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+ThriftProtocol *
+thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol)
+{
+	ThriftProtocol *retval = NULL;
+	if(!THRIFT_IS_PROTOCOL_DECORATOR(protocol)){
+		g_warning("The type is not protocol decorator");
+		return NULL;
+	}
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR(protocol);
+	g_info("Getting concrete protocol from %X -> %X", self, self->concrete_protocol);
+
+	return retval;
+}
+
+
+static void
+thrift_protocol_decorator_init (ThriftProtocolDecorator *protocol)
+{
+	protocol->concrete_protocol = NULL;
+}
+
+
+
+static void
+thrift_protocol_decorator_dispose (ThriftProtocolDecorator *protocol)
+{
+	ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol);
+
+	/* dispose() might be called multiple times, so we must guard against
+	   * calling g_object_unref() on an invalid GObject by setting the member
+	   * NULL; g_clear_object() does this for us.
+	   */
+	if(self->concrete_protocol!=NULL)
+		g_clear_object (&self->concrete_protocol);
+}
+
+static void
+thrift_protocol_decorator_finalize (ThriftProtocolDecorator *protocol)
+{
+
+//	/*
+//	 * Chain the concrete protocol finalize
+//	 */
+//	if(protocol->concrete_protocol!=NULL){
+//		G_OBJECT_CLASS (protocol->concrete_protocol)->finalize(protocol->concrete_protocol);
+//	}
+	/* Always chain up to the parent class; there is no need to check if
+	 * the parent class implements the finalize() virtual function: it is
+	 * always guaranteed to do so
+	 */
+	G_OBJECT_CLASS (protocol)->finalize(protocol);
+}
+
+/* initialize the class */
+static void
+thrift_protocol_decorator_class_init (ThriftProtocolDecoratorClass *klass)
+{
+	ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->set_property = thrift_protocol_decorator_set_property;
+	object_class->get_property = thrift_protocol_decorator_get_property;
+	object_class->finalize = thrift_protocol_decorator_finalize;
+	object_class->dispose = thrift_protocol_decorator_dispose;
+
+	thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL] =
+			g_param_spec_pointer ("protocol",
+					"Protocol",
+					"Set the protocol to be implemented",
+					(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+	g_object_class_install_properties (object_class,
+			PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END,
+			thrift_protocol_decorator_obj_properties);
+
+	g_info("Current decorator write_message_begin addr %p, new %p", cls->write_message_begin, thrift_protocol_decorator_write_message_begin);
+
+
+	  cls->write_message_begin = thrift_protocol_decorator_write_message_begin;
+	  cls->write_message_end = thrift_protocol_decorator_write_message_end;
+	  cls->write_struct_begin = thrift_protocol_decorator_write_struct_begin;
+	  cls->write_struct_end = thrift_protocol_decorator_write_struct_end;
+	  cls->write_field_begin = thrift_protocol_decorator_write_field_begin;
+	  cls->write_field_end = thrift_protocol_decorator_write_field_end;
+	  cls->write_field_stop = thrift_protocol_decorator_write_field_stop;
+	  cls->write_map_begin = thrift_protocol_decorator_write_map_begin;
+	  cls->write_map_end = thrift_protocol_decorator_write_map_end;
+	  cls->write_list_begin = thrift_protocol_decorator_write_list_begin;
+	  cls->write_list_end = thrift_protocol_decorator_write_list_end;
+	  cls->write_set_begin = thrift_protocol_decorator_write_set_begin;
+	  cls->write_set_end = thrift_protocol_decorator_write_set_end;
+	  cls->write_bool = thrift_protocol_decorator_write_bool;
+	  cls->write_byte = thrift_protocol_decorator_write_byte;
+	  cls->write_i16 = thrift_protocol_decorator_write_i16;
+	  cls->write_i32 = thrift_protocol_decorator_write_i32;
+	  cls->write_i64 = thrift_protocol_decorator_write_i64;
+	  cls->write_double = thrift_protocol_decorator_write_double;
+	  cls->write_string = thrift_protocol_decorator_write_string;
+	  cls->write_binary = thrift_protocol_decorator_write_binary;
+	  cls->read_message_begin = thrift_protocol_decorator_read_message_begin;
+	  cls->read_message_end = thrift_protocol_decorator_read_message_end;
+	  cls->read_struct_begin = thrift_protocol_decorator_read_struct_begin;
+	  cls->read_struct_end = thrift_protocol_decorator_read_struct_end;
+	  cls->read_field_begin = thrift_protocol_decorator_read_field_begin;
+	  cls->read_field_end = thrift_protocol_decorator_read_field_end;
+	  cls->read_map_begin = thrift_protocol_decorator_read_map_begin;
+	  cls->read_map_end = thrift_protocol_decorator_read_map_end;
+	  cls->read_list_begin = thrift_protocol_decorator_read_list_begin;
+	  cls->read_list_end = thrift_protocol_decorator_read_list_end;
+	  cls->read_set_begin = thrift_protocol_decorator_read_set_begin;
+	  cls->read_set_end = thrift_protocol_decorator_read_set_end;
+	  cls->read_bool = thrift_protocol_decorator_read_bool;
+	  cls->read_byte = thrift_protocol_decorator_read_byte;
+	  cls->read_i16 = thrift_protocol_decorator_read_i16;
+	  cls->read_i32 = thrift_protocol_decorator_read_i32;
+	  cls->read_i64 = thrift_protocol_decorator_read_i64;
+	  cls->read_double = thrift_protocol_decorator_read_double;
+	  cls->read_string = thrift_protocol_decorator_read_string;
+	  cls->read_binary = thrift_protocol_decorator_read_binary;
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
----------------------------------------------------------------------
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
new file mode 100644
index 0000000..8eb6bac
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_PROTOCOL_DECORATOR_H
+#define _THRIFT_PROTOCOL_DECORATOR_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_protocol_decorator.h
+ *  \brief Multiplexed protocol implementation of a Thrift protocol.  Implements the
+ *         ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_PROTOCOL_DECORATOR (thrift_protocol_decorator_get_type ())
+#define THRIFT_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecorator))
+#define THRIFT_IS_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR))
+#define THRIFT_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass))
+#define THRIFT_IS_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_DECORATOR))
+#define THRIFT_PROTOCOL_DECORATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass))
+
+typedef struct _ThriftProtocolDecorator ThriftProtocolDecorator;
+
+
+/*!
+ * Thrift Multiplexed Protocol instance.
+ */
+struct _ThriftProtocolDecorator
+{
+	ThriftProtocol parent;
+
+	ThriftProtocol *concrete_protocol;
+};
+
+typedef struct _ThriftProtocolDecoratorClass ThriftProtocolDecoratorClass;
+
+/*!
+ * Thrift Multiplexed Protocol class.
+ */
+struct _ThriftProtocolDecoratorClass
+{
+	ThriftProtocolClass parent;
+
+};
+
+/* used by THRIFT_TYPE_PROTOCOL_DECORATOR */
+GType thrift_protocol_decorator_get_type (void);
+
+
+ThriftProtocol *
+thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol);
+
+
+G_END_DECLS
+
+#endif /* _THRIFT_PROTOCOL_DECORATOR_H */

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/java/test/org/apache/thrift/test/TestServer.java
----------------------------------------------------------------------
diff --git a/lib/java/test/org/apache/thrift/test/TestServer.java b/lib/java/test/org/apache/thrift/test/TestServer.java
index 14cd2ab..f4defad 100644
--- a/lib/java/test/org/apache/thrift/test/TestServer.java
+++ b/lib/java/test/org/apache/thrift/test/TestServer.java
@@ -30,6 +30,7 @@ import org.apache.thrift.protocol.TCompactProtocol;
 import org.apache.thrift.protocol.TJSONProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
+import org.apache.thrift.protocol.TMultiplexedProtocol;
 import org.apache.thrift.server.ServerContext;
 import org.apache.thrift.server.TServer;
 import org.apache.thrift.server.TServer.Args;
@@ -46,10 +47,11 @@ import org.apache.thrift.transport.TSSLTransportFactory;
 import org.apache.thrift.transport.TTransport;
 import org.apache.thrift.transport.TTransportFactory;
 import org.apache.thrift.transport.TNonblockingServerSocket;
-
+import org.apache.thrift.TMultiplexedProcessor;
 
 import thrift.test.Insanity;
 import thrift.test.Numberz;
+import thrift.test.SecondService;
 import thrift.test.ThriftTest;
 import thrift.test.Xception;
 import thrift.test.Xception2;
@@ -58,6 +60,25 @@ import thrift.test.Xtruct2;
 
 public class TestServer {
 
+  // Multiplexed Protocol Support Details:
+  //
+  // For multiplexed testing we always use binary protocol underneath.
+  //
+  // "ThriftTest" named service implements ThriftTest from ThriftTest.thrift
+  // "Second" named service implements "SecondService" from ThriftTest.thrift
+
+  static class SecondHandler implements thrift.test.SecondService.Iface {
+
+    @Override
+    public void blahBlah() throws org.apache.thrift.TException
+    { throw new org.apache.thrift.TException("blahBlah"); }
+
+    @Override
+    public java.lang.String secondtestString(java.lang.String thing) throws org.apache.thrift.TException
+    { return "testString(\"" + thing + "\")"; }
+
+  }
+
   static class TestServerContext implements ServerContext {
 
         int connectionId;
@@ -139,7 +160,7 @@ public class TestServer {
             System.out.println("  --help\t\t\tProduce help message");
             System.out.println("  --port=arg (=" + port + ")\tPort number to connect");
             System.out.println("  --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed");
-            System.out.println("  --protocol=arg (=" + protocol_type + ")\tProtocol: binary, json, compact");
+            System.out.println("  --protocol=arg (=" + protocol_type + ")\tProtocol: binary, compact, json, multiplexed");
             System.out.println("  --ssl\t\t\tEncrypted Transport using SSL");
             System.out.println("  --server-type=arg (=" + server_type +")\n\t\t\t\tType of server: simple, thread-pool, nonblocking, threaded-selector");
             System.out.println("  --string-limit=arg (=" + string_limit + ")\tString read length limit");
@@ -167,8 +188,9 @@ public class TestServer {
           throw new Exception("Unknown server type! " + server_type);
         }
         if (protocol_type.equals("binary")) {
-        } else if (protocol_type.equals("json")) {
         } else if (protocol_type.equals("compact")) {
+        } else if (protocol_type.equals("json")) {
+        } else if (protocol_type.equals("multiplexed")) {
         } else {
           throw new Exception("Unknown protocol type! " + protocol_type);
         }
@@ -183,11 +205,12 @@ public class TestServer {
         System.exit(1);
       }
 
-      // Processor
-      TestHandler testHandler =
-        new TestHandler();
-      ThriftTest.Processor testProcessor =
-        new ThriftTest.Processor(testHandler);
+      // Processors
+      TestHandler testHandler = new TestHandler();
+      ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
+
+      SecondHandler secondHandler = new SecondHandler();
+      SecondService.Processor secondProcessor = new SecondService.Processor(secondHandler);
 
       // Protocol factory
       TProtocolFactory tProtocolFactory = null;
@@ -195,7 +218,7 @@ public class TestServer {
         tProtocolFactory = new TJSONProtocol.Factory();
       } else if (protocol_type.equals("compact")) {
         tProtocolFactory = new TCompactProtocol.Factory(string_limit, container_limit);
-      } else {
+      } else { // also covers multiplexed
         tProtocolFactory = new TBinaryProtocol.Factory(string_limit, container_limit);
       }
 
@@ -211,6 +234,10 @@ public class TestServer {
 
       TServer serverEngine = null;
 
+      // If we are multiplexing services in one server...
+      TMultiplexedProcessor multiplexedProcessor = new TMultiplexedProcessor();
+      multiplexedProcessor.registerProcessor("ThriftTest", testProcessor);
+      multiplexedProcessor.registerProcessor("Second", secondProcessor);
 
       if (server_type.equals("nonblocking") ||
           server_type.equals("threaded-selector")) {
@@ -218,23 +245,21 @@ public class TestServer {
         TNonblockingServerSocket tNonblockingServerSocket =
           new TNonblockingServerSocket(new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(port));
 
-        if (server_type.equals("nonblocking")) {
+        if (server_type.contains("nonblocking")) {
           // Nonblocking Server
           TNonblockingServer.Args tNonblockingServerArgs
               = new TNonblockingServer.Args(tNonblockingServerSocket);
-          tNonblockingServerArgs.processor(testProcessor);
+          tNonblockingServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor);
           tNonblockingServerArgs.protocolFactory(tProtocolFactory);
           tNonblockingServerArgs.transportFactory(tTransportFactory);
-
           serverEngine = new TNonblockingServer(tNonblockingServerArgs);
         } else { // server_type.equals("threaded-selector")
           // ThreadedSelector Server
           TThreadedSelectorServer.Args tThreadedSelectorServerArgs
               = new TThreadedSelectorServer.Args(tNonblockingServerSocket);
-          tThreadedSelectorServerArgs.processor(testProcessor);
+          tThreadedSelectorServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor);
           tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory);
           tThreadedSelectorServerArgs.transportFactory(tTransportFactory);
-
           serverEngine = new TThreadedSelectorServer(tThreadedSelectorServerArgs);
         }
       } else {
@@ -251,25 +276,22 @@ public class TestServer {
         if (server_type.equals("simple")) {
           // Simple Server
           TServer.Args tServerArgs = new TServer.Args(tServerSocket);
-          tServerArgs.processor(testProcessor);
+          tServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor);
           tServerArgs.protocolFactory(tProtocolFactory);
           tServerArgs.transportFactory(tTransportFactory);
-
           serverEngine = new TSimpleServer(tServerArgs);
         } else { // server_type.equals("threadpool")
           // ThreadPool Server
           TThreadPoolServer.Args tThreadPoolServerArgs
               = new TThreadPoolServer.Args(tServerSocket);
-          tThreadPoolServerArgs.processor(testProcessor);
+          tThreadPoolServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor);
           tThreadPoolServerArgs.protocolFactory(tProtocolFactory);
           tThreadPoolServerArgs.transportFactory(tTransportFactory);
-
           serverEngine = new TThreadPoolServer(tThreadPoolServerArgs);
         }
       }
 
-
-      //Set server event handler
+      // Set server event handler
       serverEngine.setServerEventHandler(new TestServerEventHandler());
 
       // Run it

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/c_glib/src/test_client.c
----------------------------------------------------------------------
diff --git a/test/c_glib/src/test_client.c b/test/c_glib/src/test_client.c
index 9713e8c..a6ef869 100644
--- a/test/c_glib/src/test_client.c
+++ b/test/c_glib/src/test_client.c
@@ -28,6 +28,7 @@
 #include <thrift/c_glib/thrift.h>
 #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
 #include <thrift/c_glib/protocol/thrift_compact_protocol.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
 #include <thrift/c_glib/transport/thrift_buffered_transport.h>
 #include <thrift/c_glib/transport/thrift_framed_transport.h>
 #include <thrift/c_glib/transport/thrift_ssl_socket.h>
@@ -73,6 +74,32 @@ gint32_compare (gconstpointer a, gconstpointer b)
   return result;
 }
 
+/**
+ * It gets a multiplexed protocol which uses binary underneath
+ * @param  transport      the underlying transport
+ * @param  service_name   the single supported service name
+ * @todo                  need to allow multiple services to fully test multiplexed
+ * @return                a multiplexed protocol wrapping the correct underlying protocol
+ */
+ThriftProtocol *
+get_multiplexed_protocol(ThriftTransport *transport, gchar *service_name)
+{
+  ThriftProtocol * result_protocol=NULL;
+  ThriftProtocol * multiplexed_protocol=NULL;
+
+  multiplexed_protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
+               "transport", transport,
+               NULL);
+
+  result_protocol = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROTOCOL,
+          "transport",  transport,
+          "protocol",   multiplexed_protocol,
+          "service-name",   service_name,
+          NULL);
+
+  return result_protocol;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -94,7 +121,7 @@ main (int argc, char **argv)
     { "transport",       't', 0, G_OPTION_ARG_STRING,   &transport_option,
       "Transport: buffered, framed (=buffered)", NULL },
     { "protocol",        'r', 0, G_OPTION_ARG_STRING,   &protocol_option,
-      "Protocol: binary, compact (=binary)", NULL },
+      "Protocol: binary, compact, multiplexed (=binary)", NULL },
     { "testloops",       'n', 0, G_OPTION_ARG_INT,      &num_tests,
       "Number of tests (=1)", NULL },
     { NULL }
@@ -153,7 +180,14 @@ main (int argc, char **argv)
       protocol_type = THRIFT_TYPE_COMPACT_PROTOCOL;
       protocol_name = "compact";
     }
-    else if (strncmp (protocol_option, "binary", 7) != 0) {
+    else if (strncmp (protocol_option, "multiplexed", 12) == 0) {
+      protocol_type = THRIFT_TYPE_MULTIPLEXED_PROTOCOL;
+      protocol_name = "multiplexed(binary)";
+    }
+    else if (strncmp (protocol_option, "binary", 7) == 0) {
+      printf("We are going with default binary protocol");
+    }
+    else {
       fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
       options_valid = FALSE;
     }
@@ -213,9 +247,22 @@ main (int argc, char **argv)
   transport = g_object_new (transport_type,
                             "transport", socket,
                             NULL);
-  protocol = g_object_new (protocol_type,
-                           "transport", transport,
-                           NULL);
+
+  if(protocol_type==THRIFT_TYPE_MULTIPLEXED_PROTOCOL) {
+    // TODO: A multiplexed test should also test "Second" (see Java TestServer)
+    // The context comes from the name of the thrift file. If multiple thrift
+    // schemas are used we have to redo the way this is done.
+    protocol = get_multiplexed_protocol(transport, "ThriftTest");
+    if (NULL == protocol) {
+      g_object_unref (transport);
+      g_object_unref (socket);
+      return 252;
+    }
+  }else{
+    protocol = g_object_new (protocol_type,
+           "transport", transport,
+           NULL);
+  }
   test_client = g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT,
                               "input_protocol",  protocol,
                               "output_protocol", protocol,

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/crossrunner/report.py
----------------------------------------------------------------------
diff --git a/test/crossrunner/report.py b/test/crossrunner/report.py
index cc5f26f..26f7d9e 100644
--- a/test/crossrunner/report.py
+++ b/test/crossrunner/report.py
@@ -104,7 +104,7 @@ class TestReporter(object):
 
     def _print_bar(self, out=None):
         print(
-            '==========================================================================',
+            '===============================================================================',
             file=(out or self.out))
 
     def _print_exec_time(self):
@@ -259,14 +259,14 @@ class SummaryReporter(TestReporter):
         name = '%s-%s' % (test.server.name, test.client.name)
         trans = '%s-%s' % (test.transport, test.socket)
         if not with_result:
-            return '{:24s}{:13s}{:25s}'.format(name[:23], test.protocol[:12], trans[:24])
+            return '{:24s}{:18s}{:25s}'.format(name[:23], test.protocol[:17], trans[:24])
         else:
-            return '{:24s}{:13s}{:25s}{:s}\n'.format(name[:23], test.protocol[:12], trans[:24], self._result_string(test))
+            return '{:24s}{:18s}{:25s}{:s}\n'.format(name[:23], test.protocol[:17], trans[:24], self._result_string(test))
 
     def _print_test_header(self):
         self._print_bar()
         print(
-            '{:24s}{:13s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
+            '{:24s}{:18s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
             file=self.out)
 
     def _print_header(self):

http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/tests.json
----------------------------------------------------------------------
diff --git a/test/tests.json b/test/tests.json
index f1d6a47..2ab2e1d 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -13,6 +13,9 @@
       "command": [
         "test_client"
       ],
+      "protocols": [
+        "multiplexed"
+      ],
       "sockets": [
         "ip-ssl"
       ]
@@ -106,7 +109,10 @@
     ],
     "server": {
       "delay": 10,
-      "extra_args": ["run-testserver"]
+      "extra_args": ["run-testserver"],
+      "protocols": [
+        "multiplexed"
+      ]
     },
     "client": {
       "timeout": 13,
@@ -125,8 +131,8 @@
       "ip-ssl"
     ],
     "protocols": [
-      "compact",
       "binary",
+      "compact",
       "json"
     ],
     "workdir": "../lib/java"